为了账号安全,请及时绑定邮箱和手机立即绑定

Keras中Conv1D和Conv2D的区别

标签:
人工智能

如有错误,欢迎斧正。

我的答案是,在Conv2D输入通道为1的情况下,二者是没有区别或者说是可以相互转化的。首先,二者调用的最后的代码都是后端代码(以TensorFlow为例,在tensorflow_backend.py里面可以找到):


  1. x = tf.nn.convolution(  

  2.         input=x,  

  3.         filter=kernel,  

  4.         dilation_rate=(dilation_rate,),  

  5.         strides=(strides,),  

  6.         padding=padding,  

  7.         data_format=tf_data_format)  

区别在于input和filter传递的参数不同,input不必说,filter=kernel是什么呢?

我们进入Conv1D和Conv2D的源代码看一下。他们的代码位于layers/convolutional.py里面,二者继承的都是基类_Conv(Layer)。进入_Conv类查看代码可以发觉以下代码:


  1. self.kernel_size = conv_utils.normalize_tuple(kernel_size, rank, 'kernel_size')  

  2. ……#中间代码省略  

  3. input_dim = input_shape[channel_axis]  

  4. kernel_shape = self.kernel_size + (input_dim, self.filters)  

我们假设,Conv1D的input的大小是(600,300),而Conv2D的input大小是(600),二者kernel_size为3。

进入conv_utils.normalize_tuple函数可以看到:


  1. def normalize_tuple(value, n, name):  

  2.     """Transforms a single int or iterable of ints into an int tuple. 

  3.  

  4.     # Arguments 

  5.         value: The value to validate and convert. Could an int, or any iterable 

  6.           of ints. 

  7.         n: The size of the tuple to be returned. 

  8.         name: The name of the argument being validated, e.g. "strides" or 

  9.           "kernel_size". This is only used to format error messages. 

  10.  

  11.     # Returns 

  12.         A tuple of n integers. 

  13.  

  14.     # Raises 

  15.         ValueError: If something else than an int/long or iterable thereof was 

  16.         passed. 

  17.     """  

  18.     if isinstance(value, int):  

  19.         return (value,) * n  

  20.     else:  

  21.         try:  

  22.             value_tuple = tuple(value)  

  23.         except TypeError:  

  24.             raise ValueError('The `' + name + '` argument must be a tuple of ' +  

  25.                              str(n) + ' integers. Received: ' + str(value))  

  26.         if len(value_tuple) != n:  

  27.             raise ValueError('The `' + name + '` argument must be a tuple of ' +  

  28.                              str(n) + ' integers. Received: ' + str(value))  

  29.         for single_value in value_tuple:  

  30.             try:  

  31.                 int(single_value)  

  32.             except ValueError:  

  33.                 raise ValueError('The `' + name + '` argument must be a tuple of ' +  

  34.                                  str(n) + ' integers. Received: ' + str(value) + ' '  

  35.                                  'including element ' + str(single_value) + ' of type' +  

  36.                                  ' ' + str(type(single_value)))  

  37.     return value_tuple  


所以上述代码得到的kernel_size是kernel的实际大小,根据rank进行计算,Conv1D的rank为1,Conv2D的rank为2,如果是Conv1D,那么得到的kernel_size就是(3,)如果是Conv2D,那么得到的是(3,3)


  1. input_dim = input_shape[channel_axis]  

  2. kernel_shape = self.kernel_size + (input_dim, self.filters)  

又因为以上的inputdim是最后一维大小,filter数目我们假设二者都是64个卷积核。因此,Conv1D的kernel的shape实际为:

(3,300,64)

而Conv2D的kernel的shape实际为:

(3,3,1,64)

如果,我们将传参Conv2D时使用的的kernel_size设置为自己的元组例如(3,300),那么传根据conv_utils.normalize_tuple函数,最后的kernel_size会返回我们自己设置的元组,也即(3,300)那么Conv2D的实际shape是:

(3,300,1,64),也即这个时候的Conv1D的大小reshape一下得到,二者等价。

换句话说,Conv1D(kernel_size=3)实际就是Conv2D(kernel_size=(3,300)),当然必须把输入也reshape成(600,300,1),即可在多行上进行Conv2D卷积。

这也可以解释,为什么在Keras中使用Conv1D可以进行自然语言处理,因为在自然语言处理中,我们假设一个序列是600个单词,每个单词的词向量是300维,那么一个序列输入到网络中就是(600,300),当我使用Conv1D进行卷积的时候,实际上就完成了直接在序列上的卷积,卷积的时候实际是以(3,300)进行卷积,又因为每一行都是一个词向量,因此使用Conv1D(kernel_size=3)也就相当于使用神经网络进行了n_gram=3的特征提取了。这也是为什么使用卷积神经网络处理文本会非常快速有效的内涵。

原文出处

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消