Cette fois, j'aimerais faire une prédiction de géolocalisation à partir d'une image de bâtiment à l'aide d'un modèle entraîné. Surtout dans cet article, j'ai commencé avec le but d'utiliser la sortie de plusieurs étiquettes de latitude et de longitude à partir de l'image d'entrée.
Les données utilisées cette fois sont "European Cities 1M dataset" http://image.ntua.gr/iva/datasets/ec1m/index.html
Utilisez respectivement l'image de l'ensemble de points de repère et la géolocalisation sur ce site.
La mise en œuvre de cet article utilise Google Colaboratory. Les paramètres de l'environnement utilisé sont répertoriés ci-dessous.
import keras
from keras.utils import np_utils
from keras.models import Sequential, Model, load_model
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Dense, Dropout, Activation, Flatten
import numpy as np
from sklearn.model_selection import train_test_split
import os, zipfile, io, re
from PIL import Image
import glob
from tqdm import tqdm
from sklearn.model_selection import train_test_split
from keras.applications.xception import Xception
from keras.applications.resnet50 import ResNet50
from keras.layers.pooling import GlobalAveragePooling2D
from keras.optimizers import Adam, Nadam
Ici, en tant que prétraitement, un traitement avec des étiquettes de latitude et de longitude est effectué. Cette fois, nous apprendrons la latitude et la longitude séparément en tant qu'étiquettes, nous les traiterons donc afin qu'elles puissent être facilement récupérées sous forme de liste.
with open("landmark/ec1m_landmarks_geotags.txt") as f:
label=f.readlines()
for i in label:
ans=i.split(' ')
ans[1]=ans[1].replace('\n','')
print(ans)
production
['41.4134', '2.153']
['41.3917', '2.16472']
['41.3954', '2.16177']
['41.3954', '2.16177']
['41.3954', '2.16156']
['41.3899', '2.17428']
['41.3953', '2.16184']
['41.3953', '2.16172']
['41.3981', '2.1645']
.....
.....
La taille de l'image est de 100 Convertir l'ensemble de données en tableau Étiqueter l'image sans séparer la latitude et la longitude
X = []
Y = []
image_size=100
with open("landmark/ec1m_landmarks_geotags.txt") as f:
label=f.readlines()
dir = "landmark/ec1m_landmark_images"
files = glob.glob(dir + "/*.jpg ")
for index,file in tqdm(enumerate(files)):
image = Image.open(file)
image = image.convert("RGB")
image = image.resize((image_size, image_size))
data = np.asarray(image)
X.append(data)
Y.append(label[index])
X = np.array(X)
Y = np.array(Y)
production
927it [00:08, 115.29it/s]
X.shape,Y.shape
((927, 100, 100, 3), (927,))
Ensuite, divisez en train, testez, validez Divisez la latitude et la longitude ici
y0=[] #Libellé Latitude
y1=[] #Libellé de longitude
for i in Y:
ans=i.split(' ')
ans[1]=ans[1].replace('\n','')
y0.append(float(ans[0]))
y1.append(float(ans[1]))
y0=np.array(y0)
y1=np.array(y1)
#X(train,test)Divisé
X_train, X_test = train_test_split(X, random_state = 0, test_size = 0.2)
print(X_train.shape, X_test.shape)
#(741, 100, 100, 3) (186, 100, 100, 3)
#y0,y1(train,test)Divisé
y_train0,y_test0,y_train1, y_test1 = train_test_split(y0,y1,
random_state = 0,
test_size = 0.2)
print(y_train0.shape, y_test0.shape)
print(y_train1.shape, y_test1.shape)
#(741,) (186,)
#(741,) (186,)
#Conversion et normalisation du type de données
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
#X(train,valid)Divisé
X_train, X_valid= train_test_split(X_train, random_state = 0, test_size = 0.2)
print(X_train.shape, X_valid.shape)
#(592, 100, 100, 3) (149, 100, 100, 3)
#y0,y1(train,valid)Divisé
y_train0, y_valid0,y_train1, y_valid1= train_test_split(y_train0,y_train1,
random_state = 0,
test_size = 0.2)
print(y_train0.shape, y_valid0.shape)
print(y_train1.shape, y_valid1.shape)
#(592,) (149,)
#(592,) (149,)
Cette fois, nous utiliserons le modèle entraîné de Xception en nous référant à l'article suivant. https://qiita.com/ha9kberry/items/314afb56ee7484c53e6f#データ取得
Je voulais l'essayer avec d'autres modèles, donc j'essaierai également d'utiliser Resnet.
#xception model
base_model = Xception(
include_top = False,
weights = "imagenet",
input_shape = None
)
#resnet model
base_model = ResNet50(
include_top = False,
weights = "imagenet",
input_shape = None
)
Entrez une valeur prédite à la fin du problème de régression Préparer la sortie d'étiquette pour la latitude et la longitude
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions1 = Dense(1,name='latitude')(x)
predictions2 = Dense(1,name='longitude')(x)
Mettez predictions1 et predictions2 en sortie. D'autres sont comme dans l'article de référence Cette fois, nous étudierons l'utilisation d'Adam et Nadam comme optimiseurs.
model = Model(inputs = base_model.input, outputs = [predictions1,predictions2])
#Congelez jusqu'à 108 couches
for layer in model.layers[:108]:
layer.trainable = False
#Libérer la normalisation des lots
if layer.name.startswith('batch_normalization'):
layer.trainable = True
if layer.name.endswith('bn'):
layer.trainable = True
#Apprenez à partir de la couche 109
for layer in model.layers[108:]:
layer.trainable = True
# layer.compiler après avoir défini entraînable
model.compile(
optimizer = Adam(),
#optimizer=Nadam(),
loss = {'latitude':root_mean_squared_error,
'longitude':root_mean_squared_error
}
)
history = model.fit( X_train, #decode_train
{'latitude': y_train0,
'longitude':y_train1},
batch_size=64,
epochs=50,
validation_data=(X_valid, decode_valid
{'latitude' :y_valid0,
'longitude':y_valid1}),
)
production
Epoch 1/50
10/10 [==============================] - 4s 409ms/step - loss: 0.6146 - latitude_loss: 0.4365 - longitude_loss: 0.1782 - val_loss: 1.6756 - val_latitude_loss: 1.3430 - val_longitude_loss: 0.3326
Epoch 2/50
10/10 [==============================] - 4s 404ms/step - loss: 0.5976 - latitude_loss: 0.4415 - longitude_loss: 0.1562 - val_loss: 0.7195 - val_latitude_loss: 0.5987 - val_longitude_loss: 0.1208
...
...
import matplotlib.pyplot as plt
plt.figure(figsize=(18,6))
# loss
plt.subplot(1, 2, 1)
plt.plot(history.history["latitude_loss"], label="latitude_loss", marker="o")
plt.plot(history.history["longitude_loss"], label="longitude_loss", marker="o")
#plt.yticks(np.arange())
#plt.xticks(np.arange())
plt.ylabel("loss")
plt.xlabel("epoch")
plt.title("")
plt.legend(loc="best")
plt.grid(color='gray', alpha=0.2)
plt.show()
résultat
#batch size 64 Adam
scores = model.evaluate(X_test,{'latitude' :y_test0,
'longitude':y_test1},
verbose=1)
print("total loss:\t{0}".format(scores[0]))
print("latitude loss:\t{0}".format(scores[1]))
print("longtitude loss:{0}".format(scores[2]))
production
total loss: 0.7182420492172241
latitude loss: 0.6623533964157104
longtitude loss:0.05588864907622337
# show image, prediction and actual label
for i in range(10,12):
plt.figure(figsize=(10,10))
print('latitude:{} \tlongititude{}'.format(
prediction[0][i],
prediction[1][i],
))
plt.imshow(X_test[i].reshape(100, 100, 3))
plt.show()
latitude:[39.69221] longititude[2.2188098]
latitude:[39.728386] longititude[2.224149]
Il y a des nombres comme ça, mais lorsqu'ils sont exprimés sur la carte (Google Map), c'est au milieu de la mer comme indiqué ci-dessous, ce qui n'est pas suffisant à utiliser.
Paramètres utilisés | Total loss | latitude_loss | longtitude_loss |
---|---|---|---|
Xception , Adam | 0.7182 | 0.6623 | 0.0558 |
Xception , Nadam | 0.3768 | 0.1822 | 0.1946 |
Resnet , Adam | 0.7848 | 0.7360 | 0.0488 |
Resnet , Nadam | 49.6434 | 47.2652 | 2.3782 |
Resnet,Adam,AutoEncoder | 1.8299 | 1.6918 | 0.13807 |
Dans cet essai, la combinaison de Xception et de Nadam s'est avérée la plus précise. À l'avenir, j'utiliserai un autre modèle ou créerai un modèle à partir de zéro
base de données
Publications Conferences Y. Avrithis, Y. Kalantidis, G. Tolias, E. Spyrou. Retrieving Landmark and Non-Landmark Images from Community Photo Collections. In Proceedings of ACM Multimedia (MM 2010), Firenze, Italy, October 2010.
Journals Y. Kalantidis, G. Tolias, Y. Avrithis, M. Phinikettos, E. Spyrou, P. Mylonas, S. Kollias. VIRaL: Visual Image Retrieval and Localization. In Multimedia Tools and Applications (to appear), 2011.
article
--https: //qiita.com/ha9kberry/items/314afb56ee7484c53e6f # Présentation
Recommended Posts