开个头
很多小伙伴们很想亲近人工智能与机器学习领域,然而这个领域里的核心理论、算法、工具给人感觉都太过“高冷”,让很多小伙伴们望而却步,导致一直无法入门。
如何捅破这层窗户纸?
让高冷的不再高冷,让神秘的不再神秘!
不要怕它,伙计们,咱们以这个小系列文章零基础入门。
(这个系列的文章仅需要您稍微听说过一点点编程语言即可,比如Python)
如果是对IT这个产业了解不深的小伙伴,可以先快速浏览一下我的这两篇文章:
政安晨AI笔记:芯片极简史-了解人工智能的算力诞生https://blog.csdn.net/snowdenkeke/article/details/135768549政安晨AI笔记:计算机怎样运行——学习人工智能的起点https://blog.csdn.net/snowdenkeke/article/details/135769416 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/snowdenkeke/article/details/135769416
开始
一切都准备好之后,咱们开始!
计算机的核心部分就是计算,这些计算机做算术的速度非常快。
即使是在计算机上观看网络电视节目或听流媒体的音乐,也只涉及一次又一次地执行简单的算术指令。
在互联网上通过管道将1和0输送到计算机,重建视频帧,所使用的算术也不会比你在中学所做的加法运算复杂,这一点也许令你颇为惊奇。
计算机可以用相当快的速度,在1秒钟内进行4位数甚至10位数的相加,这也许给人留下了深刻的印象,但是这不是人工智能。
人类可能发现自己很难快速地进行加法运算,然而进行加法运算的过程不需要太多的智慧,简单说来,这只要求计算机拥有遵循基本指令的能力,而这正是计算机内的电子器件所做的事情。
但是如果尝试下面这个任务:
请描述如下3张蒙娜丽莎图片各自的艺术创意特点?
咱们作为人类智能,可以快速地对着这三张图片说出一大堆特点,并可以非常精准地分辨出这三张图片的不同。实际上,咱们人类可以快速并行地处理图像中所包含的相当大量信息,并且可以成功地识别图像中有哪些内容。
但这种任务对计算机而言,呵呵,并不是那么容易,甚至可以说是相当困难的。
但是,由于计算机速度非常快,并且不知疲倦,我们恰恰希望计算机能更好地进行求解图像识别这类问题,人工智能所探讨的一切问题就是解决这种类型的难题。
哪怕是量子计算机也基本离不开电子器件制造,因此,人类研究人工智能的任务就是找到新方法或新算法,使用新的工作方式,尝试求解这类相对困难的问题。即使计算机不能完美地解决这些问题,但是我们只要求计算机足够出色,给人们留下一种印象,让人觉得这是智能在起作用。
从一台简单的预测机开始
咱们即将要构建的这台机器超级简单,甚至您想象一下就能完成。
想象一下,一台基本的机器,接受了一个问题,做了一些“思考”,并输出了一个答案。与我们在上面的例子中进行的操作一样:我们从眼睛输入图片,使用大脑分析场景,并得出在图片中艺术创意特点的结论。
下面就是这台机器看起来的样子。
您要注意哦,计算机不是真的思考,它们只是“打包了的”计算机器,因此让我们使用更恰当的词语来形容这个过程:
一台计算机接受了一些输入,执行了一些计算,然后弹出输出。
比如,一台计算机对“3×5”的输入进行处理,这种处理也许是将乘法运算转化为相对简单的一组加法,然后弹出答案“15”。
让咱们在这种简单的级别上增强一点,用个熟悉的例子,引出此后我们将看到的更有趣的神经网络的概念。
您设想一下:我们要造一台将千米单位转化为英里单位的机器,只不过这台机器咱们使用人工智能的方式来建造。
咱们所知道的唯一线索是,两者之间的关系是线性的。这意味着,如果英里数加倍,那么表示相同距离的千米数也是加倍的,这是非常直观的,某种程度上可以认为是真理。
千米和英里之间的这种线性关系,为我们提供了这种神秘计算的线索,即它的形式应该是“英里=千米×C”,其中C为常数。
现在,我们还不知道这个常数C是多少。我们拥有的唯一其他的线索是,一些正确的千米/英里匹配的数值对示例,这些示例就像用来验证科学理论的现实世界观察实验一样,显示了世界的真实情况。
我们应该做些什么,才能计算出缺失的常数C呢?
我们信手拈来一个随机的数值,让机器试一试!让我们试着使用C=0.5,看看会发生什么情况:
此时,我们令:英里=千米×C,其中千米为100,当前,我们猜测C为0.5,这台机器得到50英里的答案。
鉴于我们随机选择了C=0.5,这种表现还算不错。
但是,上述表格中的真实示例告诉我们(我们实际测量的),答案应该是62.137,因此我们知道这是不准确的,我们少了12.137。
这是计算结果与我们列出的示例真实值之间的差值,是误差。即:误差值=真实值-计算值=62.137-50=12.137。
下一步,我们将做些什么呢?
我们知道错了,并且知道差了多少。我们无需对这种误差感到失望,我们可以使用这个误差,指导我们得到第二个、更好的C的猜测值。
再看看这个误差值。我们少了12.137。
由于千米转换为英里的公式是线性的,即英里=千米×C,因此我们知道,增加C就可以增加输出。
让我们将C从0.5稍微增加到0.6,观察会发生什么情况:
现在,由于将C设置为0.6,我们得到了英里=千米×C=100×0.6=60,这个答案比先前50的答案更好。我们取得了明显的进步,现在,误差值变得更小了,为2.137。这个数值甚至可能是我们很乐于接受的一个误差值。
这里,很重要的一点是,我们使用误差值的大小指导如何改变C的值。
A 我们希望输出值从50增大一些,因此我们稍微增加了C的值。
B 我们不必尝试使用代数法计算出C需要改变的确切量,让我们继续使用这种方法改进C值。
如果你还不能被我说服,还是认为计算出确切的答案才够简单,那么,请记住,更多有趣的问题是没有一个简单的数学公式将输出和输入关联起来的。这就是我们需要诸如神经网络这样相对成熟而复杂的方法的原因。
让我们再次重复这个过程。输出值60还是太小了。我们再次微调C,将其从0.6调到0.7。
Opps,过犹不及,结果超过了已知的正确答案。
先前的误差值为2.137,现在的误差值为-7.863,这个负号告诉我们,我们不是不足,而是超调了。
请记住上面的公式,误差值等于真实值减去计算值,如此说来,C=0.6比C=0.7好得多,我们可以就此结束这个练习,欣然接受C=0.6带来的小小误差,但是,让我继续向前走一小段距离,我们为什么不使用一个较小的量,微调C,将C从0.6调到0.61呢?
这比先前得到的答案要好得多。
我们得到输出值61,比起正确答案62.137,这只差了1.137。
因此,最后的这次尝试告诉我们,应该适度调整C值,如果输出值越来越接近正确答案,即误差值越来越小,那么我们就不要做那么大的调整。
使用这种方式,我们就可以避免像先前那样得到超调的结果,同样,读者无需为如何使用确切的方式算出C值而分心,请继续关注这种持续细化误差值的想法,我们建议将修正值取为误差值的百分比。
直觉上,这是正确的:大误差意味着需要大的修正值,小误差意味着我们只需要小小地微调C的值。无论你是否相信,我们刚刚所做的,就是走马观花地浏览了一遍神经网络中学习的核心过程。
我们训练机器,使其输出值越来越接近正确的答案,这值得读者停下来,思考一下这种方法,我们并未像在学校里求解数学和科学问题时所做的一样一步到位,精确求解问题。
这样,我们尝试得到一个答案,并多次改进答案,这是一种非常不同的方法,一些人将这种方法称为迭代,意思是持续地、一点一点地改进答案。
所有有用的计算机系统都有一个输入和一个输出,并在输入和输出之间进行某种类型的计算,神经网络也是如此。
当我们不能精确知道一些事情如何运作时,我们可以尝试使用模型来估计其运作方式,在模型中,包括了我们可以调整的参数。如果我们不知道如何将千米转换为英里,那么我们可以使用线性函数作为模型,并使用可调节的梯度值作为参数。
改进这些模型的一种好方法是,基于模型和已知真实示例之间的比较,得到模型偏移的误差值,调整参数。
咱们已经知晓了一个最简单的预测器,这是理解人工智能的神经网络基础。
神经元——大自然的计算机
我们曾表示,虽然一些计算机拥有大量的电子计算元件、巨大的存储空间,并且这些计算机的运行频率比肉蓬蓬、软绵绵的生物大脑要快得多,但是即使是像鸽子一样小的大脑,其能力也远远大于这些电子计算机,这使得科学家们对动物的大脑迷惑不解。
现在小伙伴们将注意力转向架构的不同。
传统的计算机按照严格的串行顺序,相当准确具体地处理数据,对于这些冰冷坚硬的计算机而言,不存在模糊性或不确定性。
而另一方面,动物的大脑表面上看起来以慢得多的节奏运行,却似乎以并行方式处理信号,模糊性是其计算的一种特征。
让我们来观察生物大脑中的基本单元—神经元。
虽然神经元有各种形式,但是所有的神经元都是将电信号从一端传输到另一端,沿着轴突,将电信号从树突传到树突。
然后,这些信号从一个神经元传递到另一个神经元。这就是身体感知光、声、触压、热等信号的机制。来自专门的感觉神经元的信号沿着神经系统,传输到大脑,而大脑本身主要也是由神经元构成的。
一般说来,能力非常强的人类大脑有大约1000亿个神经元。
一只果蝇拥有约10万个神经元,能够飞翔、觅食、躲避危险、寻找食物以及执行许多相当复杂的任务。10万个神经元,这个数字恰好落在了现代计算机试图复制的范围内。一只线虫仅仅具有302个神经元,与今天的数字计算机资源相比,简直就是微乎其微!但是一只线虫能够完成一些相当有用的任务,而这任务对于尺寸大得多的传统计算机程序而言却难以完成。
其中有什么秘密吗?
生物的大脑要慢得多,并且比起现代计算机,其计算元件相对较少,但是为什么生物的大脑却有如此能力呢?大脑的全部功能(例如意识)仍是一个谜,但是关于神经元能够使用不同方式进行计算,也就是不同的求解问题的方式,人类掌握的知识已经足够我们使用了。
我们来看看一个神经元是如何工作的:
它接受了一个电输入,输出另一个电信号。这看起来,与我们先前所观察的分类或预测的机器一模一样,这些机器也是接受了一个输入,进行一些处理,然后弹出一个输出。
因此,我们可以与以前一样,将神经元表示为线性函数吗?
虽然这是个好主意,但是不可以这样做,生物神经元与简单的线性函数不一样,不能简单地对输入做出的响应,生成输出。
它的输出不能采用这种形式:输出=(常数*输入)+(也许另一常数)。
观察表明,神经元不会立即反应,而是会抑制输入,直到输入增强,强大到可以触发输出。
你可以这样认为,在产生输出之前,输入必须到达一个阈值。就像水在杯中—直到水装满了杯子,才可能溢出,直观上,这是有道理的—神经元不希望传递微小的噪声信号,而只是传递有意识的明显信号。下图说明了这种思想,只有输入超过了阈值(threshold),足够接通电路,才会产生输出信号。
虽然这个函数接受了输入信号,产生了输出信号,但是我们要将某种称为激活函数的阈值考虑在内,在数学上,有许多激活函数可以达到这样的效果,一个简单的阶跃函数可以实现这种效果。
你可以看到,在输入值较小的情况下,输出为零,然而,一旦输入达到阈值,输出就一跃而起。
具有这种行为的人工神经元就像一个真正的生物神经元。
科学家所使用的术语实际上非常形象地描述了这种行为,他们说,输入达到阈值时,神经元就激发了,我们可以改进阶跃函数。
下图所示的S形函数称为S函数(sigmoid function),这个函数,比起冷冰冰、硬邦邦的阶跃函数要相对平滑,这使得这个函数更自然、更接近现实。
我们将继续使用这种平滑的S形函数制作神经网络,虽然人工智能研究人员还使用其他外形类似的函数,但是S函数简单,并且事实上非常常见,因此S函数对我们非常重要。
S函数,有时也称为逻辑函数:
这个表达式乍看来比较可怕,其实也是“纸老虎”,字母e是数学常数2.71828 ……,这是一个非常有趣的数字,出现在各种数学和物理学领域,我使用省略号的原因是,这是一个无限不循环小数。
这样的数字有一个奇特的名字—超越数(transcendental number)。
这很有趣,很好玩吧,但是出于我们的目的,你可以把它当作2.71828。
上面那个看起来有点可怕的函数先对输入x取反,计算出e的-x次方,然后将所得到的结果加1,得到1+e -x;
最后,对整个结果取倒数,也就是1除以1+e -x,做为输出值y给出。这就是上面那个看起来有点可怕的函数,它对输入的x进行操作,然后给出输出值y。因此,这没有那么可怕。
出于兴趣,由于任何数的0次方都等于1,因此当x为0时,e -x为1。因此y变成了1/(1+1),为1/2。
此时,基本S形函数在y=½时,对y轴进行切分,我们使用这种S函数,而不使用其他可以用于神经元输出的S形函数,还有另一个非常重要的原因,那就是,这个S函数比起其他S形函数计算起来容易得多,在后面的实践中,我们会看到为什么。
让我们回到神经元,并思考我们如何建模人工神经。
小伙伴们要认识到的第一件事情是生物神经元可以接受许多输入,而不仅仅是一个输入,刚才,我们观察了布尔逻辑机器有两个输入,因此,有多个输入的想法并不新鲜,并非不同寻常。
对于所有这些输入,我们该做些什么呢?
我们只需对它们进行相加,得到最终总和,作为S函数的输入,然后输出结果。这实际上反映了神经元的工作机制。
下图说明了这种组合输入,然后对最终输入总和使用阈值的思路。
如果组合信号不够强大,那么S阈值函数的效果是抑制输出信号。
如果总和x足够大,S函数的效果就是激发神经元。
有趣的是,如果只有其中一个输入足够大,其他输入都很小,那么这也足够激发神经元。
更重要的是,如果其中一些输入,单个而言一般大,但不是非常大,这样由于信号的组合足够大,超过阈值,那么神经元也能激发。
这就带来了一种直观的感觉,即这些神经元也可以进行一些相对复杂、在某种意义上有点模糊的计算。
树突收集了这些电信号,将其组合形成更强的电信号,如果信号足够强,超过阈值,神经元就会发射信号,沿着轴突,到达终端,将信号传递给下一个神经元的树突。
下图显示了使用这种方式连接的若干神经元。
需要注意的一点是,每个神经元接受来自其之前多个神经元的输入,并且如果神经元被激发了,它也同时提供信号给更多的神经元。
将这种自然形式复制到人造模型的一种方法是,构建多层神经元,每一层中的神经元都与在其前后层的神经元互相连接。
下图详细描述了这种思想:
你可以看到三层神经元,每一层有三个人工神经元或节点。
你还可以看到每个节点都与前一层或后续层的其他每一个节点互相连接。
但是,这看起来很酷的体系架构,哪一部分能够执行学习功能呢?
针对训练样本,我们应该如何调整做出反应呢?
有没有和先前线性分类器中的斜率类似的参数供我们调整呢?
最明显的一点就是调整节点之间的连接强度。
在一个节点内,我们可以调整输入的总和或S阈值函数的形状,但是比起简单地调整节点之间的连接强度,调整S阀值函数的形状要相对复杂。如果相对简单的方法可以工作,那么请坚持这种方法!
下图再一次显示了连接的节点,但是这次在每个连接上显示了相关的权重,较小的权重将弱化信号,而较大的权重将放大信号。
此处,我需要解释一下权重符号旁边的有趣小数字(即下标),简单说来,权重w2,3与前一层节点2传递给下一层的节点3的信号相关联,因此,权重w1,2减小或放大节点1传递给下一层节点2的信号,为了详细说明这种思路,下图突出显示了第一层和第二层之间的两条连接。
你可能有充分的理由来挑战这种设计,质问为什么必须把前后层的每一个神经元与所有其他层的神经元互相连接,并且你甚至可以提出各种创造性的方式将这些神经元连接起来。
我们不采用创造性的方式将神经元连接起来,原因有两点,第一是这种一致的完全连接形式事实上可以相对容易地编码成计算机指令,第二是神经网络的学习过程将会弱化这些实际上不需要的连接(也就是这些连接的权重将趋近于0),因此对于解决特定任务所需最小数量的连接冗余几个连接,也无伤大雅。
这意味着,随着神经网络学习过程的进行,神经网络通过调整优化网络内部的链接权重改进输出,一些权重可能会变为零或接近于零。
零或几乎为零的权重意味着这些链接对网络的贡献为零,因为没有传递信号。
零权重意味着信号乘以零,结果得到零,因此这个链接实际上是被断开了。
虽然比起现代计算机,生物大脑看起来存储空间少得多,运行速度比较慢,但是生物大脑却可以执行复杂的任务,如飞行、寻找食物、学习语言和逃避天敌。相比于传统的计算机系统,生物大脑对损坏和不完善信号具有难以置信的弹性。由互相连接的神经元组成的生物大脑是人工神经网络的灵感来源。