我正在尝试使用Google QuickDrawKeras图纸上训练分类器:

import numpy as np
from tensorflow.keras.layers import Conv2D, Dense, Flatten, MaxPooling2D
from tensorflow.keras.models import Sequential

model = Sequential()

model.add(Conv2D(filters=32, kernel_size=5, data_format="channels_last", activation="relu", input_shape=(28, 28, 1)))
model.add(MaxPooling2D(data_format="channels_last"))
model.add(Conv2D(filters=16, kernel_size=3, data_format="channels_last", activation="relu"))
model.add(MaxPooling2D(data_format="channels_last"))

model.add(Flatten(data_format="channels_last"))

model.add(Dense(units=128, activation="relu"))
model.add(Dense(units=64, activation="relu"))
model.add(Dense(units=4, activation="softmax"))

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

x = np.load("./x.npy")
y = np.load("./y.npy")

model.fit(x=x, y=y, batch_size=100, epochs=40, validation_split=0.2)


输入数据是一个4d数组,每个类具有12000个标准化图像(28 x 28 x 1)。输出数据是一个热编码矢量的数组。

如果我在四个班级上训练该模型,它会产生令人信服的结果:

tensorflow - Keras CNN过度适合四类以上-LMLPHP
tensorflow - Keras CNN过度适合四类以上-LMLPHP

(红色是训练数据,蓝色是验证数据)

我知道模型有点过拟合。但是,我想使体系结构尽可能简单,所以我接受了这一点。

我的问题是,只要添加一个任意类,该模型就会开始过度拟合:

tensorflow - Keras CNN过度适合四类以上-LMLPHP
tensorflow - Keras CNN过度适合四类以上-LMLPHP

我尝试了许多不同的方法来防止其过拟合,例如批处理规范化,退出,内核正则化器,更多的训练数据和不同的批处理大小,这些都没有带来任何显着的改进。

CNN过多适合我的原因可能是什么?



编辑:这是我用来创建x.npyy.npy的代码:

import numpy as np

from tensorflow.keras.utils import to_categorical

files = ['cat.npy', 'dog.npy', 'apple.npy', 'banana.npy', 'flower.npy']

SAMPLES = 12000

x = np.concatenate([np.load(f'./data/{f}')[:SAMPLES] for f in files]) / 255.0
y = np.concatenate([np.full(SAMPLES, i) for i in range(len(files))])

# (samples, rows, cols, channels)
x = x.reshape(x.shape[0], 28, 28, 1).astype('float32')
y = to_categorical(y)

np.save('./x.npy', x)
np.save('./y.npy', y)


.npy文件来自here

最佳答案

问题在于如何进行数据拆分。请注意,有5个类,您可以进行0.2验证拆分。默认情况下,没有改组,并且在代码中按顺序输入数据。那意味着什么:


训练数据完全由4个类组成:“ cat.npy”,“ dog.npy”,“ apple.npy”,“ banana.npy”。这是0.8训练的分裂。
测试数据为“ flower.npy”。这就是您的0.2验证拆分。该模型从未对此进行过训练,因此准确性非常差。


仅由于validation_split=0.2这一事实,才有可能获得这种结果,因此您将接近完美的类分离。



x = np.load("./x.npy")
y = np.load("./y.npy")

# Shuffle the data!
p = np.random.permutation(len(x))
x = x[p]
y = y[p]

model.fit(x=x, y=y, batch_size=100, epochs=40, validation_split=0.2)


如果我的假设正确,请将validation_split设置为0.5还应该为您提供更好的结果(尽管这不是解决方案)。

关于tensorflow - Keras CNN过度适合四类以上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56103207/

10-12 22:38