1. 程式人生 > >『TensorFlow』slim高級模塊

『TensorFlow』slim高級模塊

學習 正則 nbsp pool 數字 ini 嵌套 graph 正則化

『TensorFlow』徒手裝高達_主機體框架開光版_Google自家AlexNet集成&slim高級模塊學習

輔助函數

slim.arg_scope()

slim.arg_scope可以定義一些函數的默認參數值,在scope內,我們重復用到這些函數時可以不用把所有參數都寫一遍,註意它沒有tf.variable_scope()劃分圖結構的功能,

with slim.arg_scope([slim.conv2d, slim.fully_connected], 
                    trainable=True,
                    activation_fn=tf.nn.relu, 
                    weights_initializer=tf.truncated_normal_initializer(stddev=0.01), 
                    weights_regularizer=slim.l2_regularizer(0.0001)):
    with slim.arg_scope([slim.conv2d], 
                        kernel_size=[3, 3], 
                        padding=‘SAME‘,
                        normalizer_fn=slim.batch_norm):
        net = slim.conv2d(net, 64, scope=‘conv1‘))
        net = slim.conv2d(net, 128, scope=‘conv2‘))
        net = slim.conv2d(net, 256, [5, 5], scope=‘conv3‘))

slim.arg_scope的用法基本都體現在上面了。一個slim.arg_scope內可以用list來同時定義多個函數的默認參數(前提是這些函數都有這些參數),另外,slim.arg_scope也允許相互嵌套。在其中調用的函數,可以不用重復寫一些參數(例如kernel_size=[3, 3]),但也允許覆蓋(例如最後一行,卷積核大小為[5,5])。
另外,還可以把這麽多scope封裝成函數:

def new_arg_sc():
    with slim.arg_scope([slim.conv2d, slim.fully_connected], 
                        trainable=True,
                        activation_fn=tf.nn.relu, 
                        weights_initializer=tf.truncated_normal_initializer(stddev=0.01), 
                        weights_regularizer=slim.l2_regularizer(0.0001)):
        with slim.arg_scope([slim.conv2d], 
                            kernel_size=[3, 3], 
                            padding=‘SAME‘,
                            normalizer_fn=slim.batch_norm) as sc:
            return sc

def main():
    ......
    with slim.arg_scope(new_arg_sc()):
        ......

slim.utils.collect_named_outputs()

將變量取個別名,並收集到collection中

net = slim.utils.collect_named_outputs(outputs_collections,sc.name,net)

參數意義如下,

return:這個方法會返回本次添加的tensor對象,
參數二:意義是為tensor添加一個別名,並收集進collections中
查看源碼可見實現如下

if collections:
append_tensor_alias(outputs,alias)
ops.add_to_collections(collections,outputs)

return outputs

據說本方法位置已經被轉移到這裏了,
from tensorflow.contrib.layers.python.layers import utils
utils.collect_named_outputs()

slim.utils.convert_collection_to_dict()

#集合轉換為字典,{節點名:輸出張量值}
end_points = slim.utils.convert_collection_to_dict(end_points_collection)
 
# 收集 & 釋放 集合值
tf.add_to_collection("loss",mse_loss)
tf.add_n(tf.get_collection("loss"))

層函數

batch_norm處理

slim.batch_norm()函數,以及slim的各個層函數的normalizer_fn=slim.batch_norm調用都會用到,

其參數很多,需要以字典的形式傳入,

batch_norm_params = {  # 定義batch normalization(標準化)的參數字典
        ‘is_training‘: is_training,
        # 是否是在訓練模式,如果是在訓練階段,將會使用指數衰減函數(衰減系數為指定的decay),
        # 對moving_mean和moving_variance進行統計特性的動量更新,也就是進行使用指數衰減函數對均值和方
        # 差進行更新,而如果是在測試階段,均值和方差就是固定不變的,是在訓練階段就求好的,在訓練階段,
        # 每個批的均值和方差的更新是加上了一個指數衰減函數,而最後求得的整個訓練樣本的均值和方差就是所
        # 有批的均值的均值,和所有批的方差的無偏估計

        ‘zero_debias_moving_mean‘: True,
        # 如果為True,將會創建一個新的變量對 ‘moving_mean/biased‘ and ‘moving_mean/local_step‘,
        # 默認設置為False,將其設為True可以增加穩定性

        ‘decay‘: batch_norm_decay,             # Decay for the moving averages.
        # 該參數能夠衡量使用指數衰減函數更新均值方差時,更新的速度,取值通常在0.999-0.99-0.9之間,值
        # 越小,代表更新速度越快,而值太大的話,有可能會導致均值方差更新太慢,而最後變成一個常量1,而
        # 這個值會導致模型性能較低很多.另外,如果出現過擬合時,也可以考慮增加均值和方差的更新速度,也
        # 就是減小decay

        ‘epsilon‘: batch_norm_epsilon,         # 就是在歸一化時,除以方差時,防止方差為0而加上的一個數
        ‘scale‘: batch_norm_scale,
        ‘updates_collections‘: tf.GraphKeys.UPDATE_OPS,     
        # force in-place updates of mean and variance estimates
        # 該參數有一個默認值,ops.GraphKeys.UPDATE_OPS,當取默認值時,slim會在當前批訓練完成後再更新均
        # 值和方差,這樣會存在一個問題,就是當前批數據使用的均值和方差總是慢一拍,最後導致訓練出來的模
        # 型性能較差。所以,一般需要將該值設為None,這樣slim進行批處理時,會對均值和方差進行即時更新,
        # 批處理使用的就是最新的均值和方差。
        #
        # 另外,不論是即使更新還是一步訓練後再對所有均值方差一起更新,對測試數據是沒有影響的,即測試數
        # 據使用的都是保存的模型中的均值方差數據,但是如果你在訓練中需要測試,而忘了將is_training這個值
        # 改成false,那麽這批測試數據將會綜合當前批數據的均值方差和訓練數據的均值方差。而這樣做應該是不
        # 正確的。
    }

在以其他層參數的形式調用時如下,

normalizer_fn=slim.batch_norm,                               # 標準化器設置為BN
normalizer_params=batch_norm_params

註意一但使用batch_norm層,在訓練節點定義時需要添加一些語句,slim.batch_norm裏有moving_mean和moving_variance兩個量,分別表示每個批次的均值和方差。在訓練時還好理解,但在測試時,moving_mean和moving_variance的含義變了,在訓練時,

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)  
    with tf.control_dependencies(update_ops):  
        train_step = tf.train.GradientDescentOptimizer(0.01).minimize(total_loss)  
# 註意並tf本體的batch_normal操作也需要這步操作
# 其中,tf.control_dependencies(update_ops)表示with段中的操作是在update_ops操作執行之後 再執行的

tf.contrib.slim.conv2d()

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

inputs 是指需要做卷積的輸入圖像
num_outputs 指定卷積核的個數(就是filter的個數)
kernel_size 用於指定卷積核的維度(卷積核的寬度,卷積核的高度)
stride 為卷積時在圖像每一維的步長
padding 為padding的方式選擇,VALID或者SAME
data_format 是用於指定輸入的input的格式
rate 這個參數不是太理解,而且tf.nn.conv2d中也沒有,對於使用atrous convolution的膨脹率(不是太懂這個atrous convolution)
activation_fn 用於激活函數的指定,默認的為ReLU函數
normalizer_fn 用於指定正則化函數
normalizer_params 用於指定正則化函數的參數
weights_initializer 用於指定權重的初始化程序
weights_regularizer 為權重可選的正則化程序
biases_initializer 用於指定biase的初始化程序
biases_regularizer biases可選的正則化程序
reuse 指定是否共享層或者和變量
variable_collections 指定所有變量的集合列表或者字典
outputs_collections 指定輸出被添加的集合
trainable 卷積層的參數是否可被訓練
scope 共享變量所指的variable_scope

slim.conv2d是基於tf.conv2d的進一步封裝,省去了很多參數,一般調用方法如下:

net = slim.conv2d(inputs, 256, [3, 3], stride=1, scope=‘conv1_1‘)

slim.max_pool2d

這個函數更簡單了,用法如下:

net = slim.max_pool2d(net, [2, 2], scope=‘pool1‘)

slim.fully_connected

slim.fully_connected(x, 128, scope=‘fc1‘)

前兩個參數分別為網絡輸入、輸出的神經元數量。

『TensorFlow』slim高級模塊