我有一个用于多标签分类的简单Keras代码,
from keras.models import Sequentialfrom keras.layers import Conv2D, GlobalAveragePooling2D, Dense, MaxPooling2D, Flattenfrom keras.callbacks import EarlyStoppingimport keras(x_train, y_train), (x_test, y_test) = keras.datasets.fashion_mnist.load_data()model = Sequential()model.add(Conv2D(64, (3,3), activation='relu', padding='same', input_shape=(x_train.shape[1],x_train.shape[2],1)))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Flatten())#model.add(Dense(128, activation='relu'))model.add(Dense(10, activation='softmax'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.summary()
现在,如您所见,在最后一层我使用了’sigmoid’,但由于这是多标签分类,我希望使用sigmoid。然而,如果我这样做,我会得到以下错误。
ValueError: 检查目标时出错:期望dense_2的形状为(10,),但得到的数组形状为(1,)
这里的解决方法是什么?
回答:
将loss='binary_crossentropy'
更改为loss='sparse_categorical_crossentropy'
。
当标签是独热编码时使用categorical_crossentropy
。否则,使用sparse_categorical_crossentropy
。
binary_crossentropy
在有两个类的情况下使用,它输出一个单一的神经元(或者在多输出分类的情况下可以输出多个神经元)。例如,如果神经元的值大于0.5
,则选择类1
,否则选择类0
(或者如果值低于某个阈值,则不选择任何类)。
另外,在某些keras
/tf.keras
版本中,时尚MNIST数据集没有通道维度,因此您需要手动添加它:
x_train, x_test = np.expand_dims(x_train, -1), np.expand_dims(x_test, -1)