本文主要參考博客:博客連接
前言基礎:
驗證本地的tf.contrib.slim模塊是否有效:
1 python -c "import tensorflow.contrib.slim as slim;eval=slim.evaluation.evaluate_once"
下載models模塊:
下載連接。下載后解壓到你設定的文件夾,筆者解壓到“E:\TENSORFLOW\models”
找到並且打開文件夾"E:\TENSORFLOW\models\research",找到slim文件夾,shift+右鍵點擊slim文件夾,選擇“在此處打開Powershell窗口”
輸入命令:
1 python -c "from nets import cifarnet;mynet=cifarnet.cifarnet"
如圖,如果沒有報錯,說明一切正常。
slim文件夾目錄結構:
共包含5個文件夾,Datasets處理數據集相關代碼,Deloyment通過創建clone方式實現跨機器的分布訓練,可以在多CPU和GPU上實現運算的同步或者異步。
Nets放着各種網絡模型,Preprocessing用於各個網絡的圖片處理函數。Scripts運行網路的一些腳本。
1.簡介
slim是位於tf.contrib.slim位置,所以使用slim有兩種方法
1 import tensorflow.contrib.slim as slim 2 3 #或者 4 5 slim=tf.contrib.slim
slim是一個使構建,訓練,評估神經網絡變得簡單的庫。它可以消除原生tensorflow里面很多重復的模板性的代碼,讓代碼更緊湊,更具備可讀性。
另外slim提供了很多計算機視覺方面的著名模型(VGG, AlexNet等),我們不僅可以直接使用,甚至能以各種方式進行擴展。
slim子模塊介紹:
1 arg_scope: 2 除了基本的namescope,variabelscope外,又加了argscope,它是用來控制每一層的默認超參數的。 3 4 layers: 5 slim的核心和精髓,一些復雜層的定義 6 7 learning: 8 一些訓練規則 9 10 metrics: 11 評估模型的度量標准 12 13 nets: 14 非常重要,包含一些經典網絡,VGG等。 15 16 queues: 17 隊列 18 19 regularizers: 20 包含一些正則規則 21 22 variables: 23 slim管理變量的機制
2.slim定義模型
slim定義變量:
變量分為兩類:模型變量和局部變量。局部變量是不作為模型參數保存的,而模型變量會再save的時候保存下來。這個玩過tensorflow的人都會明白,諸如global_step之類的就是局部變量。slim中可以寫明變量存放的設備,正則和初始化規則。還有獲取變量的函數也需要注意一下,get_variables是返回所有的變量。
1 # Model Variables 2 weights = slim.model_variable('weights', 3 shape=[10, 10, 3 , 3], 4 initializer=tf.truncated_normal_initializer(stddev=0.1), 5 regularizer=slim.l2_regularizer(0.05), 6 device='/CPU:0') 7 model_variables = slim.get_model_variables() 8 9 # Regular variables 10 my_var = slim.variable('my_var', 11 shape=[20, 1], 12 initializer=tf.zeros_initializer()) 13 regular_variables_and_model_variables = slim.get_variables()
slim定義層:
1 input = ... 2 net = slim.conv2d(input, 128, [3, 3], scope='conv1_1')#分別對應輸入,輸出維度,卷積核,層的名字
更amazing...
如果像上面定義多個相同卷積層,比如:
1 net = ... 2 net = slim.conv2d(net, 256, [3, 3], scope='conv3_1') 3 net = slim.conv2d(net, 256, [3, 3], scope='conv3_2') 4 net = slim.conv2d(net, 256, [3, 3], scope='conv3_3') 5 net = slim.max_pool2d(net, [2, 2], scope='pool2')
我們可以通過使用slim.repeat()實現:
1 net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3') 2 net = slim.max_pool2d(net, [2, 2], scope='pool2')
而當卷積核不同時,可以使用slim.stack():
1 #原始重復定義 2 x = slim.fully_connected(x, 32, scope='fc/fc_1') 3 x = slim.fully_connected(x, 64, scope='fc/fc_2') 4 x = slim.fully_connected(x, 128, scope='fc/fc_3') 5 6 #slim.srack簡化: 7 slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')
在卷積操作中,也可以同時改變卷積核和輸出個數:
1 # 普通方法: 2 x = slim.conv2d(x, 32, [3, 3], scope='core/core_1') 3 x = slim.conv2d(x, 32, [1, 1], scope='core/core_2') 4 x = slim.conv2d(x, 64, [3, 3], scope='core/core_3') 5 x = slim.conv2d(x, 64, [1, 1], scope='core/core_4') 6 7 # slim.stack()簡化: 8 slim.stack(x, slim.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')
slim管理大量參數:
slim.arg_scope()可以實現大量相同參數:
1 #原始復雜大量相同參數: 2 net = slim.conv2d(inputs, 64, [11, 11], 4, padding='SAME', 3 weights_initializer=tf.truncated_normal_initializer(stddev=0.01), 4 weights_regularizer=slim.l2_regularizer(0.0005), scope='conv1') 5 net = slim.conv2d(net, 128, [11, 11], padding='VALID', 6 weights_initializer=tf.truncated_normal_initializer(stddev=0.01), 7 weights_regularizer=slim.l2_regularizer(0.0005), scope='conv2') 8 net = slim.conv2d(net, 256, [11, 11], padding='SAME', 9 weights_initializer=tf.truncated_normal_initializer(stddev=0.01), 10 weights_regularizer=slim.l2_regularizer(0.0005), scope='conv3') 11 12 #使用slim.srg_scope()簡化: 13 with slim.arg_scope([slim.conv2d], padding='SAME', 14 weights_initializer=tf.truncated_normal_initializer(stddev=0.01) 15 weights_regularizer=slim.l2_regularizer(0.0005)): 16 net = slim.conv2d(inputs, 64, [11, 11], scope='conv1') 17 net = slim.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2') 18 net = slim.conv2d(net, 256, [11, 11], scope='conv3')
如果是多個層:
with slim.arg_scope([slim.conv2d, slim.fully_connected], activation_fn=tf.nn.relu, weights_initializer=tf.truncated_normal_initializer(stddev=0.01), weights_regularizer=slim.l2_regularizer(0.0005)): with slim.arg_scope([slim.conv2d], stride=1, padding='SAME'): net = slim.conv2d(inputs, 64, [11, 11], 4, padding='VALID', scope='conv1') net = slim.conv2d(net, 256, [5, 5], weights_initializer=tf.truncated_normal_initializer(stddev=0.03), scope='conv2') net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc')