构建网络的总原则
- 增大网络容量,直到过拟合。
- 采取措施抑制过拟合。
- 继续增大网络容量,直到过拟合。
过拟合与欠拟合
过拟合:在训练数据上得分很高,在测试数据上得分相对比较低。
欠拟合:在训练数据上得分比较低,在测试数据上得分相对比较低。
dropout
为什么说dropout可以解决过拟合
- 取平均的作用:先回到标准的模型即没有dropout,我们用相同的训练数据去训练5个不同的神经网络,一般会得到5个不同的结果,此时我们可以采用“5个结果取均值”或者“多数取胜的投票策略”来决定最终结果。
- 减少神经元之间复杂的共适应关系:因为dropout程序导致两个神经元不一定每次都在一个dropout网络中出现。这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况。
- dropout类似于性别在生物进化中的角色。
参数选择原则
理想的模型是刚好在欠拟合和过拟合的界线上,也就是正好拟合数据。
首先开发一个过拟合的模型:
- 添加更多的层。
- 让每一层变得更大。
- 训练更多的轮次。
抑制过拟合:(没有训练数据的情况下)
- dropout。
- 正则化。
- 图像增强。
再次,调节超参数:
- 学习速率。
- 隐藏层单元数。
- 训练轮次。
- 超参数的选择是一个经验与不断测试的结果。
- 经典机器学习的方法,如特征工程、增加训练数据。
- 注意交叉验证。
添加dropout层训练
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28))) # 28*28
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10,activation='softmax')) #把输出变成概率分布
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['acc']
)
model.fit(train_image,train_label_onehot,epochs=10)
结果如下:
查看loss曲线和acc曲线
小型网络训练
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28))) # 28*28
model.add(tf.keras.layers.Dense(32,activation='relu'))
model.add(tf.keras.layers.Dense(10,activation='softmax')) #把输出变成概率分布
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['acc']
)
history = model.fit(train_image,train_label_onehot,
epochs=10,
validation_data=(test_image,test_label_onehot))
训练结果如下:
loss值和acc值如下: