一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d

这几天在看代码,然后看网上关于一维卷积介绍的文档很多,但是对于tf.nn.conv1d 矩阵运算过程几乎没有介绍,这里我就将刚弄懂的写出来,希望能帮到大家理解这个函数,也为了让自己以后能更好的查阅~~


conv1d(value,  filters, stride, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

value: A 3D Tensor . Must be of type float16 or float32 .
被卷积的矩阵 :可以当成是[batch, sample, feature]

filters: A 3D Tensor . Must have the same type as input .
卷积核 :形状 [filter_width, in_channels, out_channels]

stride: An integer . The number of entries by which the filter is moved right at each step.
步长 :卷积核滑动步长

padding: ‘SAME’ or ‘VALID’
same和valid可以参考这篇文档: 深度学习面试题09:一维卷积(Full卷积、Same卷积、Valid卷积、带深度的一维卷积)

废话不多说,咱们今天不讲原理,只讲其中矩阵运算过程~ 帮助大家理解~


卷积核filter 的形状:[filter_width, in_channels, out_channels]

  • in_channels 必须等于被卷积的矩阵的第3维数,即列数
  • out_channels 表示卷积核数目,类似于图像里,一个卷积核得到一个输出,这里有|out_channels |个卷积核,则输出必定有|out_channels| 列 
  • filter_width 表示与 value 进行卷积的 个数/每次 (这里不懂可以以往后看例子)

例一:filter_width=1时:

举例,令被一维卷积的value维度是:(2,3,4)
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第1张图片
令卷积核的filter维度是:(1,4,5)
即 [filter_width, in_channels, out_channels] = (1,4,5)
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第2张图片
filter_width =1 说明每次对value里的一行进行卷积:

以value第一个batch里为例:

第一个batch中第1行的计算过程是:
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第3张图片
第一个batch中第2行的计算过程是:
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第4张图片
tf.nn.conv1d 一次对一个batch进行卷积处理,batch之间互不影响。
以此类推,完成一个batch的计算后,第二个batch的计算过程也如此。
所以value整体卷积的结果是:
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第5张图片
以上filter_width=1时的代码如下:

sess= tf.Session()
    a = tf.Variable(np.random.randint(1,3,(2,3,4)))
    filt = tf.get_variable("weights", initializer=np.random.randint(1,3,(1,4,5)))

    sess.run(tf.global_variables_initializer())
    print(sess.run(a))
    print('\n')
    print(sess.run(filt))
    filt_input = tf.nn.conv1d(tf.to_float(a), tf.to_float(filt), 1, "VALID", name="embedded_input")
    print(sess.run(filt_input))

由于filter_width=1时,valid和same的计算没啥区别,这里不讲,在filter_width>1时介绍。


例二:filter_width>1时:

举例,令被一维卷积的value维度是:(2,3,4)
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第6张图片
令卷积核的filter维度是:(2,4,5)
即 [filter_width, in_channels, out_channels] = (2,4,5)
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第7张图片
filter_width =2 说明每次对value里的2行进行卷积:

1. VALID 时:

tf.nn.conv1d 一次对一个batch进行卷积处理,batch之间互不影响 ,所以这里以第一个batch中的计算进行说明:
咱们这里设置的filter_width =2, 说明每次对value里的2行进行卷积。
则:

  • 第一次计算取1,2行进行卷积,第1行和卷积核的第一大块,也就是(0,:,:)进行矩阵乘法,第2行和卷积核的第二大块,也就是(1,:,:)进行矩阵乘法,结果相加得到第一次卷积结果:

一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第8张图片

  • 第二次计算取2,3行进行卷积,第2行和卷积核的第一大块,也就是(0,:,:)进行矩阵乘法,第3行和卷积核的第二大块,也就是(1,:,:)进行矩阵乘法,结果相加得到第二次卷积结果:
    一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第9张图片

以此类推,完成一个batch的计算后,第二个batch的计算过程也如此。

所以value整体VALID卷积的结果是:
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第10张图片


2. SAME 时:

刚才在VALID中,第一次计算取value的1,2行进行卷积,第二次取value的2,3行进行卷积。
也就是说VALID中,filter_width =2时每次取两行来卷积,然后只要value的 1,2,3行全部都处理完了就OK 。也就是一共进行了两次卷积,得到的卷积的结果, 每个batch的行数为两行 
而这里的 “SAME”, 为了保证卷积后的结果每个batch的行数和原先VALUE行数相等(原先Value中每个batch有3行) ,所以还需要再在VALID基础上做一次卷积!

以第一个batch为例,整体运算过程是:

  • 第一次计算取1,2行进行卷积,第1行和卷积核的第一大块,也就是(0,:,:)进行矩阵乘法,第2行和卷积核的第二大块,也就是(1,:,:)进行矩阵乘法,相加得到第一次卷积结果:
    一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第11张图片
  • 第二次计算取2,3行进行卷积,第2行和卷积核的第一大块,也就是(0,:,:)进行矩阵乘法,第3行和卷积核的第二大块,也就是(1,:,:)进行矩阵乘法,相加得到第二次卷积结果:
    一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第12张图片
  • 第三次计算按理来说,每次取两行来卷积,这里就要取3,4行进行卷积,但是这里VALUE中没有第4行,所以只需要第3行和卷积核的第一大块,也就是(0,:,:)进行矩阵乘法,得到第三次卷积结果:
    一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第13张图片
    这样就保证了计算结果是3行。

以此类推,完成一个batch的计算后,第二个batch的计算过程也如此。

所以value整体SAME卷积的结果是:
一维卷积表示tf.nn.conv1d矩阵的运算过程,以,例子,说明,tfnnconv1d_第14张图片

这里VALID和SAME代码如下:

sess= tf.Session()
    a = tf.Variable(np.random.randint(1,3,(2,3,4)))
    filt = tf.get_variable("weights", initializer=np.random.randint(1,3,(2,4,5)))

    sess.run(tf.global_variables_initializer())
    print(sess.run(a))
    print('\n')
    print(sess.run(filt))
    filt_input = tf.nn.conv1d(tf.to_float(a), tf.to_float(filt), 1, "VALID", name="embedded_input")
    filt_input2 = tf.nn.conv1d(tf.to_float(a), tf.to_float(filt), 1, "SAME", name="embedded_input")
    print(sess.run(filt_input))
    print(sess.run(filt_input2))

个人觉得filter_width=1的时候更适合做embedding~~

文章来源互联网,如有侵权,请联系管理员删除。邮箱:[email protected] / QQ:417803890

你可能感兴趣的:(tensorflow)