[date: 2018-03-30 16:37] [visits: 40]

深度学习-图片识别(下)

本文主要针对优达学城深度学习课程中的练习题任务4,整理练习内容,有兴趣者可结合本文内容然后按练习题实践,帮助理解。

任务四

继续之前的代码基础,为模型增加卷积神经层,主要步骤:

与之前的任务类似,但格式化逻辑有所变化,将原始数据由20000 x 28 x 28格式化为20000 x 28 x 28 x 1numpy.reshape(-1...),-1表示该维度通过其他维度推算而来

通过两个卷积层后,将张量变形为[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:

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.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基础 -> 编程实践。