tensorflow中tf.nn.conv1d和layers.conv1d的區別

在用tensorflow做一維的卷積神經網絡的時候會遇到tf.nn.conv1d和layers.conv1d這兩個函數,但是這兩個函數有什麼區別呢,通過計算得到一些規律。

1.關於tf.nn.conv1d的解釋,以下是Tensor Flow中關於tf.nn.conv1d的API註解:

Computes a 1-D convolution given 3-D input and filter tensors.

Given an input tensor of shape
  [batch, in_width, in_channels]
if data_format is "NHWC", or
  [batch, in_channels, in_width]
if data_format is "NCHW",
and a filter / kernel tensor of shape
[filter_width, in_channels, out_channels], this op reshapes
the arguments to pass them to conv2d to perform the equivalent
convolution operation.

Internally, this op reshapes the input tensors and invokes `tf.nn.conv2d`.
For example, if `data_format` does not start with "NC", a tensor of shape
  [batch, in_width, in_channels]
is reshaped to
  [batch, 1, in_width, in_channels],
and the filter is reshaped to
  [1, filter_width, in_channels, out_channels].
The result is then reshaped back to
  [batch, out_width, out_channels]
\(where out_width is a function of the stride and padding as in conv2d\) and
returned to the caller.

Args:
  value: A 3D `Tensor`.  Must be of type `float32` or `float64`.
  filters: A 3D `Tensor`.  Must have the same type as `input`.
  stride: An `integer`.  The number of entries by which
    the filter is moved right at each step.
  padding: 'SAME' or 'VALID'
  use_cudnn_on_gpu: An optional `bool`.  Defaults to `True`.
  data_format: An optional `string` from `"NHWC", "NCHW"`.  Defaults
    to `"NHWC"`, the data is stored in the order of
    [batch, in_width, in_channels].  The `"NCHW"` format stores
    data as [batch, in_channels, in_width].
  name: A name for the operation (optional).

Returns:
  A `Tensor`.  Has the same type as input.

Raises:
  ValueError: if `data_format` is invalid.
什麼意思呢?就是說conv1d的參數含義:(以NHWC格式爲例,即,通道維在最後)

1、value:在註釋中,value的格式爲:[batch, in_width, in_channels],batch爲樣本維,表示多少個樣本,in_width爲寬度維,表示樣本的寬度,in_channels維通道維,表示樣本有多少個通道。 
事實上,也可以把格式看作如下:[batch, 行數, 列數],把每一個樣本看作一個平鋪開的二維數組。這樣的話可以方便理解。

2、filters:在註釋中,filters的格式爲:[filter_width, in_channels, out_channels]。按照value的第二種看法,filter_width可以看作每次與value進行卷積的行數,in_channels表示value一共有多少列(與value中的in_channels相對應)。out_channels表示輸出通道,可以理解爲一共有多少個卷積核,即卷積核的數目。

3、stride:一個整數,表示步長,每次(向下)移動的距離(TensorFlow中解釋是向右移動的距離,這裏可以看作向下移動的距離)。

4、padding:同conv2d,value是否需要在下方填補0。

5、name:名稱。可省略。
首先從參數列表可以看出value指的輸入的數據,stride就是卷積的步長,這裏我們最有疑問的就是filters這個參數,那麼我們對filter進行簡單的說明。從上面可以看到filters的格式爲:[filter_width, in_channels, out_channels],這是一個數組的維度,對應的是卷積核的大小,輸入的channel的格式,和卷積核的個數,下面我們用例子說明問題:

import tensorflow as tf
import numpy as np


if __name__ == '__main__':
    inputs = tf.constant(np.arange(1, 6, dtype=np.float32), shape=[1, 5, 1])
    w = np.array([1, 2], dtype=np.float32).reshape([2, 1, 1])
    # filter width, filter channels and out channels(number of kernels)
    cov1 = tf.nn.conv1d(inputs, w, stride=1, padding='VALID')
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        out = sess.run(cov1)
        print(out)

其輸出爲:[[[ 5.],
        [ 8.],
        [11.],
        [14.]]]
我們分析一下,輸入的數據爲[[[1],[2],[3],[4],[5]]],有5個特徵,分別對應的數值爲1,2,3,4,5,那麼經過卷積的結果爲5,8,11,14,那麼這個結果是怎麼來的呢,我們根據卷積的計算,可以得到5 = 1*1 + 2*2, 8=2*1+ 3*2, 11 = 3*1+4*2, 14=4*1+5*2, 也就是W1=1, W2=2,正好和我們先面filters設置的數值相等,

w = np.array([1, 2], dtype=np.float32).reshape([2, 1, 1])

所以可以看到這個filtes設置的是是卷積核矩陣的,換句話說,卷積核矩陣我們是可以設置的。

2. 1.關於tf.layers.conv1d,函數的定義如下


tf.layers.conv1d(

inputs,

filters,

kernel_size,

strides=1,

padding='valid',

data_format='channels_last',

dilation_rate=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, kernel_size,下面分別說明

 

inputs :  輸入tensor, 維度(None,  a, b) 是一個三維的tensor

             None  :  一般是填充樣本的個數,batch_size

             a         :  句子中的詞數或者字數

             b          :    字或者詞的向量維度

 

filters :  過濾器的個數
kernel_size : 卷積核的大小,卷積核其實應該是一個二維的,這裏只需要指定一維,是因爲卷積核的第二維與輸入的詞向量維度是一致的,因爲對於句子而言,卷積的移動方向只能是沿着詞的方向,即只能在列維度移動。

一個例子:

import tensorflow as tf
import numpy as np


if __name__ == '__main__':
    inputs = tf.constant(np.arange(1, 6, dtype=np.float32), shape=[1, 5, 1])
    cov2 = tf.layers.conv1d(inputs, filters=1, kernel_size=2, strides=1, padding='VALID')
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        out = sess.run(cov2)
        print(out)

輸出結果:[[[-1.9953331]
  [-3.5520997]
  [-5.108866 ]
  [-6.6656327]]]

也許你得到的結果和我得到的結果不同,因爲在這個函數裏面只是設置了卷積核的尺寸和步長,沒有設置具體的卷積核矩陣,所以這個卷積核矩陣是隨機生成的,就會出現可能運行上面的程序出現不同結果的情況。

 

引用:

https://blog.csdn.net/u011734144/article/details/84066928

https://blog.csdn.net/DaVinciL/article/details/81359245

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章