В настоящее время я пытаюсь использовать предварительно обученную сеть и протестировать этот набор данных а>. Первоначально я использовал VGG19 и просто настроил только классификатор в конце, чтобы он соответствовал моим 120 классам. Я позволил тренироваться всем слоям, чтобы, возможно, улучшить производительность за счет более глубокого обучения. Проблема в том, что модель очень медленная (даже если я позволю ей поработать на ночь, у меня всего пара эпох и точность около 45% - у меня GPU GTX 1070).
Затем я подумал о том, чтобы заморозить все слои из этой модели, так как у меня всего 10k изображений и тренирую только несколько последних слоев Denses, но это все еще не очень быстро.
После просмотра этого видео (примерно 2 мин 30 сек) я решил воспроизвести принцип передачи значений с InceptionResnetv2.
Я обработал все изображения и сохранил результат в матрице numpy со следующим кодом.
# Loading pre-trained Model + freeze layers
model = applications.inception_resnet_v2.InceptionResNetV2(
include_top=False,
weights='imagenet',
pooling='avg')
for layer in model.layers:
layer.trainable = False
# Extraction of features and saving
a = True
for filename in glob.glob('train/resized/*.jpg'):
name_img = os.path.basename(filename)[:-4]
class_ = label[label["id"] == name_img]["breed"].values[0]
input_img = np.expand_dims(np.array(Image.open(filename)), 0)
pred = model.predict(input_img)
if a:
X = np.array(pred)
y = np.array(class_)
a = False
else:
X = np.vstack((X, np.array(pred)))
y = np.vstack((y, class_))
np.savez_compressed('preprocessed.npz', X=X, y=y)
X - это матрица формы (10222, 1536), а y - (10222, 1).
После того, как я разработал свой классификатор (несколько топологий), я понятия не имею, почему он не может выполнять какое-либо обучение.
# Just to One-Hot-Encode labels properly to (10222, 120)
label_binarizer = sklearn.preprocessing.LabelBinarizer()
y = label_binarizer.fit_transform(y)
model = Sequential()
model.add(Dense(512, input_dim=X.shape[1]))
# model.add(Dense(2048, activation="relu"))
# model.add(Dropout(0.5))
# model.add(Dense(256))
model.add(Dense(120, activation='softmax'))
model.compile(
loss = "categorical_crossentropy",
optimizer = "Nadam", # I tried several ones
metrics=["accuracy"]
)
model.fit(X, y, epochs=100, batch_size=64,
callbacks=[early_stop], verbose=1,
shuffle=True, validation_split=0.10)
Ниже вы можете найти результат работы модели:
Train on 9199 samples, validate on 1023 samples
Epoch 1/100
9199/9199 [==============================] - 2s 185us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Epoch 2/100
9199/9199 [==============================] - 1s 100us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Epoch 3/100
9199/9199 [==============================] - 1s 98us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Epoch 4/100
9199/9199 [==============================] - 1s 96us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Epoch 5/100
9199/9199 [==============================] - 1s 99us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Epoch 6/100
9199/9199 [==============================] - 1s 96us/step - loss: 15.9639 - acc: 0.0096 - val_loss: 15.8975 - val_acc: 0.0137
Я пытался изменить топологию, функции активации, добавить отсевы, но ничего не дало никаких улучшений.
Я понятия не имею, что не так в моем способе делать это. Матрица X неверна? Разве не разрешено использовать предварительно обученную модель только в качестве экстрактора признаков, а затем выполнить классификацию с помощью второй модели?
Большое спасибо за отзывы, С уважением, Николас