tensorflow - Keras:以两种不同方式拟合 ConvNet 时结果不一致

标签 tensorflow machine-learning neural-network keras image-recognition

我正在尝试使用 VGG16 网络进行图像分类。我尝试了两种不同的方法来做到这一点,据我所知,这两种方法应该大致相同,但结果却截然不同。

方法 1: 使用 VGG16 提取特征,并使用自定义全连接网络拟合这些特征。这是代码:

model = vgg16.VGG16(include_top=False, weights='imagenet',
                    input_shape=(imsize,imsize,3),
                    pooling='avg')
model_pred = keras.Sequential()
model_pred.add(keras.layers.Dense(1024, input_dim=512, activation='sigmoid'))
model_pred.add(keras.layers.Dropout(0.5))
model_pred.add(keras.layers.Dense(512, activation='sigmoid'))
model_pred.add(keras.layers.Dropout(0.5))
model_pred.add(keras.layers.Dense(num_categories, activation='sigmoid'))
model_pred.compile(loss=keras.losses.categorical_crossentropy,
                   optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])

(xtr, ytr) = tools.extract_features(model, 3000, imsize, datagen,
                                    rootdir + '/train',
                                    pickle_name = rootdir + '/testpredstrain.pickle')
(xv, yv) = tools.extract_features(model, 300, imsize, datagen,
                                  rootdir + '/valid1',
                                  pickle_name = rootdir + '/testpredsvalid.pickle')

model_pred.fit(xtr, ytr, epochs = 10, validation_data = (xv, yv), verbose=1)

(函数 extract_features() 只是使用 Keras ImageDataGenerator 生成样本图像,并在使用 model.predict() 后返回输出这些图像)

方法2:采用没有顶部部分的VGG16网络,将所有卷积层设置为不可训练,并添加一些可训练的密集连接层。然后使用 keras fit_generator() 进行拟合。这是代码:

model2 = vgg16.VGG16(include_top=False, weights='imagenet',
                    input_shape=(imsize,imsize,3),
                    pooling='avg')
for ll in model2.layers:
    ll.trainable = False

out1 = keras.layers.Dense(1024, activation='softmax')(model2.layers[-1].output)
out1 = keras.layers.Dropout(0.4)(out1)
out1 = keras.layers.Dense(512, activation='softmax')(out1)
out1 = keras.layers.Dropout(0.4)(out1)
out1 = keras.layers.Dense(num_categories, activation='softmax')(out1)
model2 = keras.Model(inputs = model2.input, outputs = out1)
model2.compile(loss=keras.losses.categorical_crossentropy,
               optimizer=keras.optimizers.Adadelta(),
               metrics=['accuracy'])


model2.fit_generator(train_gen,
                     steps_per_epoch = 100,
                     epochs = 10,
                     validation_data = valid_gen,
                     validation_steps = 10)

两种方法中的 epoch 数、样本数等并不完全相同,但无需注意这种不一致:方法 1 仅在一个 epoch 后即可获得 0.47 的验证准确率,并且高达0.7-0.8,当我使用更多的样本来拟合时甚至更好。然而,方法 2 的验证精度停留在 0.1-0.15 之间,无论我训练多少,都永远不会变得更好。

此外,方法 2 比方法 1 慢得多,尽管在我看来它们应该大致一样快(考虑到提取方法 1 中的特征所需的时间)。

最佳答案

使用第一种方法时,您使用 vgg16 预训练模型提取特征一次,然后进行训练 - 微调您的网络,而在第二种方法中,您不断地将图像传递到每一层,包括 vgg 的层<强>在每个时期。这会导致您的模型使用第二种方法运行得更慢。

关于tensorflow - Keras:以两种不同方式拟合 ConvNet 时结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49068494/

相关文章:

r - 使用 R 上的反向传播神经网络模型生成预测会为所有观察返回相同的值

tensorflow - 使用Tensorflow和预训练的FastText获得看不见的单词的嵌入

tensorflow - 即使指定了种子,tf.random.shuffle 也不会给出可重现的结果

algorithm - 为特征选择实现反​​向贪婪

nlp - 重建现在著名的 17 岁男孩基于马尔可夫链的信息检索算法 "Apodora"

python - 神经网络异或门不学习

python - 如何在 Tensorflow 中使用现有数据集的一部分

python - 如何在实例化后更改 ImageDataGenerator 的批量大小?

machine-learning - 监督文本评分

tensorflow - 如何将 Onnx 模型 (.onnx) 转换为 Tensorflow (.pb) 模型