Keras多类概率为0和1的值

问题描述 投票:1回答:2

我正在实现一个分类器来识别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,有谁知道为什么概率会出现这种情况?

python keras classification image-recognition cnn
2个回答
1
投票

使用 softmax 在最后一层,而不是 sigmoid.

model.add(Dense(3, activation='softmax'))

对于多类分类,要想得到概率,需要softmax。


1
投票

问题在你的输出层,你的问题是一个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)
© www.soinside.com 2019 - 2024. All rights reserved.