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

    xiaoxiao2022-07-12  132

    把卷积核裁开,从而减少计算量,是等价计算。比如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 0 == 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"
    转载请注明原文地址: https://yun.8miu.com/read-53685.html
    最新回复(0)