最近在学习tensorflow,因为有项目需要使用深度学习。
但是本人又是重度windows OS的依赖者,所以就在windows下写相关代码。我主要是把一些心得分享给大家,然后有一些坑帮大家排一排。
大家在动手实践之前,最好能把神经网络的概念和工作原理搞明白一些,推荐一些课程和书籍,Andrew Ng的课程,有兴趣的可以听听李飞飞老师的CV课程,同时书的话可以参考周志华老师的西瓜书,我自己也有《机器学习实践》。
从理论到应用,都是可以了解下的,动起手来会发现,脑子里有一个框架。
开始前,最重要的就是环境了。
我们需要的不多:Win10 OS,pycharm,Anaconda3。
windows是因为我本身就离不开,所以就在windows上了(能狠心把机子刷成ubuntu的,我还是觉得在unix架构的系统上跑实验比较舒服);pycharm的话,因为jetbrain那一套对学生蛮友好的,学校邮箱激活了之后,都可以免费用;anaconda3是因为有一套包,集成了,我比较懒,用起来也没啥问题。
当我们用的时候,下载下来如果没问题的话,就有python3.6了,然后把我们需要的包pip一下就行了。
主要是要用到tensorflow和numpy
我自己在学习的过程中,非常感谢莫烦的视频教程,但是由于我自己环境不同,理解也有些自己的想法,所以记录下这篇博文。
莫烦教程link:https://morvanzhou.github.io/

大家都说TF比较难搞,我自己就是尝试下看看,当一段时间的TFboy就好了。刚好windows下,tf只要装个包就能用了,所以就跟着教程试试看了。
其实,我问了不少人,做deep是用TF还是pytorch好,大家都会说pytorch友好点,因为pytorch是动态的网络。我思考了很久,tensorflow到底可以被类比为什么呢?我想了下,就像是玩具火车的轨道。只有全部搭建完毕了,小火车才能跑起来,如果中间出了问题,就有如代码出了bug,那小火车就跑不动了。当然,轨道的搭建也有好有坏,搭的好,就能有更好的效果,小火车跑得快,搭的不好,火车也能跑,大不了就是慢些。
有了这个思维框架之后,开始这部分的内容就简单多啦。
很多人可能会在运行TF(windows+pycharm)的时候,遇到这个问题,但是这个无所谓。。。我在ubuntu虚拟机下面就没这个问题,ignore it!~
(这里就尽量避免基础知识的讲解了,对于NN的概念,包括连接主义,仿生学怎么衍生,以及定义的问题,晚上有很多大拿都写的不错,大家可以自行选取参考呢~)
那么如何定义一个自己的神经网络层呢?这个比较重要!
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size]))
#随机变量比全部为零好一些,生成一个变量矩阵
biases = tf.Variable(tf.zeros([1,out_size])+0.1)
#偏置不推荐为0
Wx_plus_b = tf.matmul(inputs,Weights)+biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
如上代码,每一层都要有输入,就是inputs,然后定义输入和输出的大小,最后就要确定这层的激活函数。前三个参数比较好理解,第三个参数,从字面意思理解,就是“激活”。就像我们高中学生物的时候,神经递质乙酰胆碱,当够了之后,就传递到下一层了,差不多这个意思!一般我们用到的激活函数,大概就是relu,tanh这样了。很多教程上推导都是按照sigmoid教的,但是这个只是给大家个例子而已,真的在实操的时候,基本上都是前两种激活函数,sigmoid会出现梯度消失的问题,基本弃置啦。
接下来,就是里面的权重和偏置的定义了。我们可以理解每一个神经元,都是个线性函数,然后通过不同线性函数的组合,就变成非线性了。已经有人证明了,通过线性函数的组合,可以无限逼近任何函数了(?如果我记得没错的话)。每次更新的时候,就是对权重和偏置进行更新,求到最后“最合适”的解。
prediction = add_layer(xs,784,10,activation_function=tf.nn.softmax)
如上代码就是定义一层的神经网络,10个结点,最后以softmax作为结果的输出。(senario是MNIST)
l1 = add_layer(xs,784,10,activation_function=tf.nn.tanh)
#隐层使用relu6或者tanh都没问题,但是relu的话可能会产生梯度消失的问题,至少result不work
prediction = add_layer(l1,10,10,activation_function=tf.nn.softmax)
#rediction = add_layer(xs,784,10,activation_function=tf.nn.softmax)
如果要写两层,就让他们接起来就行了,中间的隐层激活函数输出用tanh就好了。这里注意一下,我一开始用的relu,不知道为啥就有问题,我猜可能是小于0的时候梯度消失了,就不更新了。(只是猜想,至少tanh是work的)
但是只用一层或者两层的单纯的神经网络,结果很一般,用一层的结果大概能到0.86,如果用两层可能只有0.82了(没调参数),之后我们来看看用CNN能不能有更好的结果。
如上是使用cnn来进行MNIST预测的例子(自己画的图!不是偷图的!)。
首先输入一个sample,是28*28,共784个像素点,其中由于其样本是黑白的,所以只有1的“深度”。然后经过5*5的,步长为1的卷积操作,然后再进行池化,将深度从1增加到32,这是conv1;然后同理,再进行卷积,增加深度到64,这是conv2;然后将其序列化之后输入1024个结点的隐层(layer1)之后,在输入layer2中,最后经过softmax进行结果one-hot的输出。
基于CNN的手写数字数据集的识别的话,使用批处理大小为100进行训练,第一轮acc大概在0.1左右,第二轮就可以上升到0.65左右,大概在5轮之后就可以提升到0.9,经过一段时间的训练之后,最高应该是能到0.985的样子,但是再要提升可能就比较困难了。(这里注意,cnn由于本身网络比较庞大,中间的隐层节点数达到了1024个,因此可能需要较高的算力,在训练的时候如果再干别的事情,电脑可能会卡死了)
具体的代码我已经放在github上了,大家欢迎去点击(如果能给个star就好了 星星眼 码字不易)!本节中提到的都有源码,因为原教程中貌似有些code没开源,所以我自己根据理解实现了一下。以后继续学习还会更新哒!
*******************************************************************
https://github.com/chenligeng/Tensorflow-StartUp-Tutorials
*******************************************************************
以上。