一维卷积卷积神经网络 一维卷积padding_一维卷积卷积神经网络


在TensorFlow学习笔记(8):CNN实现中我们以图像处理为场景对卷积神经网络进行了介绍,包括了卷积操作和pooling操作的实现,其中卷积和pooling都采用了二维的操作,输入数据是四维的,shape = [batch, in_height, in_width, in_channels],例如图像像素为28 * 28, RGB三色道表示,batch取100,那么shape = [100, 28, 28, 3]

在处理文本的时候,通常卷积操作的kernel的高度是固定的,与文本中每个字符的向量的长度相同,因此我们通常采用一维卷积来进行操作,例如下面的模型


一维卷积卷积神经网络 一维卷积padding_ide_02


在本文中,我们介绍如何对文本向量进行卷积和pooling,


1. 一维卷积操作

在tf.layers.conv1d中提供了一维卷积操作,参数如下所示


tf.layers.conv1d(
    inputs,
    filters,
    kernel_size,
    strides=1,
    padding='valid',
    data_format='channels_last',
    dilation_rate=1,
    activation=None,
    use_bias=True,
    kernel_initializer=None,
    bias_initializer=tf.zeros_initializer(),
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None,
    trainable=True,
    name=None,
    reuse=None
)


其中几个重要的参数如下所示:

  • inputs:3维的输入Tensor,每个维度分别表示(batch size, max sentence length, vector dimension)
  • filters: 表示filters的数量
  • kernel_size:表示卷积核的大小,卷积核其实应该是一个二维的,这里只需要指定一维,是因为卷积核的第二维与输入的词向量维度是一致的,因为对于句子而言,卷积的移动方向只能是沿着词的方向,即只能在列维度移动
  • strides: 表示步长,因为只能在词的方向移动,因此是一个整数,通常取1
  • activation: 表示激活函数,如果是None的话,就表示线性激活函数
  • padding:表示是否进行填充

2. 一维pooling

同样tensorflow中提供了一维的pooling操作,包括tf.layers.MaxPooling1D和tf.layers.AveragePooling1D,我们以MaxPooling操作来进行说明


__init__(
    pool_size,
    strides,
    padding='valid',
    data_format='channels_last',
    name=None,
    **kwargs
)


其中

  • strides是整数,表示步长
  • pool_size是pooling窗口的大小
  • padding:表示是否进行填充

例如下面的代码实现了采用CNN进行文本分类的功能


# 首先对句子进行卷积
		with tf.variable_scope('cnn'):
			# shape (batch size, max sentence length, kernel nums)
			feature_maps = tf.layers.conv1d(
				inputs = self.char_embeddings,
				kernel_size = self.hp.cnn_kernel_size,
				filters = self.hp.cnn_kernel_nums,
				padding = 'same',
				use_bias = True,
				activation = tf.nn.tanh,
				name = 'convolution'
				)
		# 进行pooling
		with tf.variable_scope('poolinig'):
			# shape = (batch size, 1, kernel nums)
			pooled_output = tf.layers.max_pooling1d(
				inputs = feature_maps,
				pool_size = self.hp.max_length_sentence,
				strides = 1,
				padding = 'valid',
				name = 'max_pooling'
				)
			# 进行变换

		# 然后用全联接网络计算概率
		with tf.variable_scope('proj'):
			W = tf.get_variable(
				name = 'w', 
				dtype = tf.float32,
				shape = [self.hp.cnn_kernel_nums, len(self.argument_role_vocab)]
				)
			b = tf.get_variable(
				name = 'b',
				dtype = tf.float32,
				shape = [len(self.argument_role_vocab)],
				initializer = tf.zeros_initializer()
				)

			# shape = (batch size, kernel nums)
			output = tf.reshape(pooled_output, [-1, self.hp.cnn_kernel_nums])

			# shape = (batch size, vocab_tags_nums)
			self.logits = tf.matmul(output, W) + b


其中pooling是对每个feature map进行处理,因此我们选择了pool_size为feature map的长度,也就是句子的最大长度,这样得到的结果就是每个feature map中的最大值;然后进行维度变换,得到的结果就是图示模型中的样子