卯卯 | 炼就一手绝世刀法!

日出东海落西山,愁也一天,喜也一天。遇事不钻牛角尖,人也舒坦,心也舒坦!

NLP-使用tensorflow构建神经网络——卷积层和池化层细节说明(不是原创,写的详细而且不错)

链接:https://blog.csdn.net/spring_willow/article/details/80199975

背景介绍

本文内容是使用CNN进行文本分类,主要记录文本分类问题中使用tensorflow进行神经网络构建的内容。此篇承接上一篇的NLP-使用tensorflow构建神经网络——嵌入层细节部分说明。

目录

背景介绍

目录

一、CNN模型图

二、卷积和池化代码

三、细节说明之tf.truncated_normal;tf.concat;tf.reshape

    ①tf.truncated_normal(shape, mean, stddev)

    ②tf.concat(values,axis,name=”concat”)

四、细节说明之relu

    ①神经网络中的激活函数

    ②激活函数ReLu

    ③优化神经网络

五、细节说明之tf.nn.conv2d和tf.nn.max_pool

    ①tf.nn.conv2d(input,filter,strides, padding,use_cudnn_on_gpu=None, name=None)

    ②tf.nn.max_pool(value, ksize, strides, padding, name=None)

一、CNN模型图


图片来源:论文Convolutional Neural Networks for Sentence Classification


二、卷积和池化代码

     # Create a convolution + maxpool layer for each filter size

        pooled_outputs = []#初始化空的list

        for i, filter_size in enumerate(filter_sizes):#遍历卷积核种类,size=2、size=3、、、

            with tf.name_scope("conv-maxpool-%s" % filter_size):

                #建立一个名称为’conv-maxpool-‘的模块

                #  Convolution Layer

                filter_shape = [filter_size, embedding_size, 1, num_filters]

                #卷积核参数:高*宽*通道*卷积核个数,图片中最左侧所示

                W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")

                # W表示截断产生正态分布数据,方差为0.1,变量维度为filter_shape的张量

                b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")

                # b表示变量维度为卷积核个数,数值为0.1的张量

                conv = tf.nn.conv2d(#实现卷积

                    self.embedded_chars_expanded,

                    W,

                    strides=[1, 1, 1, 1],

                    padding="VALID",

                    name="conv")

                # Apply nonlinearity

                h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")#加入偏置,进入relu

                # Maxpooling over the outputs

                pooled = tf.nn.max_pool(#池化操作

                    h,

                    ksize=[1, sequence_length - filter_size + 1, 1, 1],

                    strides=[1, 1, 1, 1],

                    padding='VALID',

                    name="pool")

                pooled_outputs.append(pooled)

                #一个pooled是一种卷积核处理一个样本之后得到的一个值,如果有三种卷积核,则append了三次


        # Combine all the pooled features

        num_filters_total = num_filters * len(filter_sizes)

        # 每种卷积核的个数与卷积核的种类乘积,等于全部的卷积核个数

        self.h_pool = tf.concat(pooled_outputs, 3)

        #将pooled_outputs在第四维度上进行拼接

        self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

代码来源:https://github.com/dennybritz/cnn-text-classification-tf


三、细节说明之tf.truncated_normal;tf.concat;tf.reshape

    ①tf.truncated_normal(shape, mean, stddev)

    shape表示要生成的张量的维度,mean为均值,stddev为标准差,截断产生正态分布,数值与均值的差值不超过两倍的标准差。


    ②tf.concat(values,axis,name=”concat”)

    value是要进行拼接的张量,axis表示在哪一维度上进行拼接,0表示第一维度,1表示第二维度,依次往后,但是axis+1的值不        能 超过原本拼接数组本身的维度,例如对于二维数组,axis的值只能为0和1。


# a shape [2, 3]  

# b shape [2, 3]  

tf.shape(tf.concat([a, b],0)) ==> [4, 3]  

tf.shape(tf.concat([a, b],1)) ==> [2, 6]  

-----------------------------------

#a shape [2,3,4]

#b shape [2,3,4]

tf.shape(tf.concat([a,b],0))==> [4, 3,4]  

tf.shape(tf.concat([a,b],1))==> [2,6,4] 

tf.shape(tf.concat([a,b],2))==> [2,3,8]

tf.shape(tf.concat([a,a,a],0))==> [6,3,4] 

1

2

3

4

5

6

7

8

9

10

11

③tf.reshape(tensor,shape,name=None) 

tensor为要调整维度的张量,shape为要调整的形状。shape里允许最多有一个维度的值可以是-1,表示未知,根据其他维度的值自动进行计算,和np.reshape()一样。


四、细节说明之relu

①神经网络中的激活函数

如果不使用激励函数,则每一层的输出是上一层输入的线性函数,相当于没有隐藏层,只是矩阵相乘的结果。所以引入非线性函数作为激励函数,可以逼近任何函数,其作用是优化整个神经网络。


②激活函数ReLu

激活函数有好几种,如Sigmoid函数,tanh函数,这些都是比较老旧的激活函数,目前ReLu是最常用的激活函数,它有以下几个优点:


相比于其他函数计算量小(非指数运算)

sigmoid函数反向传播时,容易梯度消失造成信息丢失(饱和区倒数为0)

Relu使得一部分神经元输出为0,缓解了过拟合现象

③优化神经网络

优化神经网络的方法是反向传播:计算输出层的loss,将loss的导数不断向上一层网络传递,修正相应的参数来降低loss值。 

更多关于激活函数的信息点击这个链接,解决了我很多疑问。


五、细节说明之tf.nn.conv2d和tf.nn.max_pool

①tf.nn.conv2d(input,filter,strides, padding,use_cudnn_on_gpu=None, name=None)

input:要进行卷积的tensor,其shape为[batch, height, width, channels],在文本处理中,输入的tensor是文本词向量,shape为batch_size*seq_len*em_size*channel(=1)的4维tensor。

filter:卷积核tensor,其shape为[filter_height, filter_width, in_channels, out_channels],第三个参数 in_channels与input中in_channels值一样。在本文中,tensor的初始值是截断正态分布,shape为filter_size*em_size*channel(=1)*num_filters。

strides:步长,一个长度为4的一维向量,分别表示每一维的步长,一般是[1, stride,stride, 1]。

padding:”SAME”或”VALID”,表示不同的卷积方式。

use_cudnn_on_gpu:使用cudnn加速,默认为true。

举例说明:


②tf.nn.max_pool(value, ksize, strides, padding, name=None)

value:进行池化的张量,其shape为[batch, height, width, channels].

ksize:池化窗口的大小,参数为四维向量,跟输入数据的格式对应,即[batch,height,wide, channels],通常取[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1。

strides:窗口在每个维度上移动的步长,参数为4维向量,跟输入的格式相对应,一般也是[1, stride,stride, 1]。

padding:表示是否填充,与卷积层的padding意思相同,对input张量进行填充0,使得输出的结果shape改变。如果是’SAME’,则得到的输出特征图跟输入特征图形状相同,’VALID’得到的输出特征图跟输入特征图形状不相同。



发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«   2025年4月   »
123456
78910111213
14151617181920
21222324252627
282930
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接
  • RainbowSoft Studio Z-Blog
  • 订阅本站的 RSS 2.0 新闻聚合

Powered By Z-BlogPHP 1.5.2 Zero

转载请注明文章出处!!!!!