神经网络-自动训练

神经网络-自动训练

作者: 莫烦 编辑: 莫烦 发布于: 2021-10-31

恭喜你,已经将 Numpy 玩得炉火纯青了。我们今天就来玩点大的,用 Numpy 手工做出来一个神经网络。 上节内容,我们已经介绍了,怎么利用 Numpy 的矩阵乘法来做神经网络中最核心的部分。 而且已经把神经网络的雏形给搭建起来了。

不过光有神经网络的皮可不行,我们还要让它能够自学习起来,做一个可以被训练,能够拟合数据的模型出来。 这里就需要了解一点反向传播的概念了。 不过没关系,即使你没有弄懂其中的奥秘,以不妨碍做出一个能用的 AI 模型。

模型前向预测

神经网络能够预测物体,是因为他可以通过一个正向的信息传递,得到输入信息(比如猫的图片)加工后的一个结论(这张图片是猫)。

cat

而且这个过程的一个简单版,我们在上节内容中已经做过了。 简单回顾一下:

上面是原始数据的样子,下面是模型预测出来的样子。

如果你对 draw_scatter()draw_line() 函数感兴趣,你可以看看我怎么写的。

下面看看每个神经层的添加。

但是很明显,对比两张图片,你会发现预测是 y 坐标存在明显的量级上的差距。 而我们今天要讲的,是如何让模型能够学习出来数据背后的规律,让它能够精准地预测数据。

简单介绍反向传播

我之前做过一个反向传播的概念的动画。里面大概表达的意思是: 神经网络能够做前向的信息加工和预测,但是并不是一开始就能预测得很准的。模型得通过不断学习,不断修正自己的网络参数,才能慢慢变得精准。

那问题来了,我们通过什么样的方法和原则来做网络参数的修正?使之下次做前向预测的时候更准确?

还好,目前有这么一套叫做梯度反向更新的规则,可以做这件事。如果你大学学了高数,你应该不算陌生。没学也没关系,我不会讲太多细节,毕竟这是 Numpy 的主场, 而不是算法的主场。

backpropagation

简单来说,我们就是要找到每一个神经层的导数,用导数求梯度,用梯度来更新网络参数。哈哈,有些同学可能在这里听不懂了。没关系,你可以做一次拿来主义, 把它当成工具来用就好了。

这就是你可以直接拿来用的功能,它的目标是计算每一层神经层的更新幅度,并按照学习率来更新网络参数,让网络对数据拟合得越来越好。这里面就涉及到了 Numpy 的矩阵转置 .T,也有累加的操作 .sum()。 每次调用 backprop() 功能,我们实际上在干的事就是去计算每一层 wb 的梯度 gwgb。然后将梯度误差在传递到前面的一层去。

OK,了解了这些,我们就用 Numpy 来做神经网络的更新吧。步骤大概是这样的:

  1. 准备好数据,搭建好模型
  2. 开始训练循环
    1. 前向预测,x 通过每一层计算得到 o2
    2. 计算误差
    3. 反向传播,更新网络

运行一下上面的代码,我们就能看到在没有训练的时候,预测出来的模型线数值和预测 y 的数量级是有问题的。 下面我们开始训练,然后再画一张对比图,你就能发现模型训练好了是啥样。

现在你可以试着修改一下神经网络层里面的输入输出神经元个数layer(dim_in, dim_out),又或者多加两层神经层(对应要修改反向传播的链路)。 如果你在多加两层神经层后能成功运行,那么就说明你掌握了神经网络反向传播的诀窍~

加入激活函数

上一节 我们还提到了添加激活函数,这个激活函数也同样是要考虑到反向传播中的。 和上面一样,我下面的功能是用来计算激活函数的梯度的,你可以当成工具直接来用,不一定要搞清楚其中的原理。

我在上面帮你准备了一些激活函数,我们在搭建神经网络的时候就能用得到。上面一个环节我们训练的是一个相对简单的线性数据,这次来一个非线性,比较复杂的。

我们再来用一个没有激活函数的网络训练一次,你会发现,模型学不好。不信你运行下面的代码,看到的应该是一张拟合欠佳的结果。

现在我们加入激活函数。在第一层神经网络的结果 o1 处添加一个非线性函数。并加上对应的非线性反向传播步骤,再来一次。

你看,这不就拟合上了这些奇怪的数据点了吗。说明非线性的激活函数还是很有用的。现在你可以尝试修改激活函数的方法, 并在反向传播的地方也修改一下对应的激活函数的反向传播。

我用 Numpy 写的神经网络库

看到上面的教学案例还不过瘾,要不要上一些实战的神经网络?我前几年因为突发奇想,闲着无聊,想自己实现一下神经网络库,顺便看看自己能力如何,能做到什么程度, 所以我就用 Numpy 自己手写了一个类似 Tensorflow 和 Pytorch 的神经网络库。 这个库完全依赖于 Numpy,名字叫 npnet 而且性能也是杠杠的。我的 Github 链接: https://github.com/MorvanZhou/npnet

有兴趣的朋友,也可以直接用 pip 安装,在本地运行:

python3 -m pip install npnet

# 或

pip install npnet

或者直接在这里的交互窗口运行:

首先用 micropip 安装我的 npnet,然后在用它构建网络,并训练运行。

总结

在这一节我们完成了徒手构建简单神经网络的练习,但因为内容量的原因,我只提到了数值型预测的神经网络,而没有提到分类的神经网络。 有兴趣的朋友可以结合一下这两节内容,自己实现一个二分类的梯度更新。

Numpy 的交互式教学内容也告一段落啦。希望你们经历这一路,有学到不错的知识和技能~


降低知识传递的门槛

莫烦经常从互联网上学习知识,开源分享的人是我学习的榜样。 他们的行为也改变了我对教育的态度: 降低知识传递的门槛免费 奉献我的所学正是受这种态度的影响。 【支持莫烦】 能让我感到认同,我也更有理由坚持下去。