TF卷积函数 tf.nn.conv2d 介绍
首先介绍一下tensorflow中卷积函数tf.nn.conv2d()
。
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
主要介绍input和filter这两个参数。
input
:是一个4维的tensor,维度为[batch,in_height,in_width,in_channels][batch, in\_height, in\_width, in\_channels][batch,in_height,in_width,in_channels],4个参数的意义是[训练时一个batch的图片数量,图片高度,图片宽度,图像通道数][训练时一个batch的图片数量, 图片高度, 图片宽度,图像通道数][训练时一个batch的图片数量,图片高度,图片宽度,图像通道数]。filter
: 也是一个4维的tensor,维度为[filter_height,filter_width,in_channels,out_channels][filter\_height, filter\_width, in\_channels, out\_channels][filter_height,filter_width,in_channels,out_channels],4个参数的意义是[卷积核的高度,卷积核的宽度,图像通道数,输出通道数][卷积核的高度,卷积核的宽度,图像通道数,输出通道数][卷积核的高度,卷积核的宽度,图像通道数,输出通道数]。
注意的是,input
中的第4个维度必须和filter
中的第3个参数一致。
对于图片来说,一次输入batch个图片,然后经过tf.nn.conv2d()
函数作用,返回一个4维的tensor,维度为[batch,height,width,channels][batch, height, width, channels][batch,height,width,channels],其中height和widthheight和widthheight和width的值由卷积核的宽度、高度和输入图片的宽度、高度计算得到的。channelschannelschannels参数是filter中的第四个维度out_channelsout\_channelsout_channels。这个tensor的含义是:一张图片有channelschannelschannels个维度为height∗widthheight*widthheight∗width的feature map。
tf.nn.conv2d如何在NLP中应用
通过上面的分析可知,要应用tf.nn.conv2d
来提取句子的特征,就要将文档、句子、单词与cv中的图片、像素点对应起来,问题是如何对应?
论文中是这样对应的:将一个单词的embedding与图片中的一行像素点对应。一个句子由sequence_length个单词组成,一张图片也由一行行像素点组成。那么一个句子的维度为[sequence_length,embedding_size][sequence\_length,embedding\_size][sequence_length,embedding_size],即将一个句子与一张图片对应起来。
那么如何将文档与cv中的某个概念对应起来?其实论文中是这样做的:tf.nn.conv2d()
的input参数是一个4维的tensor,input的第一个参数是batch,对于CV来说是一次输入batch张图片,那么对于NLP来说就是输入batch个句子,但是这个batch设定为一个文档的最大的句子个数。即在NLP中,每次输入tf.nn.conv2d
的是一篇文档。
在NLP中,tf.nn.conv2d的参数的设定:
conv=tf.nn.conv2d(conv_s, filter, strides=[1,1,1,1], padding="VALID",name="conv")
# BN操作的原理:https://www.cnblogs.com/guoyaohua/p/8724433.html
conv=tf.contrib.layers.batch_norm(conv, is_training = self.tst, scope='cnn_bn_')
b=tf.get_variable("b-%s"%filter_size,[self.feature_map[i]])
h=tf.nn.tanh(tf.nn.bias_add(conv,b),"tanh")
pooled=tf.nn.max_pool(h, ksize=[1,self.sequence_length-filter_size+1,1,1], strides=[1,1,1,1], padding='VALID',name="pool")
pooled_temp.append(pooled)
其中conv_s的维度是[max_num_sequence,sentence_length,embed_size,1][max\_num\_sequence, sentence\_length, embed\_size, 1][max_num_sequence,sentence_length,embed_size,1],意义分别是
一篇文档的句子的最大数量、一个句子的单词的最大数量、word embedding的维度、最后一个维度是1的原因是对于一张图片来说就是通道数,对于文本来说那就是1个维度了。
filter的维度是[filter_size,self.embed_size,1,self.feature_map[i]][filter\_size, self.embed\_size, 1, self.feature\_map[i]][filter_size,self.embed_size,1,self.feature_map[i]]
故最终得到的conv的维度是[max_num_sequence,sequence_length−filter_size+1,1,num_filters][max\_num\_sequence, sequence\_length-filter\_size+1, 1, num\_filters][max_num_sequence,sequence_length−filter_size+1,1,num_filters]
经过tf.nn.max_pool()操作,得到pooled的维度为[max_num_sequence,1,1,num_filters][max\_num\_sequence, 1, 1, num\_filters][max_num_sequence,1,1,num_filters]