天天看点

带你学AI(二)

人工智能的Hello World--入门

不管你学的是什么语言,第一个程序肯定是Hello World。

从在屏幕上打出这行字开始,你就进入了这个语言的世界。

如果你写的是java,那么代码就是

System.out.println("Hello World!");           

复制

如果你是用python写的,那么就是

print('Hello World!')           

复制

但如果你写的是人工智能,那么第一个需要学会写的程序是什么呢?

MNIST

如果你对AI有所了解,或者学习过深度神经网络,那么对MNIST应该不陌生。

MNIST是一个数据集,它不包含任何代码逻辑,只包含两部分

· 一堆 28 * 28 的手写图片

· 对应每张图片的一个标签

因为这个数据集的数据足够简单,所以它经常被用来作为AI入门的工具。它的每一张图片都归一化到了28x28的大小,而且只有灰度值,是单通道数据。

通常来说,一张jpg图片的每一个像素都有RGB三种色值,我们也称之为3通道。如果一张图片只有黑色和白色,并且没有灰度的话,那么我们用1跟0就可以描述每个像素点的黑或者白了。

MNIST就是这么一个数据集,如果你把它的每一张图片数据转成jpg保存下来的话就像下面这张图片一样。

带你学AI(二)

标签是和每一张图片对应的,比如对应上面的图片,从MNIST里取出来的标签是

label[4]{5, 0, 4, 1}           

复制

我们要写的第一个人工智能Hello World,就是用MNIST数据集来实现的。

第一个Hello World

人工智能做的事情基本可以分为两个,分类和预测。

对于MNIST数据集来说,我们想要写一个AI网络,这个网络能够自动识别每一张图片的数字是什么。网络的输入是28x28像素的图片,输出则是一个长度10的浮点数组。

这里思考个问题,为什么输出是一个长度10的数组,而不是单个值?

其实对于分类问题都是这样的,AI最终输出的是一个概率分布,而不是一个直接的分类结果。虽然说我们也可以通过代码技巧让最终结果只有一个值,但明白这一点很关键,就是AI的输出是一个概率。

具象点地解释,假设我们把一张图片给AI进行分类,它的输出假设是下面这样子

[0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0.8,]

AI认为这张图片有10%的概率是0,10%的概率是1,还有80%的概率是9。这就是为什么AI的输出是一个10维向量的原因了。

说完了输出和输出,还缺两个东西才能构成一个AI网络,分别是

· 网络结构

· 评价函数/损失

评价函数

对于很多初学者来说评价函数是个很难的点,学习它的过程中涉及很多高等数学知识。但对于MNIST分类网络来说不需要太高深的东西,只要能明白一些基本的加减乘除就行了。

什么是评价函数呢,有些材料把它称为cost,也有叫lost的。其实他们都在描述同一个问题,就是网络分类结果跟正确结果之间的误差。

神经网络的训练是这么个过程,有点像隔壁邻居的孩子学钢琴。刚开始学的时候弹的一塌糊涂,一个音都没弹对。这个时候邻居孩子弹出来的曲子跟正确的曲子之间会有一个误差,我们就可以把这个误差认为是评价函数,或者也可以叫损失。

每弹完一次,邻居家长对孩子弹的曲子做一个评价,根据评价结果对孩子做出不同的惩罚。错的太多的话就加大惩罚力度,错的少的话就小力度惩罚。如果弹对了那惩罚为0。

一个AI网络的训练过程就是这么回事。通过不断地缩小网络输出和正确值之间的误差来完成训练。最终达到目标,神经网络的预测结果跟实际结果一致。

基于MNIST数据集的评价函数计算的是预测结果和标签之间的差距,下面的数据第一行是预测结果,第二行是标签

pred: [0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0.8,]

label: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1,]

对于这种数据,有一种专门的评价方法叫做交叉熵。交叉熵本身是属于信息论中的一种手段,用来评价两个概率区间的差异。那么当然它也可以用来对AI的分类结果和正确结果之间的差异性进行评价。我们先不要去关心交叉熵的数学实现是怎样的,先记住它计算的结果表明的是 pred和 label之间有多不一样。

网络结构

深度学习的网络结构千变万化。每年在深度学习领域的论文有几百上千篇,几乎每一篇都有一个不同的网络结构。但总的来说,不管是什么网络都由基础的几个构成

· 全连接

· 卷积

· 循环卷积

在MNIST数据集上我们只需要用到全连接网络,更复杂的网络虽然能带来更准确的结果,但同时也增加了相应的内存和空间开销。作为一个Hello World标准的例子,全连接足够我们用来练手了。