python - Keras predict_proba 中的神经网络总是返回概率等于 1
问题描述
我正在学习 ML,MNIST 集上的神经网络,我对 predict_proba 函数有疑问。我想收到我的模型做出的预测概率,但是当我调用函数 predict_proba 时,我总是收到像 [0, 0, 1., 0, 0, ...] 这样的数组,这意味着模型总是以 100% 的概率进行预测。
你能告诉我我的模型有什么问题吗,为什么会发生这种情况以及如何解决它?
我的模型看起来像:
# Load MNIST data set and split to train and test sets
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Reshaping to format which CNN expects (batch, height, width, channels)
train_images = train_images.reshape(train_images.shape[0], train_images.shape[1], train_images.shape[2], 1).astype(
"float32")
test_images = test_images.reshape(test_images.shape[0], test_images.shape[1], test_images.shape[2], 1).astype("float32")
# Normalize images from 0-255 to 0-1
train_images /= 255
test_images /= 255
# Use one hot encode to set classes
number_of_classes = 10
train_labels = keras.utils.to_categorical(train_labels, number_of_classes)
test_labels = keras.utils.to_categorical(test_labels, number_of_classes)
# Create model, add layers
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(train_images.shape[1], train_images.shape[2], 1), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(number_of_classes, activation="softmax"))
# Compile model
model.compile(loss="categorical_crossentropy", optimizer=Adam(), metrics=["accuracy"])
# Learn model
model.fit(train_images, train_labels, validation_data=(test_images, test_labels), epochs=7, batch_size=200)
# Test obtained model
score = model.evaluate(test_images, test_labels, verbose=0)
print("Model loss = {}".format(score[0]))
print("Model accuracy = {}".format(score[1]))
# Save model
model_filename = "cnn_model.h5"
model.save(model_filename)
print("CNN model saved in file: {}".format(model_filename))
对于加载图像,我使用 PIL 和 NP。我使用 keras 中的 save 函数保存模型并使用 keras.models 中的 load_model 将其加载到另一个脚本中,然后我只需调用
def load_image_for_cnn(filename):
img = Image.open(filename).convert("L")
img = np.resize(img, (28, 28, 1))
im2arr = np.array(img)
return im2arr.reshape(1, 28, 28, 1)
def load_cnn_model(self):
return load_model("cnn_model.h5")
def predict_probability(self, image):
return self.model.predict_proba(image)[0]
使用它看起来像:
predictor.predict_probability(predictor.load_image_for_cnn(filename))
解决方案
查看代码的这一部分:
# Normalize images from 0-255 to 0-1
train_images /= 255
test_images /= 255
您在加载新图像时不会这样做:
def load_image_for_cnn(filename):
img = Image.open(filename).convert("L")
img = np.resize(img, (28, 28, 1))
im2arr = np.array(img)
return im2arr.reshape(1, 28, 28, 1)
应用与训练集相同的归一化是测试任何新图像的要求,如果你不这样做,你会得到奇怪的结果。您可以按如下方式标准化图像像素:
def load_image_for_cnn(filename):
img = Image.open(filename).convert("L")
img = np.resize(img, (28, 28, 1))
im2arr = np.array(img)
im2arr = im2arr / 255.0
return im2arr.reshape(1, 28, 28, 1)
推荐阅读
- python - 实例化一个类在循环时第二次给出可疑的结果
- reactjs - antd 在反应应用程序中但无法编译
- java - 如何更改在 Java 中执行递归函数的顺序?
- javascript - 等待 setState 完成
- sql - 无法从具有公共列但不相互依赖的多个独立表中获取数据
- mongodb - 两个日期之间的mongodb持续时间
- python - 我正在 python 中形成一个 if-else 代码,输出应该是正确的答案,但它正在打印代码的 else 部分,我不知道为什么
- python - 函数的输出未显示
- vba - python - win32com -> powerpoint.application:跳过密码弹出对话框
- openssl - Using Embarcadero 10.1 Berlin with OpenSSL (C++)