我正在实现一个分类器来识别3种不同类型的图像,我的最后一层有3个神经元,有sigmoid激活。
from keras.model import Sequential
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization, Dropout, Flatten, Dense
model = Sequential()
model.add(Conv2D(16, kernel_size=(3, 3), activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Dropout(0.2))
# more conv layers
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(3, activation='sigmoid'))
model.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
训练集标签使用的是一个热点编码,3个类别的训练例子都很丰富。
但当我运行 model.predict(X)
在测试装置上,前10个输出为
[[0. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[0. 1. 1.]
[1. 1. 1.]
[0. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
model.predict()
应该输出概率,而且每一行的概率加起来应该是1,但是在实际结果中,有时候每一类的概率都是1,有谁知道为什么概率会出现这种情况?
使用 softmax
在最后一层,而不是 sigmoid
.
model.add(Dense(3, activation='softmax'))
对于多类分类,要想得到概率,需要softmax。
问题在你的输出层,你的问题是一个MULTICLASS,所以你必须用正确的方式处理它。这些都是可能性。
如果你有一个1D整数编码的目标,你可以用sparse_categorical_crossentropy作为损失函数,用softmax作为最后的激活。
X = np.random.randint(0,10, (1000,100))
y = np.random.randint(0,3, 1000)
model = Sequential([
Dense(128, input_dim = 100),
Dense(3, activation='softmax'),
])
model.summary()
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)
否则,如果你有一个热编码你的目标,为了有2D形状(n_samples, n_class),你可以使用categorical_crossentropy和softmax作为最终的激活。
X = np.random.randint(0,10, (1000,100))
y = pd.get_dummies(np.random.randint(0,3, 1000)).values
model = Sequential([
Dense(128, input_dim = 100),
Dense(3, activation='softmax'),
])
model.summary()
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)