记得17年第一次阅读深度学习相关文献及代码觉得不是很顺畅,做客户端开发时间久了,思维惯性往往觉得比较迷茫。
而且文章中涉及的数学公式及各种符号又觉得很迷惑,虽然文章读下来了,代码也调试过了,意识里并没有轻松的感觉,隔段时间再看,脑子里又是空空如也。
其实目前来看,深度学习的底层逻辑很简单,只是当时完全迷失在了数学逻辑的符号,公式推导,及代码对应层面,对于神经网络学习的精髓并未完全把握。
我尝试着就自己的理解,极简化其中的数学逻辑,阐述最简单的神经网络学习模型具体原理,不会涉及什么Tensorflow,卷积神经网络这些经常听到的概念,就是很朴素的语言。
可以参考 Michael Nielsen 的经典文章 Neural Networks and Deep Learning
神经网络 - Hello Wrold
具体神经网络缘由介绍很多,此处就不冗余跳过,从一个最简单的问题开始
上面的手写数字,计算机如何识别 就是神经网络中的 Hello World
比如手写体数字 3, 如何识别出 罗马数字3
解决输入问题
抽象
先把这个Hello World看做一个黑盒,输入就是一个手写体的数,也就是一张图
我们把 上图中的 圈计为一个神经元,圈中标注 0 ~ 1 范围的数字,表明神经元被激活的强度
手写体数字9 就被划分为 28*28 个小单元,也就是784个神经元
每个神经元中标注的数字,就是图中对应像素的灰度值
可以理解为相应位置的神经元被激活的强度
0表示纯黑像素,1表示纯白像素
激活强度,暂时命个名 - Activation (激活值)
变换
把这784个神经元经过以下变换
其中,中间的两层暂时当做大黑盒,黑盒里面就进行着处理识别数字的具体工作
最左边的一层 784 个神经元
最右边的一层神经元,激活值也为 0~1,表明输入的图像 是具体某一个罗马数字的可能性
至于中间为啥两层,每层16个神经元,可以认为就这么着,重在理解模型为主
最终构成了一个神经网络,这个网络包含了 784+16+16+10 个神经元
网络认知
我们认知手写数字的逻辑可能是这样的
数字整体拆分成 几个大的部分
每个部分进一步拆分成小一点的笔画
中间一层 对应着 拆分的较大的部分
较右边的一层 对应着 笔画部分
神经元 - 神经元
那么,如何拆分部件,怎么拆分才是正确的呢,而且输入图像,也就是784个神经元 与 网络中间的黑盒又是如何工作的?
就着这个网络,可能我们直观的逻辑就是希望这样
比如,手写体数字7 中的 水平一部分,中间较粗明亮的水平部分,如何提取出来
为了简单,拆分的大组件 用一个神经元表示
其中 横 组件边缘较 暗的部分,也就是 输入层横 边缘激活值较低的神经元, 对第二层 对应 横组件的 那个神经元 作用就弱,具体表现就是 第一层的神经元连过来的线就弱一些
第一层其余的神经元(跟横无关的神经元) 此刻 练过来的线 甚至可能看不见,影响微乎其微
w表示 - 神经元之间的连线强弱
a表示 - 神经元的激活值
此时,这个装着 横 的神经元的激活值 就是 w1a1 + w2a2 + ..... + w784*a784
前面说过,每个神经元的激活值 在 0~1之间
但此时 得到的这个 代表 横 的神经元的激活值 可能为任意值,并不在0~1之间
为了让 激活值 能继续 收敛在 0~1之间,用到Sigmoid 函数
这个 装着 横 的神经元 并不能随便激发,必须有个门槛,过门槛才能激发,比如这个门槛为1,才能激发
Sigmoid(w1a1 + w2a2 + ..... + w784*a784 - 1), 正好对应 超过上图中的 标注点,神经元激发
最终 Sigmoid(w1a1 + w2a2 + ..... + w784*a784 + bias), bias 就是 上面的 -1
抽象网络关系
这是线性代数中的矩阵 相乘
整个网络中 包含的
开关变量总数:78416 + 1616 + 1610 + 162 + 10 = 13002
也就是 总权重开关:78416 + 1616 + 16*10 = 12960
总bias开关:16*2 + 10 = 42
接下来就是 这 13000 个开关变量 的设置问题了,可以认为 这个黑盒函数 有 13000 个变量,要对这13000个变量求解,得到一个完全函数,然后使用这个函数 就可以得到 识别结果了
求解的过程就是 学习的过程