卷积神经网络实例3:深度学习的模型训练技巧

把卷积核裁开,从而减少计算量,是等价计算。比如3x3可以裁成3x1和1x3

多通道卷积

批量归一化(BN算法),一般用在全连接或卷积神经网络中。

       梯度爆炸问题:因为网络的内部协变量转移,即正向传播时的不同层的参数会将反向训练计算时所参照的数据样本分布改变。

这就是引入批量正则化的目的。它的作用是要最大限度地保证每次的正向传播输出在同一分布上,这样反向计算时参照的数据样本分布就会与正向计算时的数据分布一样了。保证了分布统一,对权重的调整才会更有意义。

       了解了原理之后,再来看批量正则化的做法就会变得很简单,即将每一层运算出来的数据都归一化成均值为0方差为1的标准高斯分布。这样就会保留样本分布特征的同时,又消除了层与层之间的分布差异。

提示:在实际应用中,批量归一化的收敛非常快,并且具有很强的泛化能力,某种情况下可以完全替代前面讲过的正则化、Dropout。

tf.nn.batch_normalization(x, mean, variance, offset, scale, variant, name=None)

  • x:代表输入
  • mean:代表样本的均值
  • variance:代表方差
  • offset:代表偏移,即相加一个转化值,后面会用激活函数来转换,所以这里不需要再转化,直接使用0.
  • scale:代表缩放,即乘以一个转化值,同理,一般用1。
  • variance_epsilon:是为了避免分母为0的情况,给分母加一个极小值。默认即可。

要想使用这个函数,必须由另一个函数配合-tf.nn.moments。由它来计算均值,然后就可以使用BN

tf.nn.moments(x, axes,name=None, keep_dims=False);axes指哪个轴来求均值与方差。

注意:axes在使用过程中经常容易犯错。这里提供一个小技巧,为了求样本的均值和方差,一般都会设为保留最后一个维度,对于x来将可以直接使用公式axes=list(range(len(x.get_shape())-1)即可。例如,[128,3,3,12] axes就为[0,1,2],输出的均值方差维度为[12]

有了上面的两个函数还不够,为了有更好的效果,我们希望使用平滑指数衰减的方法来优化每次的均值与方差,于是就用到了tf.train.ExponentialMovingAverage函数。它的作用是让上一次的值对本次的值有个衰减后的影响,从而使每次的值连起来后会相对平滑一些。

layers模块里对上面几个函数合并到了一起。

from tensorflow.contrib.layers.python.layers import batch_norm
def batch_norm( inputs, 
                decay=0.999,    # 一般为0.9
                center=True, 
                scale=False,    # 一般为False
                epsilon=0.001, # 避免分母为0
                activation_fn = None,
                param_initializers=None,
                param_regularizers=None,
                updates_collections=ops.GraphKeys.UPDATE_OPS,
                is_training=True,
                reuse=None,  # 支持共享变量
                variables_collections=None,
                outputs_collections=None,
                trainable=True,
                batch_weights=None,
                fused=False,
                data_format=DATA_FORMAT_NHWC,
                zero_debias_moving_mean=False,
                scope=None,   # 指定变量的作用域
                renorm=False,
                renorm_clipping=None,
                renorm_decay=0.99)


实例:为CIFAR图片分类模型添加BN 
 

import cifar10_input
import tensorflow as tf
import numpy as np
from tensorflow.contrib.layers.python.layers import batch_norm

batch_size = 128
print("begin")
images_train, labels_train = cifar10_input.inputs(eval_data = False, batch_size = batch_size)
images_test, labels_test = cifar10_input.inputs(eval_data = True, batch_size = batch_size)
print("begin data")
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)
  
def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')  
                        
def avg_pool_6x6(x):
  return tf.nn.avg_pool(x, ksize=[1, 6, 6, 1],
                        strides=[1, 6, 6, 1], padding='SAME')
# BN层                        
def batch_norm_layer(value,train = None, name = 'batch_norm'): 
  if train is not None:       
      return batch_norm(value, decay = 0.9,updates_collections=None, is_training = True)
  else:
      return batch_norm(value, decay = 0.9,updates_collections=None, is_training = False)
# tf Graph Input
x = tf.placeholder(tf.float32, [None, 24,24,3]) # cifar data image of shape 24*24*3
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 数字=> 10 classes
train = tf.placeholder(tf.float32)

W_conv1 = weight_variable([5, 5, 3, 64])
b_conv1 = bias_variable([64])

x_image = tf.reshape(x, [-1,24,24,3])

h_conv1 = tf.nn.relu(batch_norm_layer((conv2d(x_image, W_conv1) + b_conv1),train))
h_pool1 = max_pool_2x2(h_conv1)

W_conv2 = weight_variable([5, 5, 64, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(batch_norm_layer((conv2d(h_pool1, W_conv2) + b_conv2),train))
h_pool2 = max_pool_2x2(h_conv2)


W_conv3 = weight_variable([5, 5, 64, 10])
b_conv3 = bias_variable([10])
h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)

nt_hpool3=avg_pool_6x6(h_conv3)#10
nt_hpool3_flat = tf.reshape(nt_hpool3, [-1, 10])
y_conv=tf.nn.softmax(nt_hpool3_flat)
# 损失函数
cross_entropy = -tf.reduce_sum(y*tf.log(y_conv))
global_step = tf.Variable(0, trainable=False)
decaylearning_rate = tf.train.exponential_decay(0.04, global_step,1000, 0.9)
train_step = tf.train.AdamOptimizer(decaylearning_rate).minimize(cross_entropy,global_step=global_step)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
# 训练
sess = tf.Session()
sess.run(tf.global_variables_initializer())
tf.train.start_queue_runners(sess=sess)
for i in range(20000):
  image_batch, label_batch = sess.run([images_train, labels_train])
  label_b = np.eye(10,dtype=float)[label_batch] #one hot
  
  train_step.run(feed_dict={x:image_batch, y: label_b,train:1},session=sess)
  
  if i%200 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:image_batch, y: label_b},session=sess)
    print( "step %d, training accuracy %g"%(i, train_accuracy))

image_batch, label_batch = sess.run([images_test, labels_test])
label_b = np.eye(10,dtype=float)[label_batch]#one hot
print ("finished! test accuracy %g"%accuracy.eval(feed_dict={
     x:image_batch, y: label_b},session=sess))

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值