如何获得Keras中的分类概率?

时间:2019-06-11 12:46:34

标签: keras classification conv-neural-network predict softmax

我正在尝试从训练有素的Keras模型中获取分类概率,但是当我使用model.predict(或model.predict_proba)方法时,得到的只是这种形式的数组: array([[[0。,0.,0.,0.,0.,0.,0.,1.,0.,0.]],dtype = float32)

所以基本上我得到了一个热编码的浮点数组。 “ 1”通常位于正确的位置,因此培训似乎效果很好。但是,为什么我不能取出这些概率呢?请参阅所用架构的代码。

首先我读入数据:

mnist_train = pd.read_csv('data/mnist_train.csv')
mnist_test = pd.read_csv('data/mnist_test.csv')

mnist_train_images = mnist_train.iloc[:, 1:].values
mnist_train_labels = mnist_train.iloc[:, :1].values
mnist_test_images = mnist_test.iloc[:, 1:].values
mnist_test_labels = mnist_test.iloc[:, :1].values

mnist_train_images = mnist_train_images.astype('float32')
mnist_test_images = mnist_test_images.astype('float32')
mnist_train_images /= 255   
mnist_test_images /= 255

mnist_train_labels = keras.utils.to_categorical(mnist_train_labels, 10)
mnist_test_labels = keras.utils.to_categorical(mnist_test_labels, 10)

mnist_train_images = mnist_train_images.reshape(60000,28,28,1)
mnist_test_images = mnist_test_images.reshape(10000,28,28,1)

然后我建立模型并进行训练:

num_classes = mnist_test_labels.shape[1] 

model = Sequential()

model.add(Conv2D(64, (5, 5), input_shape=(28, 28, 1), activation='relu', data_format="channels_last", padding="same"))
model.add(Conv2D(64, (5, 5), input_shape=(28, 28, 1), activation='relu', data_format="channels_last", padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3), activation='relu', data_format="channels_last", padding="same"))
model.add(Conv2D(128, (3, 3), activation='relu', data_format="channels_last", padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Dropout(0.2))

model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(mnist_train_images, mnist_train_labels, validation_data=(mnist_test_images, mnist_test_labels), epochs=20, batch_size=256, verbose=2)

scores = model.evaluate(mnist_test_images, mnist_test_labels, verbose=0)

print("CNN Error: %.2f%%" % (100-scores[1]*100))

model.save('mnist-weights.model')
model.save_weights("mnist-model.h5")
model_json = model.to_json()
with open("mnist-model.json", "w") as json_file:
    json_file.write(model_json)

但是当我随后将模型加载到另一个应用程序中并尝试预测这样的概率时,就会发生所描述的错误。我在做什么错了?

json_file = open('alphabet_keras/mnist_model.json', 'r')
model_json = json_file.read()
model = model_from_json(model_json)
model.load_weights("alphabet_keras/mnist_model.h5")

letter = cv2.cvtColor(someImg, cv2.COLOR_BGR2GRAY)
letter = fitSquare(letter,28,2) # proprietary function, doesn't matter
letter_expanded = np.expand_dims(letter, axis=0)
letter_expanded = np.expand_dims(letter_expanded, axis=3)
model.predict_proba(letter_expanded)#[0]

输出如下: array([[[0。,0.,0.,0.,0.,0.,0.,1.,0.,0.]],dtype = float32)

我期望类似: 数组([[[0.1,0.34,0.2,0.8,0.1,0.62,0.67,1.0,0.31,0.59]],dtype = float32)

没有任何类型的错误消息。请帮忙:)

1 个答案:

答案 0 :(得分:1)

您的预期输出不正确,对于分类,神经网络的输出是标签上的概率分布,这意味着概率在0到1之间,并且总和为1.0。您显示的值总和大于1.0。

关于您的特定问题,看起来概率已经饱和,这是由于您没有对像素值进行标准化(除以255)而导致的,这是您在训练和测试集上所做的,这种不一致会饱和输出神经元。