web 前端入门神经网络(一)

文章中会涉及到值、向量、矩阵,表示方式以 q 为例: 值为小写字母 q,向量为加粗小写字母q,矩阵为大写加粗字母Q,运算非常简单,只需要具备基础线性代数知识即可。

部分例子和图片来自于 Michael Nielsen神经网络和深度学习,结合自己在学习过程中的心得和其他资料,分享出来

请看字母识别 demo

一、放松心情 一点都不难~

先来讲一个故事:

我是一个爱吃披萨的人,选择是否去一家新开的披萨店吃披萨

三个因素影响我是否去这家披萨

1. 天气好

2. 有人陪伴

3. 交通方便

交给一个抉择模型来处理

这个模型非常简单:

1)把三个因素作为输入值,形成一个三维输入向量 x(x1, x2, x3)

2)为每个输入值设定一个权重,三维权重向量 w (w1, w2, w3)

所以输出有 y = w1 x1 w2 x2 w3 * x3, 再设定一个阈值 s 与 y 做对比,给出结论:

  • 如果 y > s 就去
  • 如果 y <= s 果断家里睡觉

用公式表达:

去:w1 × x1 + w2 × x2 + w3 × x3 - s > 0

睡觉:w1 × x1 + w2 × x2 + w3 × x3 - s <= 0

设 b = -s,w1 × x1 + w2 × x2 + w3 × x3 + b 是否大于 0 就是我想要的结果

影响结果的变量有三个,向量 x,向量 w,值 b

x是已知的,三个因素(x1,x2,x3)每个值满足就是 1 不满足就是 0。

w(w1,w2,w3)和 b 怎么设定呢?

至少要先武断的设定一套值,这个模型才能运作:

我先给 b 设定一个值 b = -10,那么只要 w1 + w2 + w3 > 10 我就能愉快的出门了, 一个一个来看吧:

w1 我是个很看重天气的人,天气不好我不出门,所以我给它的权重最大: 8

w2 其实有没有人去还好啦,人总要习惯寂寞,它的权重:3

w3 因为没有车,只能公共交通,太麻烦就不去了,它的权重:5

好了,可以有结论了,只要天气差,果断睡觉,天气好再满足任意一个条件我就去。

不错,这个模型可以,不过费了这么大劲,就只为了决定是否去吃披萨?回头瞅一眼三个因素:

1. 天气好

2. 有人陪伴

3. 交通方便

这个貌似很通用哎,日常生活很多出行:吃饭,看电影,逛街 似乎都可以用这个模型来决定,因为它们的输入因素是相同的,或许不只有 3 个,可以是 n 个,那么通过为模型设定合适的 w & b,总能为大多数【选择请求】 给出令人满意的结果。

如何寻找 w & b

假如我是个很闲的人,每次有这种类型的 【选择请求】,我的都会交给这个模型去判断,如果输出结果让我不满意,我就去手动调整 w & b 值,因为它结构很简单,经过无数个日日夜夜,无数次更新迭代,总有一款 w & b 适合我多数的【选择请求】,彻底治愈选择恐惧症。

二、神经网络初识

但是现实往往没有这么简单,显然一个三维的输入向量和一个一维的输出向量是无法满足要求。

现在可以介绍 神经元 的概念,上图中的圆圈就是一个神经元,它的作用是为输入向量的每个分量分配权重值 w 和偏置值 b 通过 w1 × x1 + w2 × x2 + w3 × x3 + b 计算出输出, 这已经构成了一个非常简单的 神经网络 模型 感知机

先不考虑很复杂的 神经网络 的设计思路,先把神经元增加到两个,让输出结果成为一个二维的向量(a1,a2),然后梳理结果计算流程

输入向量x(x1,x2,x3)

神经元 n1(它分配给 x 的权重向量w1(w11,w12,w13)和偏置值 b1)

神经元 n2(它分配值 x 的权重向量w2(w21,w22,w23)和偏置值 b2)

那么输出结果是什么呢

神经元 n1 的输出结果:a1 = w1 × x + b1 = w11 × x1 + w12 × x2 + w13 × x3 + b1

神经元 n2 的输出结果:a2 = w2 × x + b2 = w21 × x1 + w22 × x2 + w23 × x3 + b2

那么二维的输出向量 a(a1,a2)= (w11 × x1 + w12 × x2 + w13 × x3 + b1, w21 × x1 + w22 × x2 + w23 × x3 +b2)

x(x1,x2,x3)

w1(w11,w12,w13)、b1

w2(w21,w22,w23)、b2

(w11 × x1 + w12 × x2 + w13 × x3 + b1,w21 × x1 + w22 × x2 + w123 × x3 + b2)

这个过程应该整合得更规范才行,复杂的神经网络的计算过程才会变得清晰。

先优化结果的表示:

(w11 × x1 + w12 × x2 + w13 × x3 + b1,w21 × x1 + w22 × x2 + w23 × x3 + b2)

= (w11 × x1 + w12 × x2 +w13 × x3,w21 × x1 + w22 × x2 + w23 × x3) (b1,b2)

注意,(b1,b2) 此时形成了一个偏置向量

这里熟悉矩阵的童鞋会发现,可以用矩阵运算表示更加简洁:

[(w11, w12, w13), (w21, w22, w23)] × [(x1), (x2), (x3)] [(b1), (b2)](这一步看不懂多看几遍)

值得关注的是:这个式子并不等于上面的二维向量,因为它是一个 2×1 的矩阵,即便转置之后也是一个 1 × 2 的矩阵并不是向量,尤其是在程序代码中,不过意义是一样的,为了计算方便我们干脆将输出结果改用矩阵来衡量,同时,输入值、权重、偏置值都用矩阵来表示

= [w1,w2] × [(x1), (x2), (x3)] [(b1), (b2)]

W 表示矩阵 [w1,w2],用 X 表示矩阵 [(x1), (x2), (x3)] ,用 B 表示矩阵 [(b1), (b2)],那么

= W × X B 这是一个 2 × 1 的矩阵

好,三个输入值,两个神经元的神经网络

输入值为 3 × 1 矩阵 X

权重为 2 × 3 矩阵 W

偏置为 2 × 1 矩阵 B

所以 W(2×3)× X(3×1)结果是(2×1)矩阵 再与矩阵 B(2×1)相加 符合矩阵运算规则,合情合理,没毛病

明白这段计算合理性,对于理解整个神经网络过程是很关键的,否则在梳理计算逻辑时会一头雾水,到后面反向传播直接蒙逼,so 一定要搞懂~

结论:A = W * X B.

A 是输出结果矩阵,X 是输入因素矩阵,W 是权重矩阵,B 是偏置矩阵

注意:这是一个只有一层神经元组包含了两个神经元的神经网络推导出的结果公式

现在我再加一层神经元组会怎样,如下图

这个图的表达不准确,第一层只是输入层,不应该画成圆形,相当于上面 x1、x2、x3,并不算作神经元组,也不会有WB,图是用的别人的,请见谅!

那么,这个网络中,实际起作用的神经元组有两层,分别包含了 4 个神经元和 1 个神经元

上面公式推导是针对一层神经元组的,我要想应用在现在这个网络N中,我要先把这个网络分割成两个,第一层 第二层算一个网络 N1,第二层 第三层是一个网络 N2,N1 输出值算作 N2 的输入值,N2 的输出值为整个网络N的结果

那么对于N1

A1 = W1 * X B1

对于N2

A = A2 = W2 * A1 B2(这里先不展开)

得到一个递推公式:An = Wn * An-1 Bn A0 其实就是输入层 X

这下牛逼了,不管多么庞大的神经网络,计算过程都是通过递推公式从前算到后。

好,现在来说一个从开始就被忽略掉的关键问题我所有的推导过程都是基于 a = w * x b 而来,但它是线性方程,线性方程会有什么问题,简单说:神经网络的训练本质是对数据的一个分类过程,线性方程无论通过多复杂的叠加,带来的始终是线性分类,直观的说,就是用直线给数据平面做划分,划分的能力不够,很多类型的数据,只有非线性(曲线) 才能将其分开,所以要引入非线性激活函数。

寻求一个有限值域的非线性函数作为激活函数,可以将 w * x b 的值收敛到一定范围,激活函数 sigmoid 函数登场,它的值域是(0,1),体态光滑,容易求导,后面要用

它的导数:sigmoid(z) * (1 - sigmoid(z))

a = sigmoid(z); z = w * x b 注意,这里是对值的计算,所以前面每一步求值 a,都要套上 sigmoid 函数。为了方便,我就直接用大写的 SIGMOID 套在递推公式的矩阵外面:

An = SIGMOID(Wn * An-1 Bn),A0 = X 这是正确的递推公式

好,讲了这么多,说的好像真的能通过 X 求出 A 似的,的确,如果你知道每一层的 W 和 B 的话。

然而我们是不知道的,神经网络模训练过程就是调节 WB,目的是将 WB 调至最优,来确保输出的 A 无限接近真实的结果 Y,然而初始的 WB 从哪里来,先简单搞,用正态分布的数值来填充WB,随便填? 是的,随便填,反正你要给个初始值,这跟文章开头武断的赋值给 w 和 b 没有任何区别,这当然不是最优办法,但现阶段是 ok 的。

三、反向传播:调节 W 和 B

给了 WB 赋值后,网络就可以运作了,通过 X 算出 AA 基本上是不可能等于 Y的,最后一层每个维度的误差值组成 C 来代表神经网络的最后一层的误差矩阵,它源于 WB 的不恰当导致,每一层的 WB 的误差 deltaWdeltaB 最终导致了整个网络的误差 C,我们现在要做的就是通过 C 从最后一层往前面推,来确定每一层的 deltaWdeltaB,这就是反向传播的含义。

c 关于 y 和 a 的函数叫做神经网络的 cost function,俗称 损失函数,这里先介绍其中简单的一种:

c = 0.5 *(y - a)^ 2

下面通过它来推导每一层的 deltaw 和 deltab

推导过程用值来算,更贴近实际程序运算的过程

如何通过 c、y、a、w、b、a" 推导出 deltaw、deltab

c 是 最后一层 第一维 误差

y 是 最后一层 第一维 正确值

a 是 最后一层 第一维 输出值

a" 是 倒数第二层 第一维 输出值

c = 0.5 *(y - a)^ 2

应用链式求导法则,结合这下面三个式子展开

a = sigmoid(z)

z = w * a" b

simoid(z)' = sigmoid(z)*(1 - sigmoid(z))

deltaw 就是 c 对 w 求偏导:下面的 ' 代表对 w 求导

c' =(0.5 *(y - a)^ 2)'

=(y - a)*(y - a)'

= -(y - a)* a'

= -(y - a)* sigmoid(z)'

= -(y - a)* sigmoid(z)(1 - sigmoid(z)) `(w*` a" b)'

= -(y - a)* sigmoid(z)*(1 - sigmoid(z)) * a"

deltab 就是 c 对 b 求偏导:下面的 ' 代表对 b 求导

c' =(0.5 *(y - a)^ 2)'

=(y - a)*(y - a)'

= -(y - a)* a'

= -(y - a)* sigmoid(z)'

= -(y - a)* sigmoid(z)*(1 - sigmoid(z))*(w * a" b)'

= -(y - a)* sigmoid(z)*(1 - sigmoid(z))* 1

从后算到前,填充每一层的 deltaW 矩阵和 deltaB 矩阵

然后,更新每一层的 WB

W = W - learning_speed *deltaW

B = B - learning_speed *deltaB

learning_speed 一般是一个介于 0~1 之间的学习速率值,来控制步进,不宜过大,否则梯度不降反升,误差越来越大

四、实战

Michael Nielsen识别手写字体的 demo 已经很好了,也是这个 demo 的 network 代码帮助我弄清了反向传播的细节计算,建议大家去看下。

我做了一个识别简单字母,就是本文开头的 demo,搭在腾讯云上的,还在完善中,不稳定,欢迎围观~

demo 的识别过程是在浏览器端完成,训练通过 nodejs 调用 python 脚本实现

页面会每十秒跟后台请求一次最新的网络模型参数,也就是 B & W,生成模型来识别验证码~

五、后续

在神经网络中,激活函数和损失函数是决定 网络模型是否有效和学习速率的关键部分,这次没有展开说,我觉得对于刚接触的同学先不要纠结于此,自己把程序先跑起来,识别几种简单的字母或文字,后面我会整理出常用的激活函数和损失函数的相互比较和应用,再来分享。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

郭佳伦的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据文摘

小白学数据神经网络第二弹:Google可视化体验平台Tensorflow Playground

1614

5种无需数学背景也可理解机器学习算法的技巧

在一种自顶向下的研究机器学习的方法中,理论应立足于何处?

26210
来自专栏量子位

图像风格迁移(Neural Style)简史

作者:李嘉铭 Northwestern University | CS 量子位 已获授权编辑发布 面向读者:没有或有一定机器学习经验并对Prisma之类的app...

3657
来自专栏绿巨人专栏

强化学习读书笔记 - 02 - 多臂老O虎O机问题

3387
来自专栏AI研习社

Prisma 技术发展的前世今生

面向读者:没有或有一定机器学习经验并对 Prisma 之类的 app 背后的原理感兴趣的读者。比较有经验的读者可以直接参照科技树阅读文章末罗列的引用论文。 阅读...

3487
来自专栏专知

【脑洞大开】IBM AAAI2018论文DLPaper2Code:自动从深度学习论文生成执行代码程序(附作者博士论文下载)

【导读】近日IBM研究院提出从深度学习相关论文中自动生成深度学习代码,使用这项研究,在研究论文中提出的DL设计可以被自动提取,然后使用一种新颖的深度学习UI编辑...

30311
来自专栏IT派

一个Python自动提取内容摘要的实践

利用计算机将大量的文本进行处理,产生简洁、精炼内容的过程就是文本摘要,人们可通过阅读摘要来把握文本主要内容,这不仅大大节省时间,更提高阅读效率。但人工摘要耗时又...

1290
来自专栏人工智能头条

数据科学与机器学习管道中预处理的重要性(一):中心化、缩放和K近邻

1653
来自专栏大数据文摘

NLP入门+实战必读:一文教会你最常见的10种自然语言处理技术(附代码)

1482
来自专栏深度学习自然语言处理

2018 NLPCC Chinese Grammatical Error Correction 论文小结

这一段时间,笔者一直在研究语音识别后的文本纠错,而就在八月26-30日,CCF的自然语言处理和中文计算会议召开了,笔者也从师兄那里拿到了新鲜出炉的会议论文集,其...

623

扫码关注云+社区