您基本上是在尝试解决回归问题。除了您所做的之外,您还可以尝试其他一些事情:
- 使用ImageAugmentation 技术生成更多数据。此外,标准化图像。
- 使用更多的卷积层制作更深的模型。
- 对卷积层使用适当的权重初始化器可能是 He-normal。
- 在层之间使用BatchNormalization 使过滤器值的mean 和std 分别等于0 和1。
- 使用交叉熵损失,因为它有助于更好地计算梯度。在 MSE 中,梯度随着时间的推移变得非常小,尽管它似乎更适合回归问题。
- 尝试将优化器更改为 Adam。
- 如果您的数据集中有更多类,并且存在类不平衡问题,您可以使用 Focal loss,这是一种交叉熵损失的变体,它对错误分类的标签的惩罚比正确分类的标签更大分类标签。此外,减少批量大小和上采样应该会有所帮助。
- 使用贝叶斯优化技术对模型进行超参数调优。
示例模型代码:
with open(os.path.join(DATA_DIR, 'mnist.pickle'), 'rb') as fr:
X_train, Y_train, X_val, Y_val = pickle.load(fr)
X_train = X_train.reshape(60000, 784)
X_val = X_val.reshape(10000, 784)
X_train = X_train.astype('float32')
X_val = X_val.astype('float32')
X_train /= 255
X_val /= 255
nb_classes = 10
Y_train = to_categorical(Y_train, nb_classes)
Y_val = to_categorical(Y_val, nb_classes)
return X_train, Y_train, X_val, Y_val
def build_model(input_shape, dropout=True):
model = Sequential()
model.add(Conv2D(32, (5,5), activation='relu', kernel_initializer='he_uniform', padding='valid', input_shape=input_shape))
model.add(BatchNormalization())
model.add(MaxPooling2D((2,2), strides=1, padding='valid'))
if dropout:
model.add(Dropout(0.2))
model.add(Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='valid'))
model.add(Conv2D(128, (3,3), activation='relu', kernel_initializer='he_uniform', padding='valid'))
model.add(BatchNormalization())
model.add(MaxPooling2D((2,2), strides=2, padding='valid'))
if dropout:
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Dense(classes, activation='softmax', kernel_initializer='he_uniform'))
# optimizer = SGD(lr=0.01, decay-1e-6, momentum=0.9)
optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
return model