深度学习-图片识别(下)
本文主要针对优达学城深度学习课程中的练习题任务4,整理练习内容,有兴趣者可结合本文内容然后按练习题实践,帮助理解。
任务四
继续之前的代码基础,为模型增加卷积神经层,主要步骤:
- 读取数据,重新格式化
与之前的任务类似,但格式化逻辑有所变化,将原始数据由
20000 x 28 x 28
格式化为20000 x 28 x 28 x 1
,numpy.reshape(-1...)
,-1表示该维度通过其他维度推算而来
- 卷积层
- 第一个卷积层weights为
[5 x 5 x 1 x 16]
,步长为2,得到的输出形状为[16 x 14 x 14 x 16]
,对卷积结果使用ReLU激活函数- 第二个卷积层weights为
[5 x 5 x 16 x 16]
,步长2,得到的输出形状为[16 x 7 x 7 x 16]
,对卷积结果使用ReLU激活函数
- 隐藏层
通过两个卷积层后,将张量变形为
[16 x 784]
,通过一个64节点的隐藏层,ReLU激活后再通过输出层进行分类
继上述主要步骤后,开始使用SGD算法训练模型1001步,最终测试集在模型上的准确率大约90%。
任务作业
作业一
使用max_pool
替换代码中的卷积操作,主要代码:
# 将第二个卷积层,改为max_pool方式
# ksize即核大小[1, width, height, 1]
conv = tf.nn.max_pool(hidden, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
hidden = tf.nn.relu(conv)
作业二
尝试使用丢弃法或学习速率衰减,使模型表现更出色,主要代码:
# 学习速率衰减
global_step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(0.05, global_step, 500, 0.7, staircase=True)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
# 不知在哪层嵌入丢弃法合适
conv = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1], padding='SAME')
hidden = tf.nn.relu(tf.nn.dropout(conv, 0.5) + layer1_biases)
添加上述代码后,训练5001步,发现模型的损失始终保持在0.5左右,难以继续收敛,最终测试集的正确率约92%,需要继续调整模型神经层,或者超参,感觉这个是学习过程中最难的部分…
本以为课程练习的6个任务都是字母图片识别,才将文章拆分为两部分,但后面才发现第5、6个练习任务不是字母图片识别,所以图片识别的练习题就暂时告一段落。
疑惑
在深度学习课程的练习题(1-4)中,对部分代码有过疑惑,把有印象的做个总结。
线性代数
由于时间相隔几年,线性代数知识忘的差不多,有时难以理解矩阵操作以及其背后的含义,在tensorflow最常见的输入矩阵 x 权重矩阵 + 偏置
,实际就是表达输入与输出的线性关系。
numpy
为学习机器学习课程,Python都是现学的,更别说numpy这个库了,以及它所代表的编程概念。每次都是在代码中看到一个方法使用,然后去查一下文档,但由于缺乏概念,只是一知半解,列举一下练习题中出现的API:
- np.arange
labels = (np.arange(num_labels) == labels[:, None]).astype(np.float32)
format中有用到
np.arange()
函数,在这里只是生成[0 ~ num_labels)之间的自然数,但整个语句对于新手就没那么友好了,其中labels[:, None]
作用是为lables添加一个维度,写成labels[:, numpy.newaxis]
可能会比较好理解,在这里可等价为labels.reshape(labels.shape[0], 1)
。
==
运算:
[0, 1, 2]
[[1],
[1],
[2]]
== 运算之后
[[False, True, False, False],
[False, True, False, False],
[False, False, True, False]]
- np.random.shuffle
打乱数组顺序,多维的话根据一维进行打乱
- np.sum & np.argmax
np.argmax
获取数组某维度的最大值索引,np.sum
累加数组的某维度
def accuracy(predictions, labels):
return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) / predictions.shape[0])
# np.argmax([[0, 1, 0, 0], [0, 0, 1, 0]], 1) => [1, 2]
# [1, 2] == [1, 1] => [True, False]
# np.sum([True, False]) => 1
tensorflow
没有tensorflow基础就开始学习机器学习,但由于过程中用到的都是比较高层API,勉强能理解,但主要困难在于直接写出代码,以及超参选择。
卷积部分的张量形状改变,多维度在头脑中的具象化花了一些时间。
why
这部分是最大的疑惑,多少层合适?隐藏层多少节点合适?为什么卷积有效?dropout放在哪层?怎么拼凑整个神经网络…
总结
在公众号文章中了解到Google机器学习速成课,纯属兴趣,捣鼓了一波,根据自己的捣鼓经验,认为针对零基础,这个学习路线并不适合。
觉得零基础正确的学习路径应该是:线代基础 -> 机器学习基础理论 -> Python基础 -> TensorFlow基础 -> numpy基础 -> 编程实践。