原文链接

单通道

第一个例子。假如现在有1000个信号谱,每个信号谱包含400个数据点。整个数据集维度是(1000,400),如何对信号谱进行一维卷积?首先,我们利用TensorFlow中的 tf.keras.layers.Conv1D 实现一维卷积。

TensorFlow

TensorFlow中一维卷积是自上而下做的,如下图所示。假设我们的卷积核是3。

§ 一维卷积 - 图1

对于上面的情况,用TensorFlow代码实现一次卷积和池化操作,代码如下:

  1. input_shape = (1000, 400, 1)
  2. x = tf.random.normal(input_shape)
  3. conv1D = tf.keras.layers.Conv1D(1, 3, padding='valid') #1是输出通道数,3是卷积核大小,不使用边界填充
  4. max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,strides=1, padding='valid')
  5. y= conv1D(x)
  6. y = max_pool_1d(y)
  7. print(y)

shape=(1000, 397, 1)

计算维度的公式如下:§ 一维卷积 - 图2表示卷积核大小,§ 一维卷积 - 图3表示使用边界填充,§ 一维卷积 - 图4表示步长。

卷积后的维度:§ 一维卷积 - 图5

池化后的维度:§ 一维卷积 - 图6

在本例中,么有使用边界填充,卷积后的维度:400-3+1=398,池化后的维度:398-2+1=397。

PyTorch

在Pytorch中,一维卷积是自左向右做的,过程如下图所示。

§ 一维卷积 - 图7

  1. import torch
  2. import torch.nn as nn
  3. # 定义网络
  4. conv1 = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=3)
  5. maxp = nn.MaxPool1d(2, stride=1) #stride的默认值是kernel_size
  6. # 使用网络
  7. input = torch.randn(1000, 1, 400)
  8. y = conv1(input)
  9. y = maxp(y)
  10. print(y)

多通道

以上是对于一维信号谱数据做的一维卷积,信号谱数据通道是1,是一种比较简单的情况。然而,在文本分析中,每一个字都被编码,通道数不再是1,如下图所示,一句诗中的每个汉字都要被编码为一个1×8的数组,那么“长风破浪会有时”就由一个§ 一维卷积 - 图8的数组表示。这种情况下,通道数就是8。

§ 一维卷积 - 图9

TensorFlow

因为上面数据的通道数是8,如果卷积核大小设置为3,则卷积核的维度为(3,8)。对上面的诗词数据进行卷积过程如下(仅展示了一个通道):

§ 一维卷积 - 图10

假如现在有1000句诗,每句诗编码为(7,8)的维度,使用TensorFlow代码实现卷积和池化过程如下:

  1. import tensorflow as tf
  2. conv1D = tf.keras.layers.Conv1D(1, 3, padding='valid')
  3. max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,strides=1, padding='valid')
  4. input_shape = (1000, 7, 8)
  5. x = tf.random.normal(input_shape)
  6. y= conv1D(x)
  7. y = max_pool_1d(y)
  8. print(y)

上述代码输出shape=(1000, 4, 1),这里的1是因为我们设置的通道数是1。如果通道数改成10,每一个通道的结果为(1000,4,1),10个通道的结果组合得到shape=(1000, 4, 10),此时“长风破浪会有时”这句诗的维度由(7,8)变成(4,10)了。

值得注意的是,TensorFlow不需要指定数据的通道,只需指定卷积核大小即可,它会根据我们的输入维度来自动匹配卷积核维度。第一个信号谱的例子中,卷积核维度为(3,1)。诗句的例子中卷积的维度为(3,8)。

PyTorch

在Pytorch中,是自左向右进行卷积,长风破浪会有时应该如下表示:

§ 一维卷积 - 图11

Pytorch中卷积过程如下:

§ 一维卷积 - 图12

Pytroch实现代码如下:

  1. import torch
  2. import torch.nn as nn
  3. conv1 = nn.Conv1d(in_channels=8, out_channels=1, kernel_size=3)
  4. maxp = nn.MaxPool1d(2, stride=1) #stride的默认值是kernel_size
  5. input = torch.randn(1000, 8, 7)
  6. y = conv1(input)
  7. y = maxp(y)
  8. print(y)

从Pytroch的代码中的in_channels=8可以知道,诗句中的每个字的数据通道为8。in_channels=8是我们必须指定的,切勿把7和8搞混了。

总结:以上分别介绍了TensorFlow中tf.keras.layers.Conv1D和Pytorch中nn.Conv1d的使用方法。TensorFlow中自上而下进行一维卷积核池化,Pytorch中则是自左向右进行一维卷积核池化。