Dieses Mal möchte ich anhand eines trainierten Modells eine Geotag-Vorhersage aus einem Gebäudebild machen. Insbesondere in diesem Artikel habe ich mit dem Ziel begonnen, die Ausgabe mehrerer Beschriftungen für Breiten- und Längengrade aus dem Eingabebild zu verwenden.
Die diesmal verwendeten Daten sind "European Cities 1M-Datensatz". http://image.ntua.gr/iva/datasets/ec1m/index.html
Verwenden Sie das Landmark-Set-Bild bzw. das Geotag auf dieser Site.
Die Implementierung in diesem Artikel verwendet Google Colaboratory. Die Einstellungen der verwendeten Umgebung sind unten aufgeführt.
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
Hier wird als Vorverarbeitung die Verarbeitung mit Breiten- und Längengradbezeichnungen durchgeführt. Dieses Mal lernen wir den Breiten- und Längengrad getrennt als Beschriftungen, sodass wir sie so verarbeiten, dass sie leicht als Liste abgerufen werden können.
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)
Ausgabe
['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']
.....
.....
Die Bildgröße beträgt 100 Datensatz in Array konvertieren Beschriften Sie das Bild, ohne den Breiten- und Längengrad zu trennen
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)
Ausgabe
927it [00:08, 115.29it/s]
X.shape,Y.shape
((927, 100, 100, 3), (927,))
Als nächstes in Zug teilen, testen, gültig Teilen Sie hier Breiten- und Längengrade
y0=[] #Latitude-Label
y1=[] #Längengradetikett
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)Teilt
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)Teilt
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,)
#Datentypkonvertierung und -normalisierung
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
#x(train,valid)Teilt
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)Teilt
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,)
Dieses Mal verwenden wir das trainierte Modell von Xception unter Bezugnahme auf den folgenden Artikel. https://qiita.com/ha9kberry/items/314afb56ee7484c53e6f#データ取得
Ich wollte es mit anderen Modellen versuchen, also werde ich auch versuchen, Resnet zu verwenden.
#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
)
Geben Sie am Ende des Regressionsproblems einen vorhergesagten Wert ein Bereiten Sie die Etikettenausgabe für Breiten- und Längengrade vor
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)
Setzen Sie Vorhersagen1 und Vorhersagen2 in die Ausgabe ein. Andere sind wie im Referenzartikel Dieses Mal werden wir Adam und Nadam als Optimierer verwenden.
model = Model(inputs = base_model.input, outputs = [predictions1,predictions2])
#Frieren Sie bis zu 108 Schichten ein
for layer in model.layers[:108]:
layer.trainable = False
#Unfreeze Batch Normalization
if layer.name.startswith('batch_normalization'):
layer.trainable = True
if layer.name.endswith('bn'):
layer.trainable = True
#Lernen Sie ab Ebene 109
for layer in model.layers[108:]:
layer.trainable = True
# layer.Kompilieren nach dem Setzen trainierbar
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}),
)
Ausgabe
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()
Ergebnis
#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]))
Ausgabe
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]
Es gibt solche Zahlen, aber wenn sie auf der Karte (Google Map) ausgedrückt werden, befindet sie sich wie unten gezeigt mitten im Meer, was nicht ausreicht, um sie zu verwenden.
Verwendete Parameter | 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 |
In dieser Studie wurde festgestellt, dass die Kombination von Xception und Nadam am genauesten ist. In Zukunft werde ich ein anderes Modell verwenden oder ein Modell von Grund auf neu erstellen
Datensatz
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.
Artikel
--https: //qiita.com/ha9kberry/items/314afb56ee7484c53e6f # Übersicht
Recommended Posts