开始学习TensorFlow, 看了一些文档以及教学视频,主要是周莫烦的TensorFlow入门视频 ,之前自己手写过BPNN,各种debug,费了很多事情,而且还有很多地方需要优化,想到自己还要用CNN, RNN等DNN,自己写的话, 可能性不大了,于是就打算使用深度学习框架了,准备多写几个例子加深印象。
介绍
TF属于google提出的一套graph计算框架,跟我们之前的思路不太一样,之前是导入数据,然后进行训练,测试等等,而TF事先设计好网络,然后再填充数据,这种方式的好处是设计与数据分离,不用针对具体数据,而坏处是不容易调试,因为network中的变量在没有数据之前,都还没有分配内存,还好有可视化工具tensorboard,可以很清楚的看到每个变量的shape。
TensorFlow的安装,上一篇博客已经记录了。 这一个博客主要是使用TensorFlow做一个mnist数据集的分类的例子。主要记录下,自己的学习流程。
实现部分
首先定义了添加层的函数。 每添加一个层,需要有输入, 参数权重,偏置,以及最后的输出, 当然还有激励函数。如下:
1 |
|
接着,开始构造神经网络。使用的数据集手写数字识别的mnist数据集,包含训练数据和测试数据,属于机器学习中的Hello World。数据的输入已经处理为了28*28的向量,标签是one-hot的10维的向量。 基于数据集,我们先定义一些参数:
1 | hidden_layers = 1 # 一共有多少层,这里只用了一个隐层,多层一样 |
下面就可以定义网络的结构了,TF的特点就是先设计网络,无需实际的数据。先定义输入数据和输出数据:
1 | xs = tf.placeholder(tf.float32, [None, n_input], name="input") |
使用placeholder
相当于给xs, ys
预留个位置,等后续填充数据,第二个参数是shape
,其中None
表示任何数都可以,一般是batch_size
,就是训练的数据量。 有了输入数据,下面开始添加层,这里加入一个隐含层:
1 | # 第一层,输入数据就是xs |
就上面的几行代码就可以构造好我们的神经网络了。 下面开始训练操作,一般神经网络是用BackProg来训练,然后SGD进行优化。 在TensorFlow里面,下面两行就可以了,手写的时候,写了一堆函数---:
1 |
|
到这里,我们的网络以及训练都完成了,可以把数据传进去,进行训练了,不过,在这之前,最好是加入一下测试,每轮训练完了,看看测试数据集的正确率。 也很简单,直接看看预测与实际的偏差,然后构造一个Tensor即可:
1 | ## accuracy |
到此,所有事情准备完毕,开始装数据!直接看完整的代码:
1 | #!/usr/bin/env python |
最终的结果,正确率到了94%:
1 | epoch 34 accuracy: 0.9424 |
因为网络的初始值都是随机的, 因此结果肯定不一样,有时候,初始值好的话, 可能很快就可以收敛,有时候运气不好,可能很多轮很慢,到百分之七八十,这个时候,就需要尝试了,调整学习率什么的,或者加大迭代的轮数,比如我增加到100轮,正确率到了95.2%。 最后说一个加快训练并且避免过拟合的方式: Dropout
, 道理简单来说,就是每次训练随机性的忽略一些节点的贡献,将一些节点权重设置为0,这样就会避免特别依赖某些神经元,减少过拟合。DropOut在TF里面很容易实现,在add_layer里面加入一句话即可:
1 | Wx_Plus_b = tf.nn.dropout(Wx_Plus_b, keep_prob) |
其中keep_prob
是要保留训练的比重,一般设置0.6,0.75等等,也是一个placeholder:
1 | xs = tf.placeholder(tf.float32, [None, n_input], name="input") |
在训练的时候,传入进去就ok了。 这篇主要记录了在用TensorFlow做神经网络的时候,一个大概的流程,其余基本很类似。下面的训练也会基于这样的流程。