今天我们对比Conv1D和Conv2D实现文本卷积,提前说明两种方式实现的运算是一样的。
两种实现方式的原理图对比
输入数据的形状对比
Conv1D (batch, steps, channels),steps表示1篇文本中含有的单词数量,channels表示1个单词的维度。
Conv2D (batch, rows, cols, channels),rows表示1篇文本中含有的单词数量,cols表示1个单词的维度,channels为1表示只有1个颜色通道,原因是对于文本来说只有1个颜色通道。
卷积核的对比
Conv1D kernel_size=2,虽然是2个单词的宽度,但在运算时是用(2,8)的卷积核的。
Conv2D kernel_size=(2, 8),(2, 8)的卷积核。
输出数据的形状对比
Conv1D (batch, new_steps, filters), 1个卷积核对文本卷积后输出列向量的行数(当然由于卷积核只可以向下移动,因此得到的是1个列向量),有多少个卷积核filters就有多少个列向量。
Conv2D (batch, new_rows, new_cols, filters), new_rows, new_cols表示1个卷积核对文本卷积后输出矩阵的行数和列数(当然由于卷积核可以向右和向下移动,因此得到的是1个矩阵),有多少个卷积核filters就有多少个矩阵。
模型结构的对比
实现代码对比
Conv1D
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from keras.layers import Conv1D
from keras.utils import plot_model
model = Sequential()
# 添加嵌入层
model.add(Embedding(10000, # 词汇表大小决定嵌入层参数矩阵的行数
8, # 输出每个词语的维度为8
input_length=4)) # 输入矩阵一个句子向量含有的词语数即列数
# Conv1D要求输入为(batch, steps, channels)分别表示(批数据量,一个句子中的词语数,一个词语的维度),
# 因此在Embedding层后不要加Flatten层
model.add(Conv1D(filters=4, # 卷积核数量
kernel_size=2)) # 卷积核的宽度
model.summary()
plot_model(model, to_file='./model.png', show_shapes=True)
Conv2D
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from keras.layers import Conv2D
from keras.layers import Reshape
from keras.utils import plot_model
model = Sequential()
# 添加嵌入层
model.add(Embedding(1000, # 词汇表大小决定嵌入层参数矩阵的行数
8, # 输出每个词语的维度为8
input_length=4)) # 输入矩阵一个句子向量含有的词语数即列数
# 添加Reshape层Conv2D要求输入为(batch, rows, cols, channels)分别表示(批数据量,一个句子中的词语数,一个词语的维度,通道数)
model.add(Reshape((4, 8, 1)))
#
model.add(Conv2D(filters=4, # 卷积核数量
kernel_size=(2, 8))) # 卷积核的宽度2
model.summary()
plot_model(model, to_file='./model.png', show_shapes=True)