这 是一个3
一个字迹歪斜 28x28像素 超低分辨率的3
但你的大脑把它辨认成3 一点问题也没有
我希望大家能稍微感叹一下 人脑"竟然"能如此轻而易举地完成这项工作
你看这个 这个 和这个图 我们都认作3
但他们每个图中各个像素的值是大相径庭的
你眼睛中 看到这张3时激发的光感细胞
和看到这张3时激发的细胞有着千差万别
但你大脑皮层中小小的一块处理视觉的智能区域
却居然能够把这些图像处理成相同信息
同时还能把其他的图像解释成各自不同的信息
不过 要是我现在叫你 嘿 你滴 给我写个程序
输入一个28x28像素的表格 输出一个0到9之间的个位数
来判断一个图片里到底写着哪个数字呢
好吧 这个原本轻松的工作一下就变得如登天一般难了
大家又不是山顶洞人
想必我没有必要再给大家展望一遍
机器学习和神经网络对当下和未来有多么息息相关
但假设大家对神经网络没有任何背景知识
我想来给大家介绍下神经网络究竟是什么
用视觉化的方式展示它的工作机制
把它作为一门数学 而不是单纯的网红热词来对待
这系列讲完 我希望大家能够理解神经网络为什么会是这样的结构
让大家再度听说神经网络"学习"之时 能够明白这究竟代表了什么
本期视频仅仅会介绍神经网络的结构
下一期将会讨论它的学习原理
接下来我们将会手把手搭建一个
能够识别手写数字的神经网络
这是一个用于入门的经典范例
而这里我并不会标新立异的原因
是因为这两期结束的时候
我会附上一些不错的补充学习资料
你能下载它们的代码 在自己的电脑上捣鼓
神经网络的变种非常非常之多
近些年来对于这些变种的研究更呈爆发的态势
不过在这几期入门介绍的视频中
咱们只会讨论最简单 不加料的原味版(多层感知器MLP)
我们得先理解经典的原版 才好理解功能更强大的现代变种
而且相信我 光理解原版就够咱们吃一壶的了
不过即便这最简单的版本
就已经能来识别手写数字
对于电脑而言已经很棒了
与此同时
你们也会看到神经网络有时也会有不尽如人意的地方
顾名思义 神经网络之名来源自人的大脑结构
我们来一层层剖析一下
它的神经元是什么 神经元又是如何连接起来的
目前说到神经元
我想要大家把它暂时理解成一个用来装数字的容器
装着一个0到1之间的数字
仅此而已
看例子 这个网络一开始的地方有很多神经元
分别对应了28x28的输入图像里的每一个像素
总计784个神经元
神经元中装着的数字代表对应像素的灰度值
0表示纯黑像素
1表示纯白像素
我们把神经元里装着的数 叫做"激活值"
大家可以想象这么一个画面
激活值越大 那么那个神经元就点着越亮
这么些784个神经元就组成了网络的第一层
现在我们跳到网络的最后一层
这一层的十个神经元分别代表0到9这十个数字
它们的激活值 同理都处在0到1之间
这些值表示系统认为输入的图像对应着哪个数字的可能性
网络中间还有几层"隐含层"
暂时我们就把它看做一个大黑箱
里面就进行着处理识别数字的具体工作
这个网络中 我选择加两层隐含层 每层有16个神经元
我得承认 这些设置都是随便选的
结构选择两层隐含层的理由过一会我自会来解释
而选择16个神经元无非是显得好看罢了
实际应用中 在网络的结构上 我们有很大的调整实验的余地
神经网络运作的时候
上一层的激活值将决定下一层的激活值
所以说 神经网络处理信息的核心机制正是
一层的激活值是通过怎样的运算 算出下一层的激活值的
某种程度上讲 它想模仿的是生物中神经元组成的网络
某些神经元的激发 就会促使另一些神经元激发
当前我给你展示的神经网络已经被训练好 可以识别数字了
我来解释下这是什么意思
这表示 如果你在网络输入层的784个神经元处
输入了784个代表输入图像各像素的灰度值
那么 这层激活值的图案会让下层的激活值产生某些特殊的图案
再让再下层的产生特殊的图案
最终在输出层得到某种结果
而输出层最亮的那个神经元就表示神经网络的"选择"
它认为输入图像里写着这个数字
在我介绍网络每层间如何影响 训练过程的数学原理之前
我们先讨论下 凭什么我们就觉得这种层状结构可以做到智能判断
我们在期待什么呢
我们到底期望这些中间层最好能做些什么呢
当我们人类在识别数字的时候
我们是在组合数字的各个部件
9 就是上边一个圈 右边再一竖
8 就是上边一个圈 搭着下边一个圈
4 就当能拆分成3条直线 诸如此类
在理想的情况下 我们希望倒数第二层中的各个神经元
能分别对应上一个笔画部件
这样一来 当我们输入一个9或者8这种带圈的数字时
某一个神经元中的激活值就会接近1
而且我并不特指某种样子的圈
我是希望 所有这种位于图像顶部的圆圈图案都能点亮这个神经元
这样一来 从第三层到最后一层
我们只需要学习哪些部件能组合出哪个数字即可
当然 这样一来我们就引来了更多的问题
例如 要如何识别这些部件呢
甚至哪些部件才算正确的呢
而且我还没提到上一层网络是如何影响下一层的
不过暂时请先陪我把话题讨论完
识别圆圈的任务同理可以拆分成更细微的问题
一种合理的方法便是首先识别出数字图形中更小的边
比如像1 4 7中的这种长条
就是一条长边嘛
或者把它当做几条短边组合起来的图案也可以
于是我们希望 也许网络第二层的各个神经元
就能对应上这些各种各样的短边
没准当这样子的图像输入进来的时候
它就能把所有关联短边的八到十个神经元都给点亮
接着就能点亮对应顶部圆圈和长竖条的神经元
最后就能点亮对应9字的神经元
至于咱们的网络是否真的能做到这一步
等我解释完网络如何训练 再来回头讨论吧
但这就是我们的希望
希望这种层状结构能完成的目标
更进一步讲 假如神经网络真能识别出这类边缘和图案
它就能很好地运用到其他图像的识别任务上来
甚至不光是图像识别
世界上各种人工智能的任务
都可以转化为抽象元素 一层层的抽丝剥茧
就比如说语音识别
就是要从原音频中识别出特殊的声音
组合成特定的音节
组合成单词
再组合成短语 以及更加抽象的概念
回到神经网络工作原理的话题上来
试想一下 你要设计上一层中的激活值
到底会如何决定下一层中的激活值
我们需要设计一个机制 可以把像素拼成短边
把短边拼成图案
或者把图案拼成数字 等等
这个例子里 我们来放大关注其中一个
我们来设计 让第二层中的这一个神经元
能够正确识别出图像中的这块区域里 是否存在一条边
现在我们就需要知道这个网络的参数
你应该如何调整网络上的旋钮开关
才能让它足以表示出 要么这种图案
要么别的像素图案
要么是几条边组合成圆圈的图案之类
我们需要给这个神经元和第一层所有神经元间的每一条接线
都赋上一个权重值
这些权重都不过是数字而已
然后 我们拿起第一层所有的激活值
和它们对应权重值一起 算出它们的加权和
我觉得把这些权重值看做一个表格更好理解
我会把正的权重值标记成绿色
负的标记成红色
颜色越暗 就大致表示它的权重越接近于0
现在我们如果把关注区域的权重赋为正值
而其他所有的权重值一律赋为0
这样一来 对所有的像素值取加权和
就只会累加我们关注区域的像素值了
此时如果你真的想识别出这里是否存在一条边
你只需要给周围一圈的像素赋予负的权重
这样当中间的像素亮 周围的像素暗时 加权和就能达到最大
这样计算出来的加权和可以是任意大小
但这个网络中 我们需要激活值都处在0与1之间
那么 我们就可以顺其自然把这个加权和输进某个函数
把这条实数轴挤压进0到1的区间内
其中一个叫sigmoid的函数非常常用
它又叫logistic/逻辑斯蒂曲线
简而言之 它能把非常大的负值变成接近0
非常大的正值变成接近1
而在取值0附近则是平稳增长的
所以这个神经元中的激活值
实际上就是一个对加权和到底有多正的打分
但有时 即使加权和大于0时 你也不想把神经元点亮
可能只有当和大于例如10的时候才让它激发
此时你就需要加上一个偏置值 保证不能随便激发
而我们只需要在加权和之后加上一个负10之类的数
再把它送进sigmoid压缩/映射函数即可
这个附加的数就叫做偏置
总而言之 权重告诉你这个第二层的神经元关注什么样的像素图案
偏置则告诉你加权和得有多大
才能让神经元的激发变得有意义
我们这就解说完了其中一个神经元
但这一层的每一个神经元 都会和第一层全部的784个神经元相连接
每一个的784个接线上都带着一个权重
而且每一个神经元都会在计算自己的加权和后加上自己的偏置
再通过sigmoid压缩输出自己的结果
一下子要考虑的就多起来了
这层隐含层的16个神经元
就需要总计784 x 16个权重值和16个偏置值
而且这还是单单第一层和第二层之间的连接
别的层之间的连接还有它们分别自带的权重和偏置
一套下来整个网络一共会用上将近13000个权重加偏置
相当于这个网络上有13000多个旋钮开关让你调整
从而带来不一样的结果
所以 当我们讨论机器如何学习的时候
我们其实在讲 电脑应该如何设置这一大坨的数字参数
才能让它正确地解决问题
这里有个细思极恐的思想实验
想象一下你自己手动调整这些权重还有偏置参数
让第二层识别短边 第三层识别图案
比起把网络完全当做一个黑箱 我个人觉得这么考虑更加令人满足
毕竟当网络的输出和期望出了偏差的时候
如果你一定程度上了解了这些权重和偏置的意义
那么你再尝试对结构进行修正就有出发点了
或许你的神经网络能输出正确的结果 但过程和你想象的不一样
那么 深挖权重和偏置的实际意义 就可以有效挑战你的假设
进而探索出所有可能的解决方案
顺便一提 整个函数这么写下来是不是很难懂
我这里就给大家展示个既能表示所有的连线 看着又清爽的符号表达好了
你之后学习神经网络你就会一直见到这种符号
我们把某一层中所有的激活值统一成一列向量
再把它和下一层间所有的权重放到一个矩阵中
矩阵第n行就是这一层的所有神经元
和下一层第n个神经元间所有连线的权重
这样权重矩阵和向量乘积的第n项
就是这一层所有的激活值 和下一层第n个神经元间连线权重的加权和
顺带一句 机器学习到头来和线性代数是不分家的
如果大家想更形象地理解矩阵和矩阵乘法的意义的话
不妨去看下我之前做的线代本质系列吧
特别是第三章
回到符号表达的话题
表达偏置值的时候 我们并不会把一个个值都拎出来单独讨论
相反 我们会把它们都放到一个向量里
然后把它和之前的矩阵乘法的结果相加
最后一步 我们把整个表达式用一个sigmoid包起来
所谓包起来就是指
对表达式结果向量中的每一项都取一次sigmoid
现在只要我们一写下权重矩阵和相应向量的符号
神经网络各层之间激活值的转化
就可以表达得清晰简洁明了了
这种表达也让我们写程序变得简便了许多
因为很多库在矩阵乘法方面做了十足的优化(比如屏幕里用的numpy)
还记得之前 我要叫大家把神经元看作数字的容器吗
实际上 神经元中装着的值是取决于你的输入图像的
所以我们把神经元看作一个函数才更加准确
它输入的是上一层所有的神经元的输出
而它的输出是一个0到1之间的值
其实整个神经网络就是一个函数
一个输入784个值 输出10个值的函数
不过这个函数极其的复杂
它用了13000个权重参数偏置参数
来识别特殊图案
又要循环不停地用到矩阵乘法和sigmoid映射运算
但它终究只是个函数而已
而它的复杂程度可以稍微让人安点心
如果它没这么复杂的话
我们恐怕就不大能指望它数字识别能多准了
那么 它是如何处理这项艰巨任务的
神经网络是如何通过数据来获得合适的权重和偏置的
这就是下一集的内容了
我们会继续探究这一种特殊的神经网络的运作方式
虽说又到了提醒大家赶紧订阅来获得下一期新视频推送的时间
但大家伙基本上都没获得过YouTube的推送消息吧
也许我更该说 大家赶紧订阅我的频道
这样YouTube后端推荐算法用的神经网络
才会相信大家想看到这个频道的内容出现在推荐栏
总之 我们不见不散
非常感谢所有在Patreon上资助我的人
这个夏天我稍微有点偏离了概率论系列的计划
但做完这个系列我会回到计划上来
所以资助的大家可以随时在那获取更新
节目的结尾 我请到了Lisha Li
她在博士期间做了深度学习理论方面的研究
而她现在在一家叫Amplify Partners的风投公司工作
他们慷慨地为本期视频提供了一部分资金资助
那么Lisha 有个事情我想稍微提到一下 就是这个sigmoid函数
以我的理解 早期的网络都是用这个
把加权和映射到0至1的区间内的
当年正是这么来模仿生物学上的神经元是否激发的来着
没错
但现在的神经网络基本上都不用sigmoid了
就很过时
没错没错 ReLU应该更好训练
ReLU全称叫"线性整流函数"吧
是的 这种函数就是返回
0和a的最大值 其中a就是函数的输入
你在视频中解释 神经元之所以会采用这种函数
我认为一部分是为了模仿生物学上的神经元什么时候会激发
所以 当超过一个阈值的时候 ReLU就和恒定函数一样
而没过这个阈值 那么就不激发 输出0
可以当作是一种简化版
Sigmoid并没有让训练结果变得更好
或者某种程度上讲它很难训练
后来有人就拿ReLU试了试
结果发现在特别深的神经网络上效果特别的好
非常感谢Lisha
Amplify Partners是一家为早期技术创业公司设立的风险投资
致力于资助下一代人工智能应用的开发
如果你自己 你认识有人想有朝一日创业
或者你自己现在就在一家草创公司工作的话
Amplify很乐意与你联系
他们为本期视频还专门设立了唯一指定邮箱
欢迎大家前去咨询