欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

笔记——TensorFlow and deep learning, without a PhD

程序员文章站 2022-06-06 13:59:10
...

看了一篇用tensorflow搭建神经网络的教程《TensorFlow and deep learning, without a PhD》,链接为TensorFlow and deep learning, without a PhD

这个教程写的很好,能教你实实在在搭建一个神经网络和简单的卷积神经网络,教程中有代码,很详细清楚,适合入门。这是我的笔记,仅仅作为个人备忘。

几个概念:

1、“Broadcasting”是Python和numpy中使用的一个标准技巧。它使得具有不兼容维度的矩阵可以进行归一化操作。”Broadcasting add”表示:如果你想将两个矩阵相加,但是你不能加,因为两个矩阵的维度不一致,那就尝试去复制较小的一个使得他们能够相加(没太懂,原话为try to replicate the small one as much as needed to make it work)。

2、“tensor”(“张量”)像一个具有任意维数的矩阵。一个一维张量是向量,一个2维张量是矩阵,张量还可以有3维4维5维等等。

笔记

1、当你看到你的准确率曲线突然下降(如下图),并且控制台输出的交叉熵的数值为NaN时,你应该是在计算log(0)或者是类似的运算,可以查找原因进行解决。

笔记——TensorFlow and deep learning, without a PhD

2、learning rate decay

如果你发现训练后期,准确率曲线波动特别大,特别不稳定(如下图),一个原因可能是学习的步长太大,即learning rate太大,使得到达极小点又反弹回来了。可以使用变步长学习,前期步长大点,后期步长减小。
Here is the formula for exponential decay:
lr = lrmin+(lrmax-lrmin)*exp(-i/2000)

笔记——TensorFlow and deep learning, without a PhD

3、过拟合与dropout

当你的网络出现过拟合的时候,你需要“dropout”。就是在每次训练迭代的过程中,你从原始神经网络中随机去掉一部分的神经元。你可以用pkeep表示保留的神经元的比例,一般取50%~75%,然后按照比例在每次训练迭代的时候,随机地去除一部分神经元,并且去除与之相关的w和b。这样,在训练的每次迭代中,都会有不同的神经元被你抛弃(并且你必须按比例地增强剩余神经元的输出,以确保对下一层的**不会移动)。进行测试时,所有的神经元都放回(即pkeep=1)。TensorFlow提供了一个drop函数作用于一层神经元的输出,它会随机的使一部分输出变为0,并且按1/pkeep 的比例增强剩余输出,该函数为tf.nn.dropout(y,pkeep)。如,两层的神经网络,第一层**函数为relu,第二层**函数为softmax,不用dropout的语句为:

y1=tf.nn.relu(tf.matmul(x,w1)+b1)
y2=tf.nn.softmax(tf.matmul(y1,w2)+b2)

改用dropout的语句为:

#feed in 1 when testing, 0.75 when training
pkeep=tf.placeholder(tf.float32)
y1=tf.nn.relu(tf.matmul(x,w1)+b1)
y1d=tf.nn.dropout(y1,pkeep)
y2=tf.nn.softmax(tf.matmul(y1d,w2)+b2)

dropout是出现过拟合是使用的常规技巧,但是不一定能解决过拟合的情况,过拟合有更深层的根源。过拟合的意思就是训练集上的准确率比测试集上的准确率高很多。造成过拟合的原因有过多的神经元、数据数量不够大、网络不好等。

4、卷积神经网络

平面图片是二维的,如果将其变成一个向量来作为输入的话,并不是一个好方法。二维的图片里面包含了形状的信息,如果认为将其变为一个向量的话,图片中本身的形状信息就被丢失了。有一种神经网络——卷积神经网络,能够较好地利用形状信息。

卷积神经网络需要用到函数
tf.nn.conv2d(input,filter,strides,padding,use_cudnn_on_gpu=None,data_format=None,name=None)。相关参数解释为:input是输入数据张量[batch, in_height, in_width, in_channels],即【数量,输入数据的高度,输入数据的宽度,输入数据的通道数】;filter是w,[filter_height, filter_width, in_channels, out_channels];strides是一个整数列表,长度为4的一维矩阵,格式为[1,stride_height,stride_width,1],中间两个值指input的每一个维度的滑动窗格的步幅,代表了”max-pooling”;padding是字符串类型,可选值有“SAME”和“VALID”,我只用过“SAME”。

5、挑战准确率达到99%

比较好的神经网络的设计是:使用一个受限制的网络,给它的*度多一点(比如设计滤波器的尺寸稍大、每层输出的通道数稍多,下面例子中的改进就是give the network more degrees of freedom),并且使用dropout保证不会过拟合。(A good approach to sizing your neural networks is to implement a network that is a little too constrained, then give it a bit more degrees of freedom and add dropout to make sure it is not overfitting. This ends up with a fairly optimal network for your problem.)

举个例子来说,我们之前用于手写数字识别的卷积网络中,第一层卷积网络的输出是4类,这个4类可能对于我们这个问题来说并不够。因为手写数字模型的类型多于4种。如果我们尝试将滤波器的大小和每层网络的输出类别增大,看看效果会不会好。网络设计由下面第一个图更改为第二个图:

笔记——TensorFlow and deep learning, without a PhD

笔记——TensorFlow and deep learning, without a PhD

运行结果表明,在该问题中效果变好了,准确率由98.9%提升到了99.1%,如果再加入dropout,准确率会提升到99.3%。

相关标签: 神经网络