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 条评论
登录 后参与评论

相关文章

来自专栏华章科技

「知识图谱」领域近期值得读的 6 篇顶会论文

论文 | Hike: A Hybrid Human-Machine Method for Entity Alignmentin Large-Scale Know...

781
来自专栏深度学习入门与实践

【深度学习系列】迁移学习Transfer Learning

  在前面的文章中,我们通常是拿到一个任务,譬如图像分类、识别等,搜集好数据后就开始直接用模型进行训练,但是现实情况中,由于设备的局限性、时间的紧迫性等导致我们...

3115
来自专栏大数据文摘

暑期追剧学AI (4) | 人工智能关键概念“神经网络”是什么?不信看完这个视频你还不懂!

1726
来自专栏SimpleAI

【DL笔记2】神经网络编程原则&amp;Logistic Regression的算法解析

从【DL笔记1】到【DL笔记N】,是我学习深度学习一路上的点点滴滴的记录,是从Coursera网课、各大博客、论文的学习以及自己的实践中总结而来。从基本的概念、...

714
来自专栏大数据挖掘DT机器学习

达观数据NLP技术的应用实践和案例分析

达观文本挖掘系统整体方案 达观文本挖掘系统整体方案包含了NLP处理的各个环节,从处理的文本粒度上来分,可以分为篇章级应用、短串级应用和词汇级应用。 篇章级应用有...

38611
来自专栏有趣的Python

2- 深度学习之神经网络核心原理与算法-提高神经网络学习效率

上一章我们介绍了基本的前馈神经网络的实现。 本节我们来介绍一些可以提高神经网络学习效率的方法。 并行计算 加快神经网络训练最直接的方式。我们需要得到的是一个网络...

53313
来自专栏媒矿工厂

基于双流编码-解码深度网络的视频对象分割算法简介

背景介绍 视频对象分割(Video Object Segmentation),目的是将视频段中的物体连续地“抠”出来以得到视频每一帧的前景、背景分割结果。分割得...

3613
来自专栏企鹅号快讯

Python数据分析与实战挖掘

基础篇 书推荐:《用python做科学计算》 ? 扩展库 简介 Numpy数组支持,以及相应的高效处理函数 Scipy矩阵支持,以及相应的矩阵数值计算模块 Ma...

3525
来自专栏AI科技评论

干货 | 史上最好记的神经网络结构速记表(上)

本文提供了神经网络结构速查表,盘点了神经网络的大量框架,并绘制了直观示意图进行说明,是人手必备的神经网络学习小抄。 新的神经网络结构不断涌现,我们很难一一掌握。...

39912
来自专栏AI科技评论

开发丨如何训练深度神经网络?老司机的 15 点建议

本文为印度深度学习专家、创业者 Rishabh Shukla 在 GitHub 上发表的长博文,总结了他过去的开发经验,旨在给新入门的开发者提供指导。AI科技评...

3648

扫码关注云+社区