前言
写了两周基金申请报告也是醉了,说什么基金申请下来后我们出国交流就不用钱啦!多么拙劣的谎言,我只想中一篇论文达到毕业要求,然后去实习就行。今天又吐槽我说我晚上出勤不够,您真不愧是大学城最努力的老师。这都还没毕业,实验室的同学们都已经过上了公务员那种朝九晚五的生活。继续学习卷积神经网络,看看怎么用 Tensorflow 实现多分类问题。
Tensorflow 模型
这个实验的要求是对手势进行识别,分析图片中的手势表示的是哪个数字(0~6)。手势图像如下所示:
首先载入需要用到的包和数据集,对数据进行简单的预处理:
1 | import math |
创建 placeholders
需要给数据创建 placeholders,在运行 session 的时候就可以喂入数据。使用 None
作为 batch size,这样就可以在后面的时候比较灵活地设置小批量的大小:
1 | def create_placeholders(n_H0, n_W0, n_C0, n_y): |
初始化参数
网络为两层卷积神经网络,分别初始化每一层的权值 $W1$ 和 $W2$,也就是滤波器 。其中 $W1$ 包含 8 个大小为 4 的 3 通道滤波器,$W2$ 包含 16 个大小为 2 的 8 通道滤波器:
1 | def initialize_parameters(): |
前向传播
在 Tensorflow 中,提供了以下函数可以用来快速构建卷积神经网络:
tf.nn.conv2d(X, W1, strides=[1,s,s,1], padding='SAME')
:给定输入 $X$ 和一组滤波器 $W1$,该函数回使用 $W1$ 中的滤波器和 $X$ 进行卷积运算,第三个参数指定了 $X$ 每个维度的卷积步长。tf.nn.max_pool(A, ksize=[1,f,f,1], strides=[1,s,s,1], padding='SAME')
:给定输入 A,滤波器大小为 f,使用最大池化进行运算。tf.nn.relu(Z1)
:对 Z1 中的每个元素进行 ReLU 运算。tf.contrib.layers.flatten(P)
:给定输入 P,将其变平(flatten)成一维向量。如果 P 中包含 batch-size 则变成形状为 [batch_size, k] 的张量。tf.contrib.layers.fully_connected(F, num_outputs)
:给定变平的输入,返回全连接神经网络层计算的输出,该层自动初始化权值。
卷积神经网络的前向传播主要流程为:CONV2D -> RELU -> MAXPOOL -> CONV2D -> RELU -> MAXPOOL -> FLATTEN -> FULLYCONNECTED
,每一层的参数配置如下所示:
- Conv2D:步长为 1,零填充为 SAME 卷积;
- ReLU;
- Max pool:滤波器大小为 8,步长为 8;
- Conv2D:卷积步长为 1,零填充为 SAME 卷积;
- ReLU;
- Max pool:滤波器尺大小为 4,步长为 4
- 将前面的输出变平(flatten);
- FULLYCONNECTED (全连接) 层:此处不需要使用 softmax 函数,在 Tensorflow 中,softmax 和代价函数被写成了一个单独的函数,所以可以直接在全连接层的输出上计算代价。
1 | def forward_propagation(X, parameters): |
计算代价
tf.nn.softmax_cross_entropy_with_logits(logits=Z3, labels=Y)
:计算 softmax 交叉损失,该函数包含了 softmax 函数。tf.reduce_mean
:计算张量每个维度的均值,用来计算整体的代价。
1 | def compute_cost(Z3, Y): |
模型
整体的模型包含以上几个步骤,最后需要创建优化器,然后运行 session 迭代数据集 num_epochs 次,在每个最小批量上运行优化器。
1 | def model(X_train, Y_train, X_test, Y_test, learning_rate=0.009, |
运行以下代码,将模型训练 100 个 epoch,同时每 5 个 epoch 输出模型的代价:
1 | _, _, parameters = model(X_train, Y_train, X_test, Y_test) |
最后模型在训练集上的准确度能达到 94%,在测试集上能达到 78%。模型的方差比较高,还可以继续调节超参数和使用正则项提高模型的性能。
总结
投出去的论文的实验也是用 Tensorflow 实现的,Tensorflow 确实强大,但是如果不是很熟悉就想用还是有点难,当时遇到一些小问题都得花半天时间解决,看来还需要多学习一下,多看看文档。
参考文献
- 吴恩达. DeepLearning.