TensorFlow layers模塊用法

TensorFlow 中的 layers 模塊提供用於深度學習的更高層次封裝的 API,利用它咱們能夠輕鬆地構建模型,這一節咱們就來看下這個模塊的 API 的具體用法。python

概覽

layers 模塊的路徑寫法爲 tf.layers,這個模塊定義在 tensorflow/python/layers/layers.py,其官方文檔地址爲:https://www.tensorflow.org/api_docs/python/tf/layers,TensorFlow 版本爲 1.5。git

這裏面提供了多個類和方法以供使用,下面咱們分別予以介紹。github

方法

tf.layers 模塊提供的方法有:api

  • Input(…): 用於實例化一個輸入 Tensor,做爲神經網絡的輸入。網絡

  • average_pooling1d(…): 一維平均池化層app

  • average_pooling2d(…): 二維平均池化層ide

  • average_pooling3d(…): 三維平均池化層函數

  • batch_normalization(…): 批量標準化層學習

  • conv1d(…): 一維卷積層spa

  • conv2d(…): 二維卷積層

  • conv2d_transpose(…): 二維反捲積層

  • conv3d(…): 三維卷積層

  • conv3d_transpose(…): 三維反捲積層

  • dense(…): 全鏈接層

  • dropout(…): Dropout層

  • flatten(…): Flatten層,即把一個 Tensor 展平

  • max_pooling1d(…): 一維最大池化層

  • max_pooling2d(…): 二維最大池化層

  • max_pooling3d(…): 三維最大池化層

  • separable_conv2d(…): 二維深度可分離卷積層

Input

tf.layers.Input() 這個方法是用於輸入數據的方法,其實相似於 tf.placeholder,至關於一個佔位符的做用,固然也能夠經過傳入 tensor 參數來進行賦值。

Input(
   shape=None,
   batch_size=None,
   name=None,
   dtype=tf.float32,
   sparse=False,
   tensor=None
)

參數說明以下:

  • shape:可選,默認 None,是一個數字組成的元組或列表,可是這個 shape 比較特殊,它不包含 batch_size,好比傳入的 shape 爲 [32],那麼它會將 shape 轉化爲 [?, 32],這裏必定須要注意。

  • batch_size:可選,默認 None,表明輸入數據的 batch size,能夠是數字或者 None。

  • name:可選,默認 None,輸入層的名稱。

  • dtype:可選,默認 tf.float32,元素的類型。

  • sparse:可選,默認 False,指定是否以稀疏矩陣的形式來建立 placeholder。

  • tensor:可選,默認 None,若是指定,那麼建立的內容便再也不是一個 placeholder,會用此 Tensor 初始化。

返回值:
返回一個包含歷史 Meta Data 的 Tensor。

咱們用一個實例來感覺一下:

x = tf.layers.Input(shape=[32])
print(x)
y = tf.layers.dense(x, 16, activation=tf.nn.softmax)
print(y)

首先咱們用 Input() 方法初始化了一個 placeholder,這時咱們沒有傳入 tensor 參數,而後調用了 dense() 方法構建了一個全鏈接網絡,激活函數使用 softmax,而後將兩者輸出,結果以下:

Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)
Tensor("dense/Softmax:0", shape=(?, 16), dtype=float32)

這時咱們發現,shape 它給咱們作了轉化,原本是 [32],結果它給轉化成了 [?, 32],即第一維表明 batch_size,因此咱們須要注意,在調用此方法的時候不須要去關心 batch_size 這一維。

若是咱們在初始化的時候傳入一個已有 Tensor,例如:

data = tf.constant([1, 2, 3])
x = tf.layers.Input(tensor=data)
print(x)

結果以下:

Tensor("Const:0", shape=(3,), dtype=int32)

能夠看到它能夠自動計算出其 shape 和 dtype。

batch_normalization

此方法是批量標準化的方法,通過處理以後能夠加速訓練速度,其定義在 tensorflow/python/layers/normalization.py,論文能夠參考:http://arxiv.org/abs/1502.03167"Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift"。

batch_normalization(
   inputs,
   axis=-1,
   momentum=0.99,
   epsilon=0.001,
   center=True,
   scale=True,
   beta_initializer=tf.zeros_initializer(),
   gamma_initializer=tf.ones_initializer(),
   moving_mean_initializer=tf.zeros_initializer(),
   moving_variance_initializer=tf.ones_initializer(),
   beta_regularizer=None,
   gamma_regularizer=None,
   beta_constraint=None,
   gamma_constraint=None,
   training=False,
   trainable=True,
   name=None,
   reuse=None,
   renorm=False,
   renorm_clipping=None,
   renorm_momentum=0.99,
   fused=None,
   virtual_batch_size=None,
   adjustment=None
)

參數說明以下:

  • inputs:必需,即輸入數據。

  • axis:可選,默認 -1,即進行標註化操做時操做數據的哪一個維度。

  • momentum:可選,默認 0.99,即動態均值的動量。

  • epsilon:可選,默認 0.01,大於0的小浮點數,用於防止除0錯誤。

  • center:可選,默認 True,若設爲True,將會將 beta 做爲偏置加上去,不然忽略參數 beta

  • scale:可選,默認 True,若設爲True,則會乘以gamma,不然不使用gamma。當下一層是線性的時,能夠設False,由於scaling的操做將被下一層執行。

  • beta_initializer:可選,默認 zeros_initializer,即 beta 權重的初始方法。

  • gamma_initializer:可選,默認 ones_initializer,即 gamma 的初始化方法。

  • moving_mean_initializer:可選,默認 zeros_initializer,即動態均值的初始化方法。

  • moving_variance_initializer:可選,默認 ones_initializer,即動態方差的初始化方法。

  • beta_regularizer: 可選,默認None,beta 的正則化方法。

  • gamma_regularizer: 可選,默認None,gamma 的正則化方法。

  • beta_constraint: 可選,默認None,加在 beta 上的約束項。

  • gamma_constraint: 可選,默認None,加在 gamma 上的約束項。

  • training:可選,默認 False,返回結果是 training 模式。

  • trainable:可選,默認爲 True,布爾類型,若是爲 True,則將變量添加 GraphKeys.TRAINABLE_VARIABLES 中。

  • name:可選,默認 None,層名稱。

  • reuse:可選,默認 None,根據層名判斷是否重複利用。

  • renorm:可選,默認 False,是否要用 Batch Renormalization (https://arxiv.org/abs/1702.03275)

  • renorm_clipping:可選,默認 None,是否要用 rmax、rmin、dmax 來 scalar Tensor。

  • renorm_momentum,可選,默認 0.99,用來更新動態均值和標準差的 Momentum 值。

  • fused,可選,默認 None,是否使用一個更快的、融合的實現方法。

  • virtual_batch_size,可選,默認 None,是一個 int 數字,指定一個虛擬 batch size。

  • adjustment,可選,默認 None,對標準化後的結果進行適當調整的方法。

最後的一些參數說明不夠詳盡,更詳細的用法參考:https://www.tensorflow.org/api_docs/python/tf/layers/batch_normalization。

其用法很簡單,在輸入數據後面加一層 batch_normalization() 便可:

x = tf.layers.Input(shape=[32])
x = tf.layers.batch_normalization(x)
y = tf.layers.dense(x, 20)

dense

dense,即全鏈接網絡,layers 模塊提供了一個 dense() 方法來實現此操做,定義在 tensorflow/python/layers/core.py 中,下面咱們來講明一下它的用法。

dense(
   inputs,
   units,
   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
)

參數說明以下:

  • inputs:必需,即須要進行操做的輸入數據。

  • units:必須,即神經元的數量。

  • activation:可選,默認爲 None,若是爲 None 則是線性激活。

  • use_bias:可選,默認爲 True,是否使用偏置。

  • kernel_initializer:可選,默認爲 None,即權重的初始化方法,若是爲 None,則使用默認的 Xavier 初始化方法。

  • bias_initializer:可選,默認爲零值初始化,即偏置的初始化方法。

  • kernel_regularizer:可選,默認爲 None,施加在權重上的正則項。

  • bias_regularizer:可選,默認爲 None,施加在偏置上的正則項。

  • activity_regularizer:可選,默認爲 None,施加在輸出上的正則項。

  • kernel_constraint,可選,默認爲 None,施加在權重上的約束項。

  • bias_constraint,可選,默認爲 None,施加在偏置上的約束項。

  • trainable:可選,默認爲 True,布爾類型,若是爲 True,則將變量添加到 GraphKeys.TRAINABLE_VARIABLES 中。

  • name:可選,默認爲 None,卷積層的名稱。

  • reuse:可選,默認爲 None,布爾類型,若是爲 True,那麼若是 name 相同時,會重複利用。

返回值:
全鏈接網絡處理後的 Tensor。

下面咱們用一個實例來感覺一下它的用法:

x = tf.layers.Input(shape=[32])
print(x)
y1 = tf.layers.dense(x, 16, activation=tf.nn.relu)
print(y1)
y2 = tf.layers.dense(y1, 5, activation=tf.nn.sigmoid)
print(y2)

首先咱們用 Input 定義了 [?, 32] 的輸入數據,而後通過第一層全鏈接網絡,此時指定了神經元個數爲 16,激活函數爲 relu,接着輸出結果通過第二層全鏈接網絡,此時指定了神經元個數爲 5,激活函數爲 sigmoid,最後輸出,結果以下:

Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)
Tensor("dense/Relu:0", shape=(?, 16), dtype=float32)
Tensor("dense_2/Sigmoid:0", shape=(?, 5), dtype=float32)

能夠看到輸出結果的最後一維度就等於神經元的個數,這是很是容易理解的。

convolution

convolution,即卷積,這裏提供了多個卷積方法,如 conv1d()、conv2d()、conv3d(),分別表明一維、二維、三維卷積,另外還有 conv2d_transpose()、conv3d_transpose(),分別表明二維和三維反捲積,還有 separable_conv2d() 方法表明二維深度可分離卷積。它們定義在 tensorflow/python/layers/convolutional.py 中,其用法都是相似的,在這裏以 conv2d() 方法爲例進行說明。

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
)

參數說明以下:

  • inputs:必需,即須要進行操做的輸入數據。

  • filters:必需,是一個數字,表明了輸出通道的個數,即 output_channels。

  • kernel_size:必需,卷積核大小,必須是一個數字(高和寬都是此數字)或者長度爲 2 的列表(分別表明高、寬)。

  • strides:可選,默認爲 (1, 1),卷積步長,必須是一個數字(高和寬都是此數字)或者長度爲 2 的列表(分別表明高、寬)。

  • padding:可選,默認爲 valid,padding 的模式,有 valid 和 same 兩種,大小寫不區分。

  • data_format:可選,默認 channels_last,分爲 channels_last 和 channels_first 兩種模式,表明了輸入數據的維度類型,若是是 channels_last,那麼輸入數據的 shape 爲 (batch, height, width, channels),若是是 channels_first,那麼輸入數據的 shape 爲 (batch, channels, height, width)。

  • dilation_rate:可選,默認爲 (1, 1),卷積的擴張率,如當擴張率爲 2 時,卷積核內部就會有邊距,3x3 的卷積核就會變成 5x5。

  • activation:可選,默認爲 None,若是爲 None 則是線性激活。

  • use_bias:可選,默認爲 True,是否使用偏置。

  • kernel_initializer:可選,默認爲 None,即權重的初始化方法,若是爲 None,則使用默認的 Xavier 初始化方法。

  • bias_initializer:可選,默認爲零值初始化,即偏置的初始化方法。

  • kernel_regularizer:可選,默認爲 None,施加在權重上的正則項。

  • bias_regularizer:可選,默認爲 None,施加在偏置上的正則項。

  • activity_regularizer:可選,默認爲 None,施加在輸出上的正則項。

  • kernel_constraint,可選,默認爲 None,施加在權重上的約束項。

  • bias_constraint,可選,默認爲 None,施加在偏置上的約束項。

  • trainable:可選,默認爲 True,布爾類型,若是爲 True,則將變量添加到 GraphKeys.TRAINABLE_VARIABLES 中。

  • name:可選,默認爲 None,卷積層的名稱。

  • reuse:可選,默認爲 None,布爾類型,若是爲 True,那麼若是 name 相同時,會重複利用。

返回值:
卷積後的 Tensor。

下面咱們用實例感覺一下它的用法:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=2, padding='same')
print(y)

這裏咱們首先聲明瞭一個 [?, 20, 20, 3] 的輸入 x,而後將其傳給 conv2d() 方法,filters 設定爲 6,即輸出通道爲 6,kernel_size 爲 2,即卷積核大小爲 2 x 2,padding 方式設置爲 same,那麼輸出結果的寬高和原來必定是相同的,可是輸出通道就變成了 6,結果以下:

Tensor("conv2d/BiasAdd:0", shape=(?, 20, 20, 6), dtype=float32)

但若是咱們將 padding 方式不傳入,使用默認的 valid 模式,代碼改寫以下:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=2)
print(y)

結果以下:

Tensor("conv2d/BiasAdd:0", shape=(?, 19, 19, 6), dtype=float32)

結果就變成了 [?, 19, 19, 6],這是由於步長默認爲 1,卷積核大小爲 2 x 2,因此獲得的結果的高寬即爲 (20 - (2 - 1)) x (20 - (2 - 1)) = 19 x 19。

固然卷積核咱們也能夠變換大小,傳入一個列表形式:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=[2, 3])
print(y)

這時咱們的卷積核大小變成了 2 x 3,即高爲 2,寬爲 3,結果就變成了 [?, 19, 18, 6],這是由於步長默認爲 1,卷積核大小爲 2 x 2,因此獲得的結果的高寬即爲 (20 - (2 - 1)) x (20 - (3 - 1)) = 19 x 18。

若是咱們將步長也設置一下,也傳入列表形式:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=[2, 3], strides=[2, 2])
print(y)

這時卷積核大小變成了 2 x 3,步長變成了 2 x 2,因此結果的高寬爲 ceil(20 - (2- 1)) / 2 x ceil(20 - (3- 1)) / 2 = 10 x 9,獲得的結果即爲 [?, 10, 9, 6]。

運行結果以下:

Tensor("conv2d_4/BiasAdd:0", shape=(?, 10, 9, 6), dtype=float32)

另外咱們還能夠傳入激活函數,或者禁用 bias 等操做,實例以下:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=2, activation=tf.nn.relu, use_bias=False)
print(y)

這樣咱們就將激活函數改爲了 relu,同時禁用了 bias,運行結果以下:

Tensor("conv2d_5/Relu:0", shape=(?, 19, 19, 6), dtype=float32)

另外還有反捲積操做,反捲積顧名思義即卷積的反向操做,即輸入卷積的結果,獲得卷積前的結果,其參數用法是徹底同樣的,例如:

x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d_transpose(x, filters=6, kernel_size=2, strides=2)
print(y)

例如此處輸入的圖像高寬爲 20 x 20,通過卷積核爲 2,步長爲 2 的反捲積處理,獲得的結果高寬就變爲了 40 x 40,結果以下:

Tensor("conv2d_transpose/BiasAdd:0", shape=(?, 40, 40, 6), dtype=float32)

pooling

pooling,即池化,layers 模塊提供了多個池化方法,這幾個池化方法都是相似的,包括 max_pooling1d()、max_pooling2d()、max_pooling3d()、average_pooling1d()、average_pooling2d()、average_pooling3d(),分別表明一維二維三維最大和平均池化方法,它們都定義在 tensorflow/python/layers/pooling.py 中,這裏以 max_pooling2d() 方法爲例進行介紹。

max_pooling2d(
   inputs,
   pool_size,
   strides,
   padding='valid',
   data_format='channels_last',
   name=None
)

參數說明以下:

  • inputs: 必需,即須要池化的輸入對象,必須是 4 維的。

  • pool_size:必需,池化窗口大小,必須是一個數字(高和寬都是此數字)或者長度爲 2 的列表(分別表明高、寬)。

  • strides:必需,池化步長,必須是一個數字(高和寬都是此數字)或者長度爲 2 的列表(分別表明高、寬)。

  • padding:可選,默認 valid,padding 的方法,valid 或者 same,大小寫不區分。

  • data_format:可選,默認 channels_last,分爲 channels_last 和 channels_first 兩種模式,表明了輸入數據的維度類型,若是是 channels_last,那麼輸入數據的 shape 爲 (batch, height, width, channels),若是是 channels_first,那麼輸入數據的 shape 爲 (batch, channels, height, width)。

  • name:可選,默認 None,池化層的名稱。

返回值:
通過池化處理後的 Tensor。

下面咱們用一個實例來感覺一下:

x = tf.layers.Input(shape=[20, 20, 3])
print(x)
y = tf.layers.conv2d(x, filters=6, kernel_size=3, padding='same')
print(y)
p = tf.layers.max_pooling2d(y, pool_size=2, strides=2)
print(p)

在這裏咱們首先指定了輸入 x,shape 爲 [20, 20, 3],而後對其進行了卷積計算,而後池化,最後獲得池化後的結果。結果以下:

Tensor("input_layer_1:0", shape=(?, 20, 20, 3), dtype=float32)
Tensor("conv2d/BiasAdd:0", shape=(?, 20, 20, 6), dtype=float32)
Tensor("max_pooling2d/MaxPool:0", shape=(?, 10, 10, 6), dtype=float32)

能夠看到這裏池化窗口用的是 2,步長也是 2,因此本來卷積後 shape 爲 [?, 20, 20, 6] 的結果就變成了 [?, 10, 10, 6]。

dropout

dropout 是指在深度學習網絡的訓練過程當中,對於神經網絡單元,按照必定的機率將其暫時從網絡中丟棄,能夠用來防止過擬合,layers 模塊中提供了 dropout() 方法來實現這一操做,定義在 tensorflow/python/layers/core.py。下面咱們來講明一下它的用法。

dropout(
   inputs,
   rate=0.5,
   noise_shape=None,
   seed=None,
   training=False,
   name=None
)

參數說明以下:

  • inputs:必須,即輸入數據。

  • rate:可選,默認爲 0.5,即 dropout rate,如設置爲 0.1,則意味着會丟棄 10% 的神經元。

  • noise_shape:可選,默認爲 None,int32 類型的一維 Tensor,它表明了 dropout mask 的 shape,dropout mask 會與 inputs 相乘對 inputs 作轉換,例如 inputs 的 shape 爲 (batch_size, timesteps, features),但咱們想要 droput mask 在全部 timesteps 都是相同的,咱們能夠設置 noise_shape=[batch_size, 1, features]。

  • seed:可選,默認爲 None,即產生隨機熟的種子值。

  • training:可選,默認爲 False,布爾類型,即表明了是否標誌爲 training 模式。

  • name:可選,默認爲 None,dropout 層的名稱。

返回:
通過 dropout 層以後的 Tensor。

咱們用一個實例來感覺一下:

x = tf.layers.Input(shape=[32])
print(x)
y = tf.layers.dense(x, 16, activation=tf.nn.softmax)
print(y)
d = tf.layers.dropout(y, rate=0.2)
print(d)

運行結果:

Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)
Tensor("dense/Softmax:0", shape=(?, 16), dtype=float32)
Tensor("dropout/Identity:0", shape=(?, 16), dtype=float32)

在這裏咱們使用 dropout() 方法實現了 droput 操做,並制定 dropout rate 爲 0.2,最後輸出結果的 shape 和原來是一致的。

flatten

flatten() 方法能夠對 Tensor 進行展平操做,定義在 tensorflow/python/layers/core.py。

flatten(
   inputs,
   name=None
)

參數說明以下:

  • inputs:必需,即輸入數據。

  • name:可選,默認爲 None,即該層的名稱。

返回結果:
展平後的 Tensor。

下面咱們用一個實例來感覺一下:

x = tf.layers.Input(shape=[5, 6])
print(x)
y = tf.layers.flatten(x)
print(y)

運行結果:

Tensor("input_layer_1:0", shape=(?, 5, 6), dtype=float32)
Tensor("flatten/Reshape:0", shape=(?, 30), dtype=float32)

這裏輸入數據的 shape 爲 [?, 5, 6],通過 flatten 層以後,就會變成 [?, 30],即將除了第一維的數據維度相乘,對原 Tensor 進行展平。

假如第一維是一個已知的數的話,它依然仍是一樣的處理,示例以下:

x = tf.placeholder(shape=[5, 6, 2], dtype=tf.float32)
print(x)
y = tf.layers.flatten(x)
print(y)

結果以下:

Tensor("Placeholder:0", shape=(5, 6, 2), dtype=float32)
Tensor("flatten_2/Reshape:0", shape=(5, 12), dtype=float32)

除了如上的方法,其實咱們還能夠直接使用類來進行操做,實際上看方法的實現就是實例化了其對應的類,下面咱們首先說明一下有哪些類可使用:

  • class AveragePooling1D: 一維平均池化層類

  • class AveragePooling2D: 二維平均池化層類

  • class AveragePooling3D: 三維平均池化層類

  • class BatchNormalization: 批量標準化層類

  • class Conv1D: 一維卷積層類

  • class Conv2D: 二維卷積層類

  • class Conv2DTranspose: 二維反捲積層類

  • class Conv3D: 三維卷積層類

  • class Conv3DTranspose: 三維反捲積層類

  • class Dense: 全鏈接層類

  • class Dropout: Dropout 層類

  • class Flatten: Flatten 層類

  • class InputSpec: Input 層類

  • class Layer: 基類、父類

  • class MaxPooling1D: 一維最大池化層類

  • class MaxPooling2D: 二維最大池化層類

  • class MaxPooling3D: 三維最大池化層類

  • class SeparableConv2D: 二維深度可分離卷積層類

其實類這些類都和上文介紹的方法是一一對應的,關於它的用法咱們能夠在方法的源碼實現裏面找到,下面咱們以 Dense 類的用法爲例來講明一下這些類的具體調用方法:

x = tf.layers.Input(shape=[32])
dense = tf.layers.Dense(16, activation=tf.nn.relu)
y = dense.apply(x)
print(y)

這裏咱們初始化了一個 Dense 類,它只接受一個必須參數,那就是 units,相比 dense() 方法來講它沒有了 inputs,所以這個實例化的類和 inputs 是無關的,這樣就至關於建立了一個 16 個神經元的全鏈接層。

但建立了不調用是沒有用的,咱們要將這個層構建到網絡之中,須要調用它的 apply() 方法,而 apply() 方法就接收 inputs 這個參數,返回計算結果,運行結果以下:

Tensor("dense/Relu:0", shape=(?, 16), dtype=float32)

所以咱們能夠發現,這些類在初始化的時候其實是比其對應的方法少了 inputs 參數,其餘的參數都是徹底一致的,另外須要調用 apply() 方法才能夠應用該層並將其構建到模型中。

因此其餘的類的用法在此就不一一贅述了,初始化的參數能夠類比其對應的方法,實例化類以後,調用 apply() 方法,能夠達到一樣的構建模型的效果。

結語

以上即是 TensorFlow layers 模塊的詳細用法說明,更加詳細的用法能夠參考官方文檔:https://www.tensorflow.org/api_docs/python/tf/layers。本節代碼地址:https://github.com/AIDeepLearning/TensorFlowLayers。

相關文章
相關標籤/搜索