【发布时间】:2019-02-16 07:45:59
【问题描述】:
我无法使用 Keras 微调 Inception 模型。
我已经设法使用教程和文档来生成一个完全连接的顶层模型,该模型使用 Inception 的瓶颈特征将我的数据集分类到适当的类别中,准确率超过 99%。
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
# dimensions of our images.
img_width, img_height = 150, 150
#paths for saving weights and finding datasets
top_model_weights_path = 'Inception_fc_model_v0.h5'
train_data_dir = '../data/train2'
validation_data_dir = '../data/train2'
#training related parameters?
inclusive_images = 1424
nb_train_samples = 1424
nb_validation_samples = 1424
epochs = 50
batch_size = 16
def save_bottlebeck_features():
datagen = ImageDataGenerator(rescale=1. / 255)
# build bottleneck features
model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_train = model.predict_generator(
generator, nb_train_samples // batch_size)
np.save('bottleneck_features_train', bottleneck_features_train)
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, nb_validation_samples // batch_size)
np.save('bottleneck_features_validation', bottleneck_features_validation)
def train_top_model():
train_data = np.load('bottleneck_features_train.npy')
train_labels = np.array(range(inclusive_images))
validation_data = np.load('bottleneck_features_validation.npy')
validation_labels = np.array(range(inclusive_images))
print('base size ', train_data.shape[1:])
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(1000, activation='relu'))
model.add(Dense(inclusive_images, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='Adam',
metrics=['accuracy'])
proceed = True
#model.load_weights(top_model_weights_path)
while proceed:
history = model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size)#,
#validation_data=(validation_data, validation_labels), verbose=1)
if history.history['acc'][-1] > .99:
proceed = False
model.save_weights(top_model_weights_path)
save_bottlebeck_features()
train_top_model()
50/50 纪元 1424/1424 [===============================] - 17 秒 12 毫秒/步 - 损耗:0.0398 - 加速度:0.9909
我还能够将此模型堆叠在 inception 之上以创建我的完整模型并使用该完整模型对我的训练集进行成功分类。
from keras import Model
from keras import optimizers
from keras.callbacks import EarlyStopping
img_width, img_height = 150, 150
top_model_weights_path = 'Inception_fc_model_v0.h5'
train_data_dir = '../data/train2'
validation_data_dir = '../data/train2'
#how many inclusive examples do we have?
inclusive_images = 1424
nb_train_samples = 1424
nb_validation_samples = 1424
epochs = 50
batch_size = 16
# build the complete network for evaluation
base_model = applications.inception_v3.InceptionV3(weights='imagenet', include_top=False, input_shape=(img_width,img_height,3))
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(1000, activation='relu'))
top_model.add(Dense(inclusive_images, activation='softmax'))
top_model.load_weights(top_model_weights_path)
#combine base and top model
fullModel = Model(input= base_model.input, output= top_model(base_model.output))
#predict with the full training dataset
results = fullModel.predict_generator(ImageDataGenerator(rescale=1. / 255).flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False))
对该完整模型的处理结果的检查与瓶颈生成的全连接模型的准确性相匹配。
import matplotlib.pyplot as plt
import operator
#retrieve what the softmax based class assignments would be from results
resultMaxClassIDs = [ max(enumerate(result), key=operator.itemgetter(1))[0] for result in results]
#resultMaxClassIDs should be equal to range(inclusive_images) so we subtract the two and plot the log of the absolute value
#looking for spikes that indicate the values aren't equal
plt.plot([np.log(np.abs(x)+10) for x in (np.array(resultMaxClassIDs) - np.array(range(inclusive_images)))])
问题出在: 当我采用这个完整的模型并尝试对其进行训练时,即使验证保持在 99% 以上,准确率也会下降到 0。
model2 = fullModel
for layer in model2.layers[:-2]:
layer.trainable = False
# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
#model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
model2.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1. / 255)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
callback = [EarlyStopping(monitor='acc', min_delta=0, patience=3, verbose=0, mode='auto', baseline=None)]
# fine-tune the model
model2.fit_generator(
#train_generator,
validation_generator,
steps_per_epoch=nb_train_samples//batch_size,
validation_steps = nb_validation_samples//batch_size,
epochs=epochs,
validation_data=validation_generator)
纪元 1/50 89/89 [==============================] - 388s 4s/step - 损失:13.5787 - acc: 0.0000e+ 00 - val_loss:0.0353 - val_acc:0.9937
随着事情的发展,情况会变得更糟
21/50 纪元 89/89 [==============================] - 372s 4s/step - loss: 7.3850 - acc: 0.0035 - val_loss : 0.5813 - val_acc: 0.8272
我唯一能想到的是,不知何故,最后一列火车上的训练标签分配不正确,但我之前使用 VGG16 用类似的代码成功地做到了这一点。
我搜索了代码,试图找到一个差异来解释为什么一个模型在 99% 的时间内做出准确预测会降低其训练准确度,同时在微调期间保持验证准确度,但我无法弄清楚。任何帮助将不胜感激。
关于代码和环境的信息:
会显得很奇怪,但本来就是这样的事情:
- 每个班级只有一张图片。该NN旨在分类 环境和方向条件为 受控。他们只是每个班级的一个可接受的图像 对应正确的环境和旋转情况。
- 测试集和验证集相同。这个NN是唯一的 设计用于正在接受培训的课程。图像 它将处理类示例的副本。这是我的 意图将模型过度拟合到这些类中
我正在使用:
- Windows 10
- Anaconda客户端1.6.14下的Python 3.5.6
- Keras 2.2.2
- Tensorflow 1.10.0 作为后端
- CUDA 9.0
- CuDNN 8.0
我已签出:
- Keras accuracy discrepancy in fine-tuned model
- VGG16 Keras fine tuning: low accuracy
- Keras: model accuracy drops after reaching 99 percent accuracy and loss 0.01
- Keras inception v3 retraining and finetuning error
- How to find which version of TensorFlow is installed in my system?
但它们似乎无关。
【问题讨论】:
-
你为什么要阻止最后 2 层的训练,在迁移学习中,当你训练模型时,这 2 层应该是最重要的。它要么是模型正在改变,但不允许对最后两层进行更改,你的模型无法正确学习,要么你以某种方式过度拟合批次。
-
我不是。 model2.layers[:-2] 返回所有但最后两层。因此,初始基础模型保持静止。我意识到 inception 的一些顶层应该解冻以进行微调,但它不应该导致这个问题。
-
Sry 将其位置误读为 [-2:]
-
@SemicolonsandDuctTape 训练目录的结构如何?每张图片都在自己的文件夹中吗?
-
是 train2/image1/image1.bmp , train2/image2/image2.bmp 等
标签: python tensorflow machine-learning keras deep-learning