1. 程式人生 > >tensorflow學習(一)——有關tensorflow不同層的使用(tf.nn 和tf.layers以及tf.contrib.layers)的簡單區別

tensorflow學習(一)——有關tensorflow不同層的使用(tf.nn 和tf.layers以及tf.contrib.layers)的簡單區別

小trick: 對於使用tf.layers建立的神經網路,如果想要對loss函式進行正則話,可以採用如下方式[1]:

但是該方法不適用於程式設計者自己定義不同層的正則化。

 l2 = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables()])

注意:本文中tensorflow ver=1.8

0. 寫作目的

好記性不如爛筆頭。及時更新。

1. 不同層的介紹

tf.nn是最基礎的層,如tf.nn.conv2d, tf.nn.max_pool等,需要程式設計者自己定義權重。下面給出自己定義的Conv2d函式:

(注意: 這裡統一使用tf.variable_scope()來管理範圍)


def myConv2d(input_tensor, conv_size, stride_size ,
output_channel, name, regu=None, padding='SAME', act=tf.nn.relu, reuse=False):
    with tf.variable_scope(name, reuse=reuse):
        input_channel = input_tensor.get_shape()[-1].value
        weights = tf.get_variable(name='weights', shape=[conv_size, conv_size, input_channel, output_channel],
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.1))
        biases = tf.get_variable(name='biases', shape=[output_channel], dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.001))
        conv = tf.nn.conv2d(input=input_tensor, filter=weights, strides=[1, stride_size, stride_size, 1], padding=padding,
                            use_cudnn_on_gpu=True, name=name)
        if regu != None and reuse != True:  
            tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regu)(weights))
        print_Layer(conv)
        if act == None:
            return tf.nn.bias_add(value=conv, bias=biases)
        conv_relu = act(tf.nn.bias_add(value=conv, bias=biases))
        print_Layer(conv_relu)
        return conv_relu

tf.layers是基於tf.nn封裝的高階函式[2],如果自己定義Conv2d,只需要一個函式即可,如下

tf.layers.conv2d(
    inputs,
    filters,
    kernel_size,
    strides=(1, 1),
    padding='valid',
    data_format='channels_last',
    dilation_rate=(1, 1),
    activation=None,
    use_bias=True,
    kernel_initializer=None,
    bias_initializer=tf.zeros_initializer(),
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None,
    trainable=True,
    name=None,
    reuse=None
)

tf.contrib.layers.conv2d也是封裝完好的高階函式[3],具體為:

tf.contrib.layers.conv2d(
    inputs,
    num_outputs,
    kernel_size,
    stride=1,
    padding='SAME',
    data_format=None,
    rate=1,
    activation_fn=tf.nn.relu,
    normalizer_fn=None,
    normalizer_params=None,
    weights_initializer=initializers.xavier_initializer(),
    weights_regularizer=None,
    biases_initializer=tf.zeros_initializer(),
    biases_regularizer=None,
    reuse=None,
    variables_collections=None,
    outputs_collections=None,
    trainable=True,
    scope=None
)

2. tensorflow中相同功能不同函式的使用對比

2.1 對於初學者

 1) 如果只是想快速瞭解一下大概,不建議使用tf.nn.conv2d類似的函式,可以使用tf.layers和tf.contrib.layers高階函式

 2) 當有了一定的基礎後,如果想在該領域進行深入學習,建議使用tf.nn.conv2d搭建神經網路,此時會幫助你深入理解網路中引數的具體功能與作用,而且對於loss函式需要進行正則化的時候很便於修改。

且能很清晰地知道修改的地方。而如果採用tf.layers和tf.contrib.layers高階函式,由於函式內部有正則項,此時,不利於深入理解。而且如果編寫者想自定義loss,此時比較困難,如如果讀者想共享引數時,此時計算loss函式中的正則項時,應該只計算一次,如果採用高階函式可能不清楚到底如何計算的。

[Reference]