为了解决在深度神经网络训练初期降低梯度消失/爆炸问题,Sergey loffe和Christian Szegedy提出了使用批量归一化的技术的方案,该技术包括在每一层激活函数之前在模型里加一个操作,简单零中心化和归一化输入,之后再通过每层的两个新参数(一个缩放,另一个移动)缩放和移动结果,话句话说,这个操作让模型学会最佳模型和每层输入的平均值

批量归一化原理

(1)\(\mu_B = \frac{1}{m_B}\sum_{i=1}^{m_B}x^{(i)}\) #经验平均值,评估整个小批量B

(2)\(\theta_B = \frac{1}{m_B}\sum_{i=1}^{m_b}(x^{(i)} - \mu_B)^2\) #评估整个小批量B的方差

(3)\(x_{(i)}^* = \frac{x^{(i)} - \mu_B}{\sqrt{\theta_B^2+\xi}}\)#零中心化和归一化

(4)\(z^{(i)} = \lambda x_{(i)}^* + \beta\)#将输入进行缩放和移动

在测试期间,没有小批量的数据来计算经验平均值和标准方差,所有可以简单地用整个训练集的平均值和标准方差来代替,在训练过程中可以用变动平均值有效计算出来

但是,批量归一化的确也给模型增加了一些复杂度和运行代价,使得神经网络的预测速度变慢,所以如果逆需要快速预测,可能需要在进行批量归一化之前先检查以下ELU+He初始化的表现如何

tf.layers.batch_normalization使用

函数原型

def batch_normalization(inputs,
axis=-1,
momentum=0.99,
epsilon=1e-3,
center=True,
scale=True,
beta_initializer=init_ops.zeros_initializer(),
gamma_initializer=init_ops.ones_initializer(),
moving_mean_initializer=init_ops.zeros_initializer(),
moving_variance_initializer=init_ops.ones_initializer(),
beta_regularizer=None,
gamma_regularizer=None,
beta_constraint=None,
gamma_constraint=None,
training=False,
trainable=True,
name=None,
reuse=None,
renorm=False,
renorm_clipping=None,
renorm_momentum=0.99,
fused=None,
virtual_batch_size=None,
adjustment=None):

使用注意事项

(1)使用batch_normalization需要三步:

a.在卷积层将激活函数设置为None
b.使用batch_normalization
c.使用激活函数激活 例子:
inputs = tf.layers.dense(inputs,self.n_neurons,
kernel_initializer=self.initializer,
name = 'hidden%d'%(layer+1))
if self.batch_normal_momentum:
inputs = tf.layers.batch_normalization(inputs,momentum=self.batch_normal_momentum,train=self._training) inputs = self.activation(inputs,name = 'hidden%d_out'%(layer+1))

(2)在训练时,将参数training设置为True,在测试时,将training设置为False,同时要特别注意update_ops的使用

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
需要在每次训练时更新,可以使用sess.run(update_ops)
也可以:
with tf.control_dependencies(update_ops):
train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)

使用mnist数据集进行简单测试

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
x_train,y_train = mnist.train.images,mnist.train.labels
x_test,y_test = mnist.test.images,mnist.test.labels
Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
he_init = tf.contrib.layers.variance_scaling_initializer()
def dnn(inputs,n_hiddens=1,n_neurons=100,initializer=he_init,activation=tf.nn.elu,batch_normalization=None,training=None):
for layer in range(n_hiddens):
inputs = tf.layers.dense(inputs,n_neurons,kernel_initializer=initializer,name = 'hidden%d'%(layer+1))
if batch_normalization is not None:
inputs = tf.layers.batch_normalization(inputs,momentum=batch_normalization,training=training)
inputs = activation(inputs,name = 'hidden%d'%(layer+1))
return inputs
tf.reset_default_graph()
n_inputs = 28*28
n_hidden = 100
n_outputs = 10 X = tf.placeholder(tf.float32,shape=(None,n_inputs),name='X')
Y = tf.placeholder(tf.int32,shape=(None,n_outputs),name='Y') training = tf.placeholder_with_default(False,shape=(),name='tarining')
dnn_outputs = dnn(X) logits = tf.layers.dense(dnn_outputs,n_outputs,kernel_initializer = he_init,name='logits')
y_proba = tf.nn.softmax(logits,name='y_proba')
xentropy = tf.nn.softmax_cross_entropy_with_logits(labels=Y,logits=y_proba)
loss = tf.reduce_mean(xentropy,name='loss')
train_op = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss) correct = tf.equal(tf.argmax(Y,1),tf.argmax(y_proba,1))
accuracy = tf.reduce_mean(tf.cast(correct,tf.float32)) epoches = 20
batch_size = 100
np.random.seed(42) init = tf.global_variables_initializer()
rnd_index = np.random.permutation(len(x_train))
n_batches = len(x_train) // batch_size
with tf.Session() as sess:
sess.run(init)
for epoch in range(epoches):
for batch_index in np.array_split(rnd_index,n_batches):
x_batch,y_batch = x_train[batch_index],y_train[batch_index]
feed_dict = {X:x_batch,Y:y_batch,training:True}
sess.run(train_op,feed_dict=feed_dict)
loss_val,accuracy_val = sess.run([loss,accuracy],feed_dict={X:x_test,Y:y_test,training:False})
print('epoch:{},loss:{},accuracy:{}'.format(epoch,loss_val,accuracy_val))

批量归一化batch_normalization的更多相关文章

  1. 第十八节,TensorFlow中使用批量归一化(BN)

    在深度学习章节里,已经介绍了批量归一化的概念,详情请点击这里:第九节,改善深层神经网络:超参数调试.正则化以优化(下) 神经网络在进行训练时,主要是用来学习数据的分布规律,如果数据的训练部分和测试部分 ...

  2. TensorFlow——批量归一化操作

    批量归一化 在对神经网络的优化方法中,有一种使用十分广泛的方法——批量归一化,使得神经网络的识别准确度得到了极大的提升. 在网络的前向计算过程中,当输出的数据不再同一分布时,可能会使得loss的值非常 ...

  3. 深度学习面试题21:批量归一化(Batch Normalization,BN)

    目录 BN的由来 BN的作用 BN的操作阶段 BN的操作流程 BN可以防止梯度消失吗 为什么归一化后还要放缩和平移 BN在GoogLeNet中的应用 参考资料 BN的由来 BN是由Google于201 ...

  4. Batch Normalization批量归一化

    BN的深度理解:https://www.cnblogs.com/guoyaohua/p/8724433.html BN: BN的意义:在激活函数之前将输入归一化到高斯分布,控制到激活函数的敏感区域,避 ...

  5. 从头学pytorch(十九):批量归一化batch normalization

    批量归一化 论文地址:https://arxiv.org/abs/1502.03167 批量归一化基本上是现在模型的标配了. 说实在的,到今天我也没搞明白batch normalize能够使得模型训练 ...

  6. 机器学习(ML)十三之批量归一化、RESNET、Densenet

    批量归一化 批量归一化(batch normalization)层,它能让较深的神经网络的训练变得更加容易.对图像处理的输入数据做了标准化处理:处理后的任意一个特征在数据集中所有样本上的均值为0.标准 ...

  7. [ DLPytorch ] 批量归一化与残差网络

    批量归一化 通常来说,数据标准化预处理对于浅层模型就足够有效了.随着模型训练的进行,当每层中参数更新时,靠近输出层的输出较难出现剧烈变化.但对深层神经网络来说,即使输入数据已做标准化,训练中模型参数的 ...

  8. 【python实现卷积神经网络】批量归一化层实现

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  9. L18 批量归一化和残差网络

    批量归一化(BatchNormalization) 对输入的标准化(浅层模型) 处理后的任意一个特征在数据集中所有样本上的均值为0.标准差为1. 标准化处理输入数据使各个特征的分布相近 批量归一化(深 ...

随机推荐

  1. 使用 Python 连接 Caché 数据库

    有不少医院的 HIS 系统用的是 Caché 数据库,比如北京协和医院.四川大学华西医院等.用过 Caché 开发的都知道,Caché 数据库的开发维护同我们常见的关系型数据库有很大差别,如 SQL ...

  2. 使用iview--1

    在任意一个你想创建项目的路径下 每次输入就输一致的就可以 /*************************安装选项开始****************/ 回车再次回车就如下,输入Y 继续 回车,输 ...

  3. 【Python】深入浅出学习Python的yield和generator

    背景 之前走马观花接触过Python协程的概念,这两天和一个同事聊到了协程,死活想不起来曾经看过的东西,就记得一个yield,概念不清: 所以想捋一捋相关的东西,此篇作为学习的记录. Generato ...

  4. 【三小时学会Kubernetes!(三) 】Service实践

    服务Service Kubernetes 服务资源可以作为一组提供相同服务的 Pod 的入口.这个资源肩负发现服务和平衡 Pod 之间负荷的重任,如图 16 所示. 图16:Kubernetes 服务 ...

  5. GTID主从 与 传统主从复制

    一.主从复制 1.)普通主从复制: 普通主从复制主要是基于二进制日志文件位置的复制,因此主必须启动二进制日志记录并建立唯一的服务器ID,复制组中的每个服务器都必须配置唯一的服务器ID.如果您省略ser ...

  6. PHP表单(get,post)提交方式

    PHP 表单处理 PHP 超全局变量 $_GET 和 $_POST 用于收集表单数据(form-data). $_GET 是通过 URL 参数传递到当前脚本的变量数组. $_POST 是通过 HTTP ...

  7. 使用Idea工具nodeJS+mysql开发项目

    一.MySQL Server的安装 1.mysql官网下载文件包:[我使用的版本是:mysql_5.7.17] 2.解压Zip压缩包: 3.安装:命令行:D:\soft\mysql-5.7.17-wi ...

  8. 外层页面与iframe相互调用的方法

    iframe调用外层页面的方法: parent.func(); 外层页面调用里面的iframe中的内容方法:  $("iframe").contents().find(" ...

  9. Python 脚本注册为Windows Service

    这部分内容就如同标题所讲的,其他的也不说了,直接上代码吧 需要说明的是,此代码在我的Win10 下可以正常使用,而在windows server 2008没有运行成功. 如果出现拒绝访问的错误,请使用 ...

  10. influxdb和boltDB简介——MVCC+B+树,Go写成,Bolt类似于LMDB,这个被认为是在现代kye/value存储中最好的,influxdb后端存储有LevelDB换成了BoltDB

    influxdb influxdb是最新的一个时间序列数据库,最新一两年才产生,但已经拥有极高的人气.influxdb 是用Go写的,0.9版本的influxdb对于之前会有很大的改变,后端存储有Le ...