我正在尝试使用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)


两种方法中的时期,样本等的数量并不完全相同,但是它们不必注意不一致之处:方法1在仅仅一个时期后得出的验证精度为0.47,并高达0.7-0.8甚至在我使用大量样本来拟合时更好。但是,方法2停留在0.1-0.15的验证精度上,而且无论我训练多少,都永远不会变得更好。

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

最佳答案

第一种方法是使用vgg16预训练模型提取特征一次,然后进行训练-微调网络,而第二种方法则是不断将图像传递到每个层,包括每个时代的vgg层。这导致您的模型使用第二种方法运行速度变慢。

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

10-12 19:39