计算机系统应用教程网站

网站首页 > 技术文章 正文

机器学习100天-Day2302 深层神经网络(批量标准化)

btikc 2024-09-06 18:08:08 技术文章 10 ℃ 0 评论

说明:本文依据《Sklearn 与 TensorFlow 机器学习实用指南》完成,所有版权和解释权均归作者和翻译成员所有,我只是搬运和做注解。

进入第二部分深度学习

第十一章训练深层神经网络

在第十章以及之前tf练习中,训练的深度神经网络都只是简单的demo,如果增大数据量或是面对更多的特征,遇到的问题就会棘手起来。

  • 梯度消失(梯度爆炸),这会影响深度神经网络,并使较低层难以训练
  • 训练效率
  • 包含数百万参数的模型将会有严重的过拟合训练集的风险
  • 本章中,教程从解释梯度消失问题开始,并探讨解决这个问题的一些最流行的解决方案。
  • 接下来讨论各种优化器,与普通梯度下降相比,它们可以加速大型模型的训练。
  • 介绍大型神经网络正则化技术。

5.批量标准化

尽管使用 He初始化和 ELU(或任何 ReLU 变体)可以显著减少训练开始阶段的梯度消失/爆炸问题,但不保证在训练期间问题不会回来,这样就提出了批量标准化策略,通过对每一层的输入值进行zero-centering和规范化,然后每层使用两个新参数(一个用于尺度变换,另一个用于偏移)对结果进行尺度变换和偏移。

这个操作可以让模型学习到每层输入值的最佳尺度,均值。为了对输入进行归零和归一化,算法需要估计输入的均值和标准差。通过评估当前小批量输入的均值和标准差(因此命名为“批量标准化”)来实现。

tensorflow中使用tf.layers.batch_normalization()完成批量标准化。

以下代码为一个完整的经过标准化的神经网络

reset_graph()
import tensorflow as tf
(X_train,y_train),(X_test,y_test)=tf.keras.datasets.mnist.load_data()
X_train=X_train.astype(np.float32).reshape(-1,28*28)/255.0
X_test = X_test.astype(np.float32).reshape(-1, 28*28) / 255.0
y_train = y_train.astype(np.int32)
y_test = y_test.astype(np.int32)
X_valid, X_train = X_train[:5000], X_train[5000:]
y_valid, y_train = y_train[:5000], y_train[5000:]
n_inputs = 28 * 28
n_hidden1 = 300
n_hidden2 = 100
n_outputs = 10
#可以看到每一层以及输出层都做了标准化
X = tf.placeholder(tf.float32, shape=(None, n_inputs), name="X")
training = tf.placeholder_with_default(False, shape=(), name="training")
hidden1 = tf.layers.dense(X, n_hidden1, name="hidden1")
bn1 = tf.layers.batch_normalization(hidden1, training=training, momentum=0.9)
bn1_act = tf.nn.elu(bn1)
hidden2 = tf.layers.dense(X, n_hidden2, name="hidden2")
bn2 = tf.layers.batch_normalization(hidden2, training=training, momentum=0.9)
bn2_act = tf.nn.elu(bn2)
logits_before_bn = tf.layers.dense(bn2_act, n_outputs, name="outputs")
logits = tf.layers.batch_normalization(logits_before_bn, training=training, momentum=0.9)

现在构建一个处理MNIST数据集的神经网络,每一层使用ELU作为激活函数

reset_graph()
batch_norm_momentum=0.9
X = tf.placeholder(tf.float32, shape=(None, n_inputs), name="X")
y=tf.placeholder(tf.int32, shape=(None), name="y")
training=tf.placeholder_with_default(False, shape=(), name="training")
with tf.name_scope("dnn"):
 he_init=tf.variance_scaling_initializer()
 # 为了防止重复设定参数,这里使用了Python的partial方法
 # 对权重的初始化
 my_batch_norm_layer=partial(
 tf.layers.batch_normalization,
 training=training,
 momentum=batch_norm_momentum
 )
 my_dense_layer=partial(
 tf.layers.dense,
 kernel_initializer=he_init
 )
 hidden1=my_dense_layer(X,n_hidden1,name="hidden1")
 bn1=tf.nn.elu(my_batch_norm_layer(hidden1))
 hidden2=my_dense_layer(bn1,n_hidden2,name="hidden2")
 bn2=tf.nn.elu(my_batch_norm_layer(hidden2))
 logits_before_bn=my_dense_layer(bn2,n_outputs,name="outputs")
 logits=my_batch_norm_layer(logits_before_bn)
with tf.name_scope("loss"):
 xentropy=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
 loss=tf.reduce_mean(xentropy,name="loss")
learning_rate = 0.01
with tf.name_scope("train"):
 optimizer=tf.train.GradientDescentOptimizer(learning_rate)
 training_op = optimizer.minimize(loss)
with tf.name_scope("eval"):
 correct=tf.nn.in_top_k(logits,y,1)
 accuracy=tf.reduce_mean(tf.cast(correct,tf.float32))
init=tf.global_variables_initializer()
saver=tf.train.Saver()
n_epochs=20
batch_size=200
def shuffle_batch(X, y, batch_size):
 rnd_idx = np.random.permutation(len(X))
 n_batches = len(X) // batch_size
 for batch_idx in np.array_split(rnd_idx, n_batches):
 X_batch, y_batch = X[batch_idx], y[batch_idx]
 yield X_batch, y_batch
extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.Session() as sess:
 init.run()
 for epoch in range(n_epochs):
 for X_batch , y_batch in shuffle_batch(X_train, y_train, batch_size):
 sess.run([training_op,extra_update_ops],
 feed_dict={training:True,X:X_batch,y:y_batch}
 )
 accuracy_val=accuracy.eval(feed_dict={X:X_valid,y:y_valid})
 print(epoch, accuracy_val)
 save_path=saver.save(sess,"./tf_logs/run-2019012801001/tensorflowmodel01normalization.ckpt")

 

以下使训练结果,因为设置的随机种子都是42,可以看到结果和教程中的一致。

0 0.8952

1 0.9202

2 0.9318

3 0.9422

4 0.9468

5 0.954

6 0.9568

7 0.96

8 0.962

9 0.9638

10 0.9662

11 0.9682

12 0.9672

13 0.9696

14 0.9706

15 0.9704

16 0.9718

17 0.9726

18 0.9738

19 0.9742

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表