我试图用卷积层替换VGG 16网络末尾的FC层。下面是我的代码:
model2= Sequential()
model2.add(Conv2D(4096, kernel_size=(8,8), activation="relu"))
model2.add(Conv2D(4096, kernel_size=(1,1), activation="relu"))
model2.add(Conv2D(16, kernel_size=(1,1), activation="softmax"))
model = applications.VGG16(weights='imagenet', include_top=False, input_shape=inputshape)
F2model = Model(inputs=model.input, outputs=model2(model.output))
for layer in F2model.layers[:25]:
layer.trainable = False
F2model.compile(optimizer=optimizers.Adam(), loss="binary_crossentropy", metrics=["accuracy"])
batch_size = 128
trainsize = 36000
validsize = 12000
F2model.fit_generator(
train_generator,
steps_per_epoch=trainsize // batch_size,
epochs=5,
validation_data=valid_generator,
validation_steps=validsize // batch_size,callbacks=[tensorboard_callback])
我使用FC层训练常规网络,并且运行良好,但是当我运行上述网络时,出现以下错误:
ValueError Traceback (most recent call last)in <module>
4 epochs=5,
5 validation_data=valid_generator,
----> 6 validation_steps=validsize // batch_size,callbacks=[tensorboard_callback])
ValueError: Error when checking target: expected sequential_1 to have 4 dimensions, but got array with shape (32, 16)
在这一点上,我试图找出这些维度(32,16)的来源。任何帮助,将不胜感激。谢谢
编辑1:对于完全回溯:
ValueError Traceback (most recent call last)
<ipython-input-15-2702f38208c0> in <module>
4 epochs=5,
5 validation_data=valid_generator,
----> 6 validation_steps=validsize // batch_size,callbacks=[tensorboard_callback])
~/anaconda3/lib/python3.7/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
89 warnings.warn('Update your `' + object_name + '` call to the ' +
90 'Keras 2 API: ' + signature, stacklevel=2)
---> 91 return func(*args, **kwargs)
92 wrapper._original_function = func
93 return wrapper
~/anaconda3/lib/python3.7/site-packages/keras/engine/training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
1730 use_multiprocessing=use_multiprocessing,
1731 shuffle=shuffle,
-> 1732 initial_epoch=initial_epoch)
1733
1734 @interfaces.legacy_generator_methods_support
~/anaconda3/lib/python3.7/site-packages/keras/engine/training_generator.py in fit_generator(model, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
218 sample_weight=sample_weight,
219 class_weight=class_weight,
--> 220 reset_metrics=False)
221
222 outs = to_list(outs)
~/anaconda3/lib/python3.7/site-packages/keras/engine/training.py in train_on_batch(self, x, y, sample_weight, class_weight, reset_metrics)
1506 x, y,
1507 sample_weight=sample_weight,
-> 1508 class_weight=class_weight)
1509 if self._uses_dynamic_learning_phase():
1510 ins = x + y + sample_weights + [1]
~/anaconda3/lib/python3.7/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
619 feed_output_shapes,
620 check_batch_axis=False, # Don't enforce the batch size.
--> 621 exception_prefix='target')
622
623 # Generate sample-wise weight values given the `sample_weight` and
~/anaconda3/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
133 ': expected ' + names[i] + ' to have ' +
134 str(len(shape)) + ' dimensions, but got array '
--> 135 'with shape ' + str(data_shape))
136 if not check_batch_axis:
137 data_shape = data_shape[1:]
ValueError: Error when checking target: expected conv2d_3 to have 4 dimensions, but got array with shape (32, 16)
编辑2:输入信息:
train_generator=datagen.flow_from_dataframe(dataframe=traindf,directory="data_final",x_col="path",y_col="label",subset="training",batch_size=32,seed=42,shuffle=True,class_mode="categorical",target_size=(256,256))
valid_generator=datagen.flow_from_dataframe(dataframe=traindf,directory="data_final",x_col="path",y_col="label",subset="validation",batch_size=32,seed=42,shuffle=True,class_mode="categorical",target_size=(256,256))
if K.image_data_format()=="channels_first":
inputshape=(3,imrows,imcols)
else:
inputshape=(imrows,imcols,3)
最佳答案
keras的函数式API对于此类问题更好:
model = VGG16(weights='imagenet', include_top=False, input_shape=inputshape)
x = model.output
x = Conv2D(4096, kernel_size=(8, 8), activation="relu")(x)
x = Conv2D(4096, kernel_size=(1, 1), activation="relu")(x)
out = Conv2D(16, kernel_size=(1, 1), activation="softmax")(x)
F2model = Model(inputs=model.inputs, outputs=out)
for layer in F2model.layers[:25]:
layer.trainable = False
而且我看到您正在使用带有softmax激活的binary_crossentropy,这可能会导致一些问题:
-使用softmax和categorical_crossentropy
-使用Sigmoid和binary_crossentropy
而且,请谨慎使用此模型,使用4096的卷积将使您的参数数量真的非常烦恼!
(在这种情况下为1.65亿)
编辑
看来您的问题仅来自标签数组:
您的最后一层是卷积层,因此它希望使用形状为
(batch_size, height, width, channel)
的4D数组,但是您要为其提供形状为(batch_size, 16)
的数组因此,要么将您的最后一层更改为:
out = Dense(16, activation="softmax")(x)
或将标签数组更改为卷积层可接受的标签。
关于python - 检查目标时出错:将FC层转换为Conv2D,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60264581/