我在使用Keras模型时遇到了一个问题。代码如下:
首先,这是输入数据,X是图像,之后会显示它们的维度
print(len(X), len(target))1500 1500
X = np.array(X, dtype="float") / 255.0target = to_categorical(target,10)target = np.array(target)X_train, X_test, y_train, y_test = train_test_split(X, target, test_size = 0.2, random_state = 777)X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size = 0.4, random_state = 777)
然后我展示了三个数据集的所有维度:
print("x_train shape = ", X_train.shape)print("y_train shape = ", y_train.shape)print("\nx_validation shape = ", X_val.shape)print("y_validation shape = ", y_val.shape)print("\nx_test shape = ", X_test.shape)print("y_test shape = ", y_test.shape)x_train shape = (720, 150, 150, 3)y_train shape = (720, 10)x_validation shape = (480, 150, 150, 3)y_validation shape = (480, 10)x_test shape = (300, 150, 150, 3)y_test shape = (300, 10)
从这里我们可以看出这些维度看起来是正常的
model=Sequential()model.add(Conv2D(filters=96,kernel_size=(11,11),strides=(4,4),padding="valid",activation="relu",input_shape=(150,150,3)))model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))model.add(BatchNormalization())model.add(Conv2D(filters=256,kernel_size=(5,5),strides=(1,1),padding="valid",activation="relu"))model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))model.add(BatchNormalization())model.add(Conv2D(filters=384,kernel_size=(3,3),strides=(1,1),padding="valid",activation="relu"))model.add(Conv2D(filters=384,kernel_size=(3,3),strides=(1,1),padding="valid",activation="relu"))model.add(Dense(4096,input_shape=(227,227,3),activation="relu"))model.add(Dropout(0.4))model.add(BatchNormalization())model.add(Dense(4096,activation="relu"))model.add(Dropout(0.4))model.add(BatchNormalization())model.add(Dense(1000,activation="relu"))model.add(Dropout(0.4))model.add(BatchNormalization())model.add(Dense(10, activation="softmax"))
这是我的错误信息:
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])history = model.fit(X_train, y_train, epochs=30)
Epoch 1/30---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-61-95c7b541e6c9> in <module>() 4 history = model.fit(X_train, 5 y_train,----> 6 epochs=EPOCHS)9 frames/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs) 975 except Exception as e: # pylint:disable=broad-except 976 if hasattr(e, "ag_error_metadata"):--> 977 raise e.ag_error_metadata.to_exception(e) 978 else: 979 raiseValueError: in user code: /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:805 train_function * return step_function(self, iterator) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:795 step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:1259 run return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2730 call_for_each_replica return self._call_for_each_replica(fn, args, kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:3417 _call_for_each_replica return fn(*args, **kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:788 run_step ** outputs = model.train_step(data) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:756 train_step y, y_pred, sample_weight, regularization_losses=self.losses) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/compile_utils.py:203 __call__ loss_value = loss_obj(y_t, y_p, sample_weight=sw) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:152 __call__ losses = call_fn(y_true, y_pred) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:256 call ** return ag_fn(y_true, y_pred, **self._fn_kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/util/dispatch.py:201 wrapper return target(*args, **kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:1537 categorical_crossentropy return K.categorical_crossentropy(y_true, y_pred, from_logits=from_logits) /usr/local/lib/python3.6/dist-packages/tensorflow/python/util/dispatch.py:201 wrapper return target(*args, **kwargs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py:4833 categorical_crossentropy target.shape.assert_is_compatible_with(output.shape) /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py:1134 assert_is_compatible_with raise ValueError("Shapes %s and %s are incompatible" % (self, other)) ValueError: Shapes (None, 10) and (None, 2, 2, 10) are incompatible
我查看了关于这种错误的一些话题,但没有一个能精确地帮助我..
回答:
错误是因为你的输出形状与标签形状不同而引发的。
如你所提供的,标签形状是(None, 10)
,这是正确的。
错误信息显示的输出形状是(None, 2, 2, 10)
,这是不正确的。
你的输出形状错误的原因是在第一个Dense
层之前和最后一个Conv2D
层之后没有添加Flatten
层来平展最后一个Conv2D
层的输出。(关于如何实现Flatten
层,请参考Keras文档,这很简单。)
你需要Flatten
层的原因是Keras的Dense
层不会自动将形状为(比如说)(10, 10, 30)的层平展为(10 * 10 * 30)。所以在最后一个Conv2D
层之后,你的输出形状可能是(2, 2, 384),经过第一个Dense
层后会变成(2, 2, 4096),经过最后一个Dense
层后会变成(2, 2, 10)。换句话说,Keras的Dense
层只会应用于它接收到的输入的最后一个维度。
一些相关点:
-
你不需要为
Dense
层指定input_shape
。 -
对于所有这类形状相关的错误,使用
model.summary()
来检查你的模型是一个很好的方法,可以帮助你发现神经网络结构中的错误之处。