回忆一些神经网络的知识
第一种归一化到 0-1之间
第二种是上次用的
未归一化是椭圆,归一化后是正圆,这样梯度下降,等高线是正圆,计算梯度没有那么曲折,训练速度加快。
把一些节点随机失效弃用,变成一个子网络
还有一个降低计算量
定义一个深度神经网络
# tf.keras.models.Sequential()
model = keras.models.Sequential()
# 把输入数据拉直展平
model.add(keras.layers.Flatten(input_shape=[28, 28]))
# for循环添加20层
for _ in range(20):
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
optimizer = "sgd",
metrics = ["accuracy"])
查看模型
model.summary()
是一个二十层的神经网络
进行训练
学习曲线图
def plot_learning_curves(history):
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
# 纵坐标不够 修改(0, 3)
plt.gca().set_ylim(0, 3)
plt.show()
plot_learning_curves(history)
# 一开始loss变化不大,没有下降
# 1. 参数众多,训练不充分
# 2. 梯度消失 -> 链式法则 -> 复合函数f(g(x))
测试集的准确率
批归一化
# tf.keras.models.Sequential()
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
for _ in range(20):
model.add(keras.layers.Dense(100, activation="relu"))
# 添加批归一化 激活函数在批归一化之前
model.add(keras.layers.BatchNormalization())
# 下面是激活函数在批归一化之后
"""
# 没有激活函数的全连接层
model.add(keras.layers.Dense(100))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation('relu'))
"""
model.add(keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
optimizer = "sgd",
metrics = ["accuracy"])
批归一化后进行模型训练
训练图,可以发现一开始的loss不会不下降了
批归一化可以缓解梯度消失(批归一化可以使每层的值非常规整)
准确率
更改激活函数
# tf.keras.models.Sequential()
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
for _ in range(20):
# selu 自带归一化功能的一个激活函数
model.add(keras.layers.Dense(100, activation="selu"))
model.add(keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
optimizer = "sgd",
metrics = ["accuracy"])
训练效果
训练图像
- selu 缓解梯度消失的问题
- selu 训练时间加快
- 看图发现,在刚开始就能达到一个很好的效果,就有很好的准确率了
测试集验证
添加dropout
# tf.keras.models.Sequential()
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
for _ in range(20):
model.add(keras.layers.Dense(100, activation="selu"))
# 在最后层添加dropout 防止过拟合 比率设为0.5
model.add(keras.layers.AlphaDropout(rate=0.5))
# AlphaDropout: 1. 均值和方差不变 2. 归一化性质也不变
# 普通dropout
# model.add(keras.layers.Dropout(rate=0.5))
model.add(keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
optimizer = "sgd",
metrics = ["accuracy"])
训练结果
学习曲线
测试集准确率
如果这个数据集的过拟合不是很严重,那么dropout的效果就一般