ValueError:形状(无,1)和(无,2)不兼容

fai*_*hid 24 keras tensorflow cnn

我正在训练一个面部表情(愤怒 vs 快乐)模型。最后一个密集输出层以前是 1,但是当我预测图像时,它的输出始终为 1,准确度为 64%。所以我将其更改为 2 以获取 2 个输出。但现在我收到这个错误::

Epoch 1/15

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-54-9c7272c38dcb> in <module>()
     11     epochs=epochs,
     12     validation_data = val_data_gen,
---> 13     validation_steps = validation_steps,
     14 
     15 )

10 frames

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
    966           except Exception as e:  # pylint:disable=broad-except
    967             if hasattr(e, "ag_error_metadata"):
--> 968               raise e.ag_error_metadata.to_exception(e)
    969             else:
    970               raise

ValueError: in user code:

    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:571 train_function  *
        outputs = self.distribute_strategy.run(
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:951 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:2290 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:2649 _call_for_each_replica
        return fn(*args, **kwargs)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:533 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:205 __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:143 __call__
        losses = self.call(y_true, y_pred)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:246 call
        return self.fn(y_true, y_pred, **self._fn_kwargs)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:1527 categorical_crossentropy
        return K.categorical_crossentropy(y_true, y_pred, from_logits=from_logits)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py:4561 categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py:1117 assert_is_compatible_with
        raise ValueError("Shapes %s and %s are incompatible" % (self, other))

    ValueError: Shapes (None, 1) and (None, 2) are incompatible
Run Code Online (Sandbox Code Playgroud)

相关代码是:

    model = Sequential([
    Conv2D(32,3, activation='relu', input_shape=(48,48,1)),
    BatchNormalization(),
    MaxPooling2D(pool_size=(3, 3)),
  
    Flatten(),
    Dense(512, activation='relu'),
    Dense(2,activation='softmax')
])
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])


model.summary()

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_6 (Conv2D)            (None, 46, 46, 32)        320       
_________________________________________________________________
batch_normalization_4 (Batch (None, 46, 46, 32)        128       
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 15, 15, 32)        0         
_________________________________________________________________
flatten_4 (Flatten)          (None, 7200)              0         
_________________________________________________________________
dense_8 (Dense)              (None, 512)               3686912   
_________________________________________________________________
dense_9 (Dense)              (None, 2)                 1026      
=================================================================
Total params: 3,688,386
Trainable params: 3,688,322
Non-trainable params: 64
_________________________________________________________________


epochs = 15
steps_per_epoch = train_data_gen.n//train_data_gen.batch_size
validation_steps = val_data_gen.n//val_data_gen.batch_size



history = model.fit(
    x=train_data_gen,
    steps_per_epoch=steps_per_epoch,
    epochs=epochs,
    validation_data = val_data_gen,
    validation_steps = validation_steps,
    
)
Run Code Online (Sandbox Code Playgroud)

Mik*_*ike 42

将 Categorical Cross Entropy 更改为 Binary Cross Entropy,因为您的输出标签是二进制的。也将 Softmax 更改为 Sigmoid,因为 Sigmoid 是二进制数据的正确激活函数

  • `loss='binary_crossentropy'` `激活='sigmoid'` (3认同)
  • 太棒了,已投票,@faiza 您能否接受这个答案,因为这是解决您的错误的答案? (2认同)
  • 这导致我出现另一个错误:“ValueError:logits和标签必须具有相同的形状((无,1)与(无,762))”,这与[这个SO问题](https://stackoverflow.com /q/48851558/940592) (2认同)
  • 检查@Muhammad Zakaria 的答案,它解决了“日志和标签错误” (2认同)

hun*_*273 21

如果您的数据集是image_dataset_from_directory使用加载的,请使用label_mode='categorical'

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  label_mode='categorical'
)
Run Code Online (Sandbox Code Playgroud)

或加载flow_from_directoryflow_from_dataframe然后使用class_mode='categorical'

train_ds = ImageDataGenerator.flow_from_directory(
  path,
  class_mode='categorical'
)
Run Code Online (Sandbox Code Playgroud)


小智 10

您可以将标签从二进制值更改为分类值,然后继续使用相同的代码。例如,

from keras.utils import to_categorical
one_hot_label = to_cateorical(input_labels)
# change to [1, 0, 0,..., 0]  --> [[0, 1], [1, 0], ..., [1, 0]]
Run Code Online (Sandbox Code Playgroud)

您可以通过此链接更好地了解Keras API

如果您想对两个类使用分类交叉熵,请使用 softmax 并进行一种热编码。对于二元分类,您可以使用二元交叉熵,如前面提到的使用 sigmoid 激活函数提到的答案。

  1. 分类交叉熵:
model = Sequential([
    Conv2D(32,3, activation='relu', input_shape=(48,48,1)),
    BatchNormalization(),
    MaxPooling2D(pool_size=(3, 3)),

    Flatten(),
    Dense(512, activation='relu'),
    Dense(2,activation='softmax')  # activation change
])
model.compile(optimizer='adam',
              loss='categorical_crossentropy', # Loss
              metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)
  1. 二元交叉熵
model = Sequential([
    Conv2D(32,3, activation='relu', input_shape=(48,48,1)),
    BatchNormalization(),
    MaxPooling2D(pool_size=(3, 3)),

    Flatten(),
    Dense(512, activation='relu'),
    Dense(1,activation='sigmoid') #activation change
])
model.compile(optimizer='adam',
              loss='binary_crossentropy', # Loss
              metrics=['accuracy'])

Run Code Online (Sandbox Code Playgroud)


小智 10

我面临着同样的问题,我的形状是

shape of X (271, 64, 64, 3)
shape of y (271,)
shape of trainX (203, 64, 64, 3)
shape of trainY (203, 1)
shape of testX (68, 64, 64, 3)
shape of testY (68, 1)
Run Code Online (Sandbox Code Playgroud)

loss="categorical_crossentropy"
Run Code Online (Sandbox Code Playgroud)

我把它改成

loss="sparse_categorical_crossentropy"
Run Code Online (Sandbox Code Playgroud)

它对我来说就像一种魅力

  • 如果你想使用“categorical_crossentropy”,标签应该是one-hot-encoded的。当标签以整数形式给出时,需要更改为“sparse_categorical_crossentropy”。使用“categorical_crossentropy”的优点是它可以为您提供类别概率,这在某些情况下可能很有用。 (24认同)

Moh*_*ler 6

在多标签分类的情况下,从“categorical_crossentropy”更改为“sparse_categorical_crossentropy”对我有用

  • 你的意思是**稀疏_分类_交叉熵**? (2认同)