基于Keras中Conv1D和Conv2D的区别说明

如有错误,欢迎斧正。

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

x = tf.nn.convolution(
  input=x,
  filter=kernel,
  dilation_rate=(dilation_rate,),
  strides=(strides,),
  padding=padding,
  data_format=tf_data_format)

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

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

进入_Conv类查看代码可以发觉以下代码:

self.kernel_size = conv_utils.normalize_tuple(kernel_size, rank, 'kernel_size')
……#中间代码省略
input_dim = input_shape[channel_axis]
kernel_shape = self.kernel_size + (input_dim, self.filters)

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

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

def normalize_tuple(value, n, name):
 """Transforms a single int or iterable of ints into an int tuple.
 # Arguments
  value: The value to validate and convert. Could an int, or any iterable
   of ints.
  n: The size of the tuple to be returned.
  name: The name of the argument being validated, e.g. "strides" or
   "kernel_size". This is only used to format error messages.
 # Returns
  A tuple of n integers.
 # Raises
  ValueError: If something else than an int/long or iterable thereof was
  passed.
 """
 if isinstance(value, int):
  return (value,) * n
 else:
  try:
   value_tuple = tuple(value)
  except TypeError:
   raise ValueError('The `' + name + '` argument must be a tuple of ' +
        str(n) + ' integers. Received: ' + str(value))
  if len(value_tuple) != n:
   raise ValueError('The `' + name + '` argument must be a tuple of ' +
        str(n) + ' integers. Received: ' + str(value))
  for single_value in value_tuple:
   try:
    int(single_value)
   except ValueError:
    raise ValueError('The `' + name + '` argument must be a tuple of ' +
         str(n) + ' integers. Received: ' + str(value) + ' '
         'including element ' + str(single_value) + ' of type' +
         ' ' + str(type(single_value)))
 return value_tuple

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

input_dim = input_shape[channel_axis] kernel_shape = self.kernel_size + (input_dim, self.filters)

又因为以上的inputdim是最后一维大小(Conv1D中为300,Conv2D中为1),filter数目我们假设二者都是64个卷积核。

因此,Conv1D的kernel的shape实际为:

(3,300,64)

而Conv2D的kernel的shape实际为:

(3,3,1,64)

刚才我们假设的是传参的时候kernel_size=3,如果,我们将传参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的特征提取了。

这也是为什么使用卷积神经网络处理文本会非常快速有效的内涵。

补充知识:tf.layer.conv1d、conv2d、conv3d

下面我都是抄的,如果说是正确,那么conv3d就是2d+时间域的吧?

网上搜的一篇资料,还没看:tensorflow中一维卷积conv1d处理语言序列的一点记录

tensorflow中的conv1d和conv2d的区别:conv1d是单通道的,conv2d是多通道,所以conv1d适合处理文本序列,conv2d适合处理图像。

conv1d

import tensorflow as tf
input = tf.Variable(tf.random_normal([1, 5, 20]))
params1 = {"inputs": input, "filters": 2048, "kernel_size": 2,"strides":1,"activation": tf.nn.relu, "use_bias": True,"padding":'SAME'}
op01 = tf.layers.conv1d(**params1)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
print(sess.run(tf.shape(op01)))
>>>[1,5,2048]

输入input第一维为batch_size,此处为1,即只有一个样本,第二维和第三维分别表示输入的长和宽,在文本中就是word_embedding矩阵,句子长度为5,embedding维度为20。

在文本中,卷积的某一维大小往往为embedding长度,即在宽度上不需要窗口移动,宽度就是整个窗口。所以conv1d默认卷积的宽度就为embedding维度,长度是通过kernel_size来指定的,此处为2,即卷积核的大小为2*embedding_size。strides为步长,此处为1,即卷积核每隔一个单词移动一次。filters是卷积核的个数,即输出的维度。padding有valid和same两种选择,valid在长度方向(宽度方向不padding)不进行padding,而same则在长度方向进行padding,保证输入句子长度和卷积后输出的句子长度一致,此处为5。

conv2d

#case 1
#input输入是1张 3*3 大小的图片,图像通道数是5(batch,长,宽,输入通道数)
#filter卷积核是 1*1 大小,数量是1(长,宽,输入通道数,输出通道数(卷积核个数))
#strides步长是[1,1,1,1],第一维和最后一维保持1不变,第二维和第三维分别为长度方向和宽度方向的步长。
#1张图最后输出的op1就是一个 shape为[1,3,3,1] 的张量,即得到一个3*3的feature map(batch,长,宽,输出通道数)
input = tf.Variable(tf.random_normal([1, 3, 3, 5]))
filter = tf.Variable(tf.random_normal([1, 1, 5, 1]))
op1 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')

这是另一个内容

class AveragePooling1D:1D输入的平均池层.

class AveragePooling2D:2D输入的平均池层(例如图像).

class AveragePooling3D:3D输入的平均池层(例如,体积).

class Conv1D:一维卷积层(例如时间卷积).

class Conv2D:二维卷积层(例如图像上的空间卷积).

class Conv3D:3D卷积层(例如卷上的空间卷积).

class MaxPooling1D:1D输入的最大池层.

class MaxPooling2D:2D输入的最大池层(例如图像).

class MaxPooling3D:3D输入的最大池层(例如卷).

以上这篇基于Keras中Conv1D和Conv2D的区别说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 对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_wi

  • Keras Convolution1D与Convolution2D区别说明

    以下是Convolution1D的例子: from keras.layers import Convolution1D from keras.models import Sequential model=Sequential() model.add(Convolution1D( filters=64, #64个滤波器 ->生成 64深度 kernel_size=3, #长度 为 3 input_shape=(10,32), # 输入形状 就是 图片形状 (step,input_dim) inpu

  • 关于keras.layers.Conv1D的kernel_size参数使用介绍

    今天在用keras添加卷积层的时候,发现了kernel_size这个参数不知怎么理解,keras中文文档是这样描述的: kernel_size: 一个整数,或者单个整数表示的元组或列表, 指明 1D 卷积窗口的长度. 又经过多方查找,大体理解如下: 因为是添加一维卷积层Conv1D(),一维卷积一般会处理时序数据,所以,卷积核的宽度为1,而kernel_size就是卷积核的长度了,这样的意思就是这个卷积核是一个长方形的卷积核. 补充知识:tf.layers.conv1d函数解析(一维卷积) 一维

  • 基于Keras中Conv1D和Conv2D的区别说明

    如有错误,欢迎斧正. 我的答案是,在Conv2D输入通道为1的情况下,二者是没有区别或者说是可以相互转化的.首先,二者调用的最后的代码都是后端代码(以TensorFlow为例,在tensorflow_backend.py里面可以找到): x = tf.nn.convolution( input=x, filter=kernel, dilation_rate=(dilation_rate,), strides=(strides,), padding=padding, data_format=tf_

  • 基于python中staticmethod和classmethod的区别(详解)

    例子 class A(object): def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%x a=A(

  • 基于js中this和event 的区别(详解)

    今天在看javascript入门经典-事件一章中看到了 this 和 event 两种传参形式.因为作为一个初级的前端开发人员平时只用过 this传参,so很想弄清楚,this和event的区别是什么,什么情况下用什么比较合适. onclick = changeImg(this)       vs     onclick = changeImg(event) <img src='usa.gif' onclick="changeImg(event)" /> <scrip

  • 基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 用户程序自定义的异常和应用程序特定的异常,必须借助于 throws 和 throw 语句来定义抛出异常. throw是语句抛出一个异常. 语法:throw (异常对象); throw e; throws是方法可能抛出异常的声明.(用在声明方法时,表示该方法可能要抛出异常) 语法:[(修饰符)](返回

  • 基于Python中capitalize()与title()的区别详解

    capitalize()与title()都可以实现字符串首字母大写. 主要区别在于: capitalize(): 字符串第一个字母大写 title(): 字符串内的所有单词的首字母大写 例如: >>> str='huang bi quan' >>> str.capitalize() 'Huang bi quan' #第一个字母大写 >>> str.title() 'Huang Bi Quan' #所有单词的首字母大写 非字母开头的情况: >>

  • keras中模型训练class_weight,sample_weight区别说明

    keras 中fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None) 官方文档

  • 基于keras中的回调函数用法说明

    keras训练 fit( self, x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None ) 1. x:输入数据.如果模型只有一个输入,那么x的类型是numpy array,如果模型有多个输入,那么x的类型应当为list,list的元素是对应

  • 浅谈Keras中fit()和fit_generator()的区别及其参数的坑

    1.fit和fit_generator的区别 首先Keras中的fit()函数传入的x_train和y_train是被完整的加载进内存的,当然用起来很方便,但是如果我们数据量很大,那么是不可能将所有数据载入内存的,必将导致内存泄漏,这时候我们可以用fit_generator函数来进行训练. 下面是fit传参的例子: history = model.fit(x_train, y_train, epochs=10,batch_size=32, validation_split=0.2) 这里需要给出

  • Keras中Conv1D的使用及说明

    目录 Conv1D 参数 输入尺寸 输出尺寸 输入输出尺寸的理解 keras Conv1D 一维卷积的输入维度 报错情况 问题原因 解决方法 总结 Conv1D keras.layers.Conv1D(filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='g

  • 基于keras中训练数据的几种方式对比(fit和fit_generator)

    一.train_on_batch model.train_on_batch(batchX, batchY) train_on_batch函数接受单批数据,执行反向传播,然后更新模型参数,该批数据的大小可以是任意的,即,它不需要提供明确的批量大小,属于精细化控制训练模型,大部分情况下我们不需要这么精细,99%情况下使用fit_generator训练方式即可,下面会介绍. 二.fit model.fit(x_train, y_train, batch_size=32, epochs=10) fit的

随机推荐