为什么 CNN 模型很难对彩色 MNIST 进行分类?

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

我正在尝试使用 Keras 上的基本 CNN 架构对彩色 MNIST 数字进行分类。这是将原始数据集着色为纯红色、绿色或蓝色的代码。

def load_norm_data():
  ## load basic mnist
  (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
  train_images = np.zeros((*x_train.shape, 3)) # orig shape: (60 000, 28, 28, 1) -> rgb shape: (60 000, 28, 28, 3)
  for num in range(x_train.shape[0]):
    rgb = np.random.randint(3) 
    train_images[num, ..., rgb] = x_train[num]/255
  return train_images, y_train
  
if __name__ == '__main__':
  ims, labels = load_norm_data()
  for num in range(10):
    plt.subplot(2, 5, num+1)
    plt.imshow(ims[num])
    plt.axis('off')

给出前几个数字:

enter image description here

然后,我尝试将这个彩色数据集分类为 MNIST 的相同 10 位数字类别,因此标签不会改变——但模型准确度从非彩色 MNIST 的 95% 下降到变化很大的 30-70%在彩色 MNIST 上,很大程度上取决于权重初始化...请在下面找到所述模型的架构:

model = keras.Sequential()
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), padding='same'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), padding='same'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2), padding='same'))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(10, activation='relu'))
model.add(keras.layers.Softmax())

input_shape = train_images.shape
model.build(input_shape)

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

model.fit(train_images, train_numbers, batch_size=12, epochs=25)

最初,我认为这种性能下降可能与数据不规则性有关(例如,想象数据中的很多 3 最终变成绿色,因此模型学习绿色 = 3)。所以我检查了数据,计数很好,每个类别的 RGB 分布也接近每种颜色的 33%。我还检查了错误分类的图像,看看是否有很多特定颜色或数字的代表,但似乎也不是这种情况。无论如何,在阅读了 Keras 的文档之后,由于

Conv2D
迫使您向其传递一个二维
kernel_size
,我认为它可以在输入图像的所有通道上运行,因此模型不应该采用此处考虑分类时的颜色。

我在这里遗漏了什么吗?

python keras conv-neural-network rgb mnist
1个回答
3
投票

模型的最后一部分包括一个dense -> relu -> softmax。应删除 relu 激活。此外,您可能会受益于在卷积块中添加非线性(例如 relu)。否则,神经网络最终将成为一个(大)线性函数,并且不能很好地处理非线性数据。

model = keras.Sequential()
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2), padding='same'))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(10))
model.add(keras.layers.Softmax())

有趣的是,原始模型在 MNIST 数据集上运行良好。我无法确定原因,但也许 MNIST 数据集足够简单,模型能够应对。此外,

relu -> softmax
会将负值限制为 0,而且负值可能并不多。

© www.soinside.com 2019 - 2024. All rights reserved.