我正在尝试创建一个图像处理CNN。我使用VGG16来加快一些学习过程。下面我的CNN的创建工作到了训练和保存模型的地步& &;权重。当我尝试在模型中加载后运行预测函数时,会出现这个问题。
image_gen = ImageDataGenerator()
train = image_gen.flow_from_directory('./data/train', class_mode='categorical', shuffle=False, batch_size=10, target_size=(151, 136))
val = image_gen.flow_from_directory('./data/validate', class_mode='categorical', shuffle=False, batch_size=10, target_size=(151, 136))
pretrained_model = VGG16(include_top=False, input_shape=(151, 136, 3), weights='imagenet')
pretrained_model.summary()
vgg_features_train = pretrained_model.predict(train)
vgg_features_val = pretrained_model.predict(val)
train_target = to_categorical(train.labels)
val_target = to_categorical(val.labels)
model = Sequential()
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.5))
model.add(BatchNormalization())
model.add(Dense(2, activation='softmax'))
model.compile(optimizer='rmsprop', metrics=['accuracy'], loss='categorical_crossentropy')
target_dir = './models/weights-improvement'
if not os.path.exists(target_dir):
os.mkdir(target_dir)
checkpoint = ModelCheckpoint(filepath=target_dir + 'weights-improvement-{epoch:02d}-{val_accuracy:.2f}.hdf5', monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]
model.fit(vgg_features_train, train_target, epochs=100, batch_size=8, validation_data=(vgg_features_val, val_target), callbacks=callbacks_list)
model.save('./models/model')
model.save_weights('./models/weights')
我有这个预测函数,我想在图像中加载,然后返回模型给出的该图像的分类。
from keras.preprocessing.image import load_img, img_to_array
def predict(file):
x = load_img(file, target_size=(151,136,3))
x = img_to_array(x)
print(x.shape)
print(x.shape)
x = np.expand_dims(x, axis=0)
array = model.predict(x)
result = array[0]
if result[0] > result[1]:
if result[0] > 0.9:
print("Predicted answer: Buy")
answer = 'buy'
print(result)
print(array)
else:
print("Predicted answer: Not confident")
answer = 'n/a'
print(result)
else:
if result[1] > 0.9:
print("Predicted answer: Sell")
answer = 'sell'
print(result)
else:
print("Predicted answer: Not confident")
answer = 'n/a'
print(result)
return answer
我遇到的问题是,当我运行这个预测函数时,我得到以下错误。
File "predict-binary.py", line 24, in predict
array = model.predict(x)
File ".venvlibsite-packagestensorflowpythonkerasenginetraining.py", line 1629, in predict
tmp_batch_outputs = self.predict_function(iterator)
File ".venvlibsite-packagestensorflowpythoneagerdef_function.py", line 828, in __call__
result = self._call(*args, **kwds)
File ".venvlibsite-packagestensorflowpythoneagerdef_function.py", line 871, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File ".venvlibsite-packagestensorflowpythoneagerdef_function.py", line 725, in _initialize
self._stateful_fn._get_concrete_function_internal_garbage_collected( # pylint: disable=protected-access
File ".venvlibsite-packagestensorflowpythoneagerfunction.py", line 2969, in _get_concrete_function_internal_garbage_collected
graph_function, _ = self._maybe_define_function(args, kwargs)
File ".venvlibsite-packagestensorflowpythoneagerfunction.py", line 3361, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File ".venvlibsite-packagestensorflowpythoneagerfunction.py", line 3196, in _create_graph_function
func_graph_module.func_graph_from_py_func(
File ".venvlibsite-packagestensorflowpythonframeworkfunc_graph.py", line 990, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File ".venvlibsite-packagestensorflowpythoneagerdef_function.py", line 634, in wrapped_fn
out = weak_wrapped_fn().__wrapped__(*args, **kwds)
File ".venvlibsite-packagestensorflowpythonframeworkfunc_graph.py", line 977, in wrapper
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:
.venvlibsite-packagestensorflowpythonkerasenginetraining.py:1478 predict_function *
return step_function(self, iterator)
.venvlibsite-packagestensorflowpythonkerasenginetraining.py:1468 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
.venvlibsite-packagestensorflowpythondistributedistribute_lib.py:1259 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
.venvlibsite-packagestensorflowpythondistributedistribute_lib.py:2730 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
.venvlibsite-packagestensorflowpythondistributedistribute_lib.py:3417 _call_for_each_replica
return fn(*args, **kwargs)
.venvlibsite-packagestensorflowpythonkerasenginetraining.py:1461 run_step **
outputs = model.predict_step(data)
.venvlibsite-packagestensorflowpythonkerasenginetraining.py:1434 predict_step
return self(x, training=False)
.venvlibsite-packagestensorflowpythonkerasenginebase_layer.py:1012 __call__
outputs = call_fn(inputs, *args, **kwargs)
.venvlibsite-packagestensorflowpythonkerasenginesequential.py:375 call
return super(Sequential, self).call(inputs, training=training, mask=mask)
.venvlibsite-packagestensorflowpythonkerasenginefunctional.py:424 call
return self._run_internal_graph(
.venvlibsite-packagestensorflowpythonkerasenginefunctional.py:560 _run_internal_graph
outputs = node.layer(*args, **kwargs)
.venvlibsite-packagestensorflowpythonkerasenginebase_layer.py:998 __call__
input_spec.assert_input_compatibility(self.input_spec, inputs, self.name)
.venvlibsite-packagestensorflowpythonkerasengineinput_spec.py:255 assert_input_compatibility
raise ValueError(
ValueError: Input 0 of layer dense is incompatible with the layer: expected axis -1 of input shape to have value 8192 but received input with shape (None, 61608)
我假设我需要改变我的模型的Flatten()
和Dense()
层之间的东西,但我不确定什么。我试图在这两者之间添加model.add(Dense(61608, activation='relu))
,因为这似乎是我看到的另一篇文章中建议的(现在找不到链接),但它导致了同样的错误。(我也试过用8192而不是61608)。任何帮助都是感激的,谢谢。
编辑# 1:
改变模型创建/训练代码,我认为这是由Gerry p建议的
img_shape = (151,136,3)
base_model=VGG19( include_top=False, input_shape=img_shape, pooling='max', weights='imagenet' )
x=base_model.output
x=Dense(100, activation='relu')(x)
x=Dropout(0.5)(x)
x=BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001)(x)
output=Dense(2, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
image_gen = ImageDataGenerator()
train = image_gen.flow_from_directory('./data/train', class_mode='categorical', shuffle=False, batch_size=10, target_size=(151, 136))
val = image_gen.flow_from_directory('./data/validate', class_mode='categorical', shuffle=False, batch_size=10, target_size=(151, 136))
vgg_features_train = base_model.predict(train)
vgg_features_val = base_model.predict(val)
train_target = to_categorical(train.labels)
val_target = to_categorical(val.labels)
model.compile(optimizer='rmsprop', metrics=['accuracy'], loss='categorical_crossentropy')
model.fit(vgg_features_train, train_target, epochs=100, batch_size=8, validation_data=(vgg_features_val, val_target), callbacks=callbacks_list)
这导致File "train-binary.py", line 37, in <module> model.fit(vgg_features_train, train_target, epochs=100, batch_size=8, validation_data=(vgg_features_val, val_target), callbacks=callbacks_list) ValueError: Input 0 is incompatible with layer model: expected shape=(None, 151, 136, 3), found shape=(None, 512)
的输入形状误差不同
您的模型期望看到model的输入。预测的维度与训练时的相同。在本例中,它是vgg_features_train的维度。模型的输入。您正在为VGG模型的输入生成的预测。你实际上是在尝试进行迁移学习所以我建议你按照以下步骤进行
base_model=tf.keras.applications.VGG19( include_top=False, input_shape=img_shape, pooling='max', weights='imagenet' )
x=base_model.output
x=Dense(100, activation='relu'))(x)
x=Dropout(0.5)(x)
x=BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001)(x)
output=Dense(2, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.fit( train, epochs=100, batch_size=8, validation_data=val, callbacks=callbacks_list)
现在,对于预测,您可以使用与训练模型相同的维度。