tensorflow学习笔记10——终于到了构建计算图

1、设置一些常量

global_step = tf.Variable(0, trainable=False)
boundaries = [10000, 15000, 20000, 25000]
values = [0.1, 0.05, 0.01, 0.005, 0.001]
learning_rate = tf.train.piecewise_constant(global_step, boundaries, values)
weight_decay = 2e-4
filters = 16  # the first resnet block filter number
n = 5  # the basic resnet block number, total network layers are 6n+2
ver = 2  # the resnet block version

2、调用resnet的inference函数

# Get the inference logits by the model
result = resnet.inference(distorted_images, True, filters, n, ver)
def inference(images, training, filters, n, ver):
    """Construct the resnet model
    Args:
      images: [batch*channel*height*width]
     training: boolean
     filters: integer, the filters of the first resnet stage, the next stage will have filters*2
     n: integer, how many resnet blocks in each stage, the total layers number is 6n+2
     ver: integer, can be 1 or 2, for resnet v1 or v2
    Returns:
      Tensor, model inference output
    """
    # Layer1 is a 3*3 conv layer, input channels are 3, output channels are 16
    inputs = tf.layers.conv2d(images, filters=16, kernel_size=(3, 3), strides=(1, 1),
                              name='conv1', reuse=tf.AUTO_REUSE, padding='same', data_format='channels_last')
                              #name='conv1', reuse=tf.AUTO_REUSE, padding='same', data_format='channels_first')

    # no need to batch normal and activate for version 2 resnet.
    if ver == 1:
        inputs = tf.layers.batch_normalization(inputs, axis=-1, name='bn_conv1',
                                               training=training, reuse=tf.AUTO_REUSE)  #by fm, 原来axis=1
        inputs = tf.nn.relu(inputs)
    for stage in range(3):
        stage_filter = filters * (2 ** stage)
        for i in range(n):
            stride = 1
            projection = False
            if i == 0 and stage > 0:
                stride = 2
                projection = True

            if ver == 1:
                inputs = _resnet_block_v1(inputs, stage_filter, stride, projection,
                                          stage, blockname=str(i), TRAINING=training)
            else:

                inputs = _resnet_block_v2(inputs, stage_filter, stride, projection,
                                          stage, blockname=str(i), TRAINING=training)


    # only need for version 2 resnet.
    if ver == 2:
        inputs = tf.layers.batch_normalization(inputs, axis=-1, name='pre_activation_final_norm',
                                               training=training, reuse=tf.AUTO_REUSE)   #by fm, 原来axis=1

        inputs = tf.nn.relu(inputs)


    #by fm, 终于找到重点了,这里,应该对[1,2]做均值
    #axes = [2, 3]
    axes = [1, 2]
    inputs = tf.reduce_mean(inputs, axes, keep_dims=True)
    inputs = tf.identity(inputs, 'final_reduce_mean')
    inputs = tf.reshape(inputs, [-1, filters * (2 ** 2)])

    inputs = tf.layers.dense(inputs=inputs, units=10, name='dense1', reuse=tf.AUTO_REUSE)

    return inputs

下面分解看,认真学习一下:
(1)tf.layers.conv2d()

inputs = tf.layers.conv2d(images, filters=16, kernel_size=(3, 3), strides=(1, 1),
                          name='conv1', reuse=tf.AUTO_REUSE, padding='same', data_format='channels_last')

filters=16,如tensorflow官网解释: filters: Integer, the dimensionality of the output space (i.e. the number of filters in the convolution). 定义此conv.层output的厚度(也就是说此conv层里面有几个filter)。本例中,output是16个通道。
reuse:Boolean类型,表示是否可以重复使用具有相同名字的前一层的权重。
padding:有SAME和VALID,VALID模式中会直接舍弃多余的像素点;SAME模式先对原图像进行填充,再做卷积,填充值须根据卷积核大小及滑动步长决定。
(2)tf.layers.batch_normalization()加速神经网络训练过程的算法.

if ver == 1:
    inputs = tf.layers.batch_normalization(inputs, axis=-1, name='bn_conv1',
                                           training=training, reuse=tf.AUTO_REUSE)  #by fm, 原来axis=1
    inputs = tf.nn.relu(inputs)

为什么需要batch_normalization?如果神经网络的层数很浅的话,其实这个问题不大,因为采取随机的mini-batch训练方法,mini-batch之间的样本分布差别不会太大。但是对于深度神经网络而言(比如微软提出152层的residual network),由于其参数是逐层启发性的结构,因此,internal covariate shift的问题就不应该忽视了。在深度神经网络中,由于第一层参数的改变,导致了传递给第二层的输入的分布也会发生改变,也就是说在更新参数的过程中,无形中发生了internal covariate shift。【所以我们要用可视化工具看一下每一层的输出数据分布】因此,这样网络就很难较好的范化,训练起来也就非常缓慢了。
这里的axis值,与传进去的数据格式有关,一般NHWC用默认的-1,NCHW用1。
【这里我还没搞明白,为什么resnet不用执行batch_normalization???留待后面解决。】

(3)tf.nn.relu()
tf.nn.relu() 这个函数的作用是计算激活函数 relu,即 max(features, 0)。将大于0的保持不变,小于0的数置为0。
标准的sigmoid输出不具备稀疏性,需要用一些惩罚因子来训练出一大堆接近0的冗余数据来,从而产生稀疏数据,例如L1、L1/L2或Student-t作惩罚因子。因此需要进行无监督的预训练。
而ReLU是线性修正,公式为:g(x) = max(0, x),是purelin的折线版。它的作用是如果计算出的值小于0,就让它等于0,否则保持原来的值不变。这是一种简单粗暴地强制某些数据为0的方法,然而经实践证明,训练后的网络完全具备适度的稀疏性【为什么需要适度的稀疏性?】。而且训练后的可视化效果和传统方式预训练出的效果很相似,这也说明了ReLU具备引导适度稀疏的能力。

(4)tf.reduce_mean()tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。如果设置保持原来的张量的维度,keep_dims=True .
tf.identity()这个函数有很多作用,在这里是为没有名称参数的op分配name。

(5)inputs = tf.reshape(inputs, [-1, filters * (2 ** 2)]),把inputs的最后一个维度改成64【还是要重新追踪shape的变化,看看有没有能打印出来的,可视化】
参考https://blog.csdn.net/qq_23981335/article/details/81361748

(6) inputs = tf.layers.dense(inputs=inputs, units=10, name=‘dense1’, reuse=tf.AUTO_REUSE)全连接层 相当于添加一个层,把数据分成10类。
通常在CNN的尾部进行重新拟合,减少特征信息的损失。
参考https://blog.csdn.net/m0_37407756/article/details/80904580
从卷积网络谈起,卷积网络在形式上有一点点像咱们正在召开的“人民代表大会制度”。卷积核的个数相当于候选人,图像中不同的特征会激活不同的“候选人”(卷积核)。池化层(仅指最大池化)起着类似于“合票”的作用,不同特征在对不同的“候选人”有着各自的喜好。全连接相当于是“代表普选”。所有被各个区域选出的代表,对最终结果进行“投票”,全连接保证了receiptive field 是整个图像,既图像中各个部分(所谓所有代表),都有对最终结果影响的权利。

3、

# Get the inference logits by the model
result = resnet.inference(distorted_images, True, filters, n, ver)

# Calculate the cross entropy loss
cross_entropy = tf.losses.sparse_softmax_cross_entropy(labels=record_labels, logits=result)
cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')

# Add the l2 weights to the loss
# Add weight decay to the loss.
l2_loss = weight_decay * tf.add_n(
    # loss is computed using fp32 for numerical stability.
    [tf.nn.l2_loss(tf.cast(v, tf.float32)) for v in tf.compat.v1.trainable_variables()])

tf.compat.v1.summary.scalar('l2_loss', l2_loss)
loss = cross_entropy_mean + l2_loss

# Define the optimizer
optimizer = tf.compat.v1.train.MomentumOptimizer(learning_rate, momentum=0.9)

# Relate to the batch normalization
update_ops = tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.UPDATE_OPS)

with tf.control_dependencies(update_ops):
    opt_op = optimizer.minimize(loss, global_step)

(1)计算损失函数
l2_loss,【这是啥?不加效果怎么样?】
(2)定义优化器,例中是实现动量算法的优化器。参考https://www.jianshu.com/p/200f3c4336a3

optimizer = tf.compat.v1.train.MomentumOptimizer(learning_rate, momentum=0.9)
【可以考虑把momentum设置成其他值试试,比如Adam
#optimizer = tf.train.GradientDescentOptimizer(learning_rate) #试试用其他优化函数效果如何 】
(3) 关于tf.GraphKeys.UPDATE_OPS,这是一个tensorflow的计算图中内置的一个集合,其中会保存一些需要在训练操作之前完成的操作,并配合tf.control_dependencies函数使用。
get_collection()用来获取一个名称是‘key’的集合中的所有元素,返回的是一个列表,列表的顺序是按照变量放入集合中的先后; scope参数可选,表示的是名称空间(名称域),如果指定,就返回名称域中所有放入‘key’的变量的列表,不指定则返回所有变量。
tf.get_collection()指定上下文中构建的所有操作的控制依赖关系的上下文管理器。
optimizer.minimize()

# Relate to the batch normalization
update_ops = tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.UPDATE_OPS)

with tf.control_dependencies(update_ops):
    opt_op = optimizer.minimize(loss, global_step)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值