【问题标题】:Simple binary classification by CNN with Keras, But got only 50% accCNN 与 Keras 的简单二进制分类,但只得到 50% 的准确率
【发布时间】:2019-03-26 13:25:35
【问题描述】:

今天我尝试使用 fit_generator 函数对纯黑白图像进行二进制分类,但它的准确率只有 50%

这只是我的编码练习,但我认为准确度应该达到 100%。所以我很好奇我的错误是什么。

我在 Google-colaboratory 中编写所有代码。

这是我的代码。

设置

import numpy as np
import random
from matplotlib import pyplot as plt

img_height = 150
img_width = 150
batch_size = 8

class MyDataset(object):

    def __init__(self):
        placeholder = 0

    def generator(self):
        is_black = True
        X, y = [], []
        while True:
            if is_black:
                img = np.full((img_height, img_width, 3), 255)
            else:
                img = np.zeros((img_height, img_width, 3))
            img = img / 255.
            X.append(img)
            y.append(is_black)
            is_black = not is_black

            if len(X) >= batch_size:
                c = list(zip(X, y))
                random.shuffle(c)
                X, y = zip(*c)
                yield np.asarray(X, dtype=np.float32), np.asarray(y, dtype=np.float32)
                X, y = [], []

dataset = MyDataset()
sample_gen = dataset.generator()

数据可视化

Example of inputs for model

X, y = next(sample_gen)

label_dict = {0:'black', 1:'white'}

sample_size = len(X)

fig = plt.figure(figsize=(16, 8))

for sample in range(sample_size):
    img = X[sample]
    lbl = label_dict[y[sample]]

    fig.add_subplot(2, sample_size//2, sample + 1)
    f = plt.imshow(img)
    f.axes.get_xaxis().set_visible(False)
    f.axes.get_yaxis().set_visible(False)
    plt.title(lbl)

plt.show()

创建模型

我创建了一个小尺寸模型。它只有 9 个参数。

import tensorflow as tf

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(filters=1, kernel_size=(1,1), padding='same', 
                                 activation='relu', input_shape=(img_height, img_width, 3)))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(img_height//2,img_height//2)))

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1, activation='softmax'))

model.summary()

训练模型

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

model.fit_generator(
    sample_gen, 
    steps_per_epoch = 100//batch_size , 
    epochs=300)

结果

200+ epochs 后,准确率仍为 0.5。

Epoch 218/300
12/12 [==============================] - 0s 8ms/step - loss: 7.9712 - acc: 0.5000
Epoch 219/300
12/12 [==============================] - 0s 8ms/step - loss: 7.9712 - acc: 0.5000
Epoch 220/300
12/12 [==============================] - 0s 8ms/step - loss: 7.9712 - acc: 0.5000
Epoch 221/300
12/12 [==============================] - 0s 9ms/step - loss: 7.9712 - acc: 0.5000
Epoch 222/300
12/12 [==============================] - 0s 8ms/step - loss: 7.9712 - acc: 0.5000

我已经学习了一些关于 CNN 的知识,并且我是 Keras 的初学者。

【问题讨论】:

  • 不要在输出上应用 softmax。它会做...... softmax,所以无论输入如何,你总是得到一个 1 作为模型的输出。 Logistic sigmoid 是要走的路。

标签: python tensorflow keras jupyter-notebook google-colaboratory


【解决方案1】:

问题出现在模型定义的末尾,特别是这里:

model.add(tf.keras.layers.Dense(1, activation='softmax'))

通过应用 softmax,您 - 根据定义 - 强制它的输出总和为 1。单个值如何遵守的唯一方法是自身变为 1。因此,不会传播任何信息。

要修复它,请将 softmax 转换为逻辑 sigmoid,例如:

model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

这样,您还可以将模型的输出解释为数据来自类1的后验概率。

【讨论】:

  • 感谢您的回答。你帮了我很多!!!!为了解决这个问题,我改变了 2 个激活函数。 (从relutanhsoftmaxsigmoid
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-15
  • 2019-01-05
相关资源
最近更新 更多