谈谈对神经网络的理解

首先,“神经网络” 这个词来源于脑科学,但其实目前计算机中的神经网络跟脑科学中的神经网络没太大关系,只能算是受其启发,个人感觉有点像飞机和鸟的关系。

从线性模型说起

先从最简单的线性模型说起,高中我们学过的线性回归就是线性模型,求解线性回归模型最经典的解法是最小二乘法。
线性模型

写成向量的形式:
线性模型的向量形式

回想高中学过的内容,通过会给我们一堆二维点的坐标值,需要找到一条直线来拟合这一堆点,如下图所示
线性回归示例

二维情况我们需要求解的 w 向量其实只有一个值,对应的拟合函数 f(x) 就是一条直线。

若将上述示例扩展一下:将给定的二维点扩展为高维空间的点。我们要找的拟合函数就变成了一个超平面,但求解方法还是一样的。

感知机(Perceptron)模型

在学习神经网络的时候,还有一个经常听到的词汇叫做 “感知机(Perceptron)”,感知机模型通常喜欢用下面的图来表示:
感知机模型

上面我们提到的线性模型,通常用来做回归,拟合数据点。而感知机模型通常用来做二分类,其数学描述为:
在这里插入图片描述

可以看到,感知机模型是在线性模型的基础上再套用了一个函数 f,函数 f 是符号函数,其数学形式为:
在这里插入图片描述
结果为 +1 时,表示正类,-1 表示 负类。感知机模型的思想可以归纳为:找到一个线性超平面,可以将高维空间的两类点完美的分开。

很明显,感知机模型的缺点是:数据集必须是线性可分的。例如下面这样的数据集用感知机模型是无法准确分类的。

在这里插入图片描述

非线性模型 - 逻辑回归(Logistic Regression,LR)

线性模型不能解决线性不可分的问题,为了解决这个问题,很自然的,需要引入非线性模型。

最简单的非线性模型就是逻辑回归了。逻辑回归这个名字很容易让人迷惑,误以为是用来处理回归问题的,事实上,逻辑回归模型更多的是用来处理分类问题。

逻辑回归是数学表达为:
在这里插入图片描述

仔细一看,跟上面提到的感知机模型的数学描述一样。是的,目前看就是一样的,都是在线性模型的基础上套一个函数 f,区别也就在函数 f 的选取上,感知机模型使用符号函数 sign 作为 f,逻辑回归则使用的是鼎鼎大名的 sigmoid 函数。

嗯,sigmoid 函数很有名,在机器学习界应该算家喻户晓,它的形状是一个 S 形,如下:
在这里插入图片描述

sigmoid 函数的数学公式为:
在这里插入图片描述

sigmoid 函数的厉害之处在于:它的值域是 (0, 1)。对于任意大小的输入,它都可以将其压缩至 (0, 1) 之间,更好玩的是,它是关于 (0, 0.5) 这个点中心对称的。所以做二分类时,当逻辑回归的输出值大于 0.5 的时候,判断为正类;输出值小于 0.5 的时候,判断为负类。这个输出值也可以作为类别判断的概率值来使用。

LR 在推荐领域应用非常广泛,最常用来做 CTR 预估,可以算是机器学习中最经典的模型之一。

但是,读到这里的读者其实会发现,在同样的参数 w, b 下,LR 和感知机模型的分类结果其实是一样的,只是输出的数值不一样。为什么 LR 应用这么广泛,而感知机模型几乎没有实际应用呢?

关于这个问题,我的理解是 LR 的输出更加直观,直接可以作为分类概率值使用,适合用来做排序和调整分类的概率阈值。

另外还有一个问题:LR 模型本质上也可以看做线性模型,对于线性不可分的数据,它其实也是无能为力的,为何它还能得到广泛的应用?

这个问题的答案是:既然 LR 模型无法处理线性不可分数据,那我们就将线性不可分数据做一个预处理,使其变成线性可分的数据。听起来比较玄乎,其实这个操作有一个专有名词,叫做 “特征交叉”, 做推荐的朋友肯定不会陌生,“特征交叉” 的过程实际就是将数据从线性不可分转为线性可分的过程。类似的还有一个例子就是:核函数在 SVM 中应用。SVM 本质上也是线性模型,但其可以通过核函数映射,将低维线性不可分数据转为高维线性可分数据,从而达到分类线性不可分数据的目的。

所以,总结一下,LR 虽然通过 sigmoid 函数引入了非线性,但事实上它还是不能自动处理线性不可分数据,必须通过人工的特征交叉来解决。那有没有一种方法,可以不需要人工干预也能够处理线性不可分数据呢?

答案必然是有的,也就是下面讲的:神经网络

神经网络

首先说结论,神经网络毫无疑问是一个强大的非线性模型,只要参数够多,可以拟合任意函数。

先上图:
在这里插入图片描述

可以看到,神经网络主体分成三个部分:输入层(Input Layer),隐藏层(Hidden Layer),输出层(Output Layer)。每一层的基本单元是 “神经元(Neuron)”。

输入层就是输入数据层,隐藏层可以理解为是一个黑盒子,里面有很多参数,输出层就是输出数据层。

“神经元” 是什么呢?貌似生物里面学过,还有 “突触”、“神经递质” 等一系列吊吊哒的东西。不过,很可惜,这里的 “神经元” 更那些没什么关系,就像飞机发动机跟鸟类心脏没什么关系一样。

这里的 “神经元” 其实我们在前面见过,它就是 LR 换了个马甲的样子,嗯,所以皮肤很重要。下面是它的数学描述:
在这里插入图片描述

是的,又跟感知机和 LR 的数学描述一样。区别还是在套用的 f 函数上。现在呢,在神经网络中,这个 f 函数也有了一个专有名词,叫做 “激活函数(activation function)”,嗯,不是咱们公司的 “激活”。再看个图好理解:
在这里插入图片描述

每个神经元的输出可以理解成 LR 的输出,所以其实也可以先把神经网络粗暴的理解成很多个 LR 的组合体。

每一层的输出又作为下一层输入,堆叠很多这样的层,就叫做深度神经网络了,研究这些深度神经网络的学问又叫深度学习了。那有没有浅度学习呢,答案是没有的,一般 3, 4 层网络就号称深度网络了。

当然,神经网络毕竟发展了这么多年,也不能简单的用 LR 组合体来解释,其中还是有不少细微差别的。下面一一道来。

激活函数

首先是激活函数,早期的神经网络最常用的激活是 sigmoid 和 tahn 函数(用 sigmoid 的话就是 LR 组合体了)。它俩的形状都是 S 形,值域一个是 (0, 1),一个是 (-1, 1),差不多,都起到了引入非线性和压缩输入范围的效果。

但事实上,S 形的激活函数都有一个问题,那就是容易造成梯度消失(至于什么是梯度消失,需要先理解反向传播、梯度下降的概念,这个以后再讲,或者读者自行查资料,不过这里可以先记住结论,就是 sigmoid 和 tahn 作为激活函数都有大问题)。

机器学习界的扛把子 Hinton 老爷子受到生物学研究的启发,于 2010 年提出了一种全新的激活函数,叫做 ReLU(Rectified Linear Units,线性整流单元),效果拔群,远超 sigmoid 和 tahn,又由 12 年的 AlexNet 发扬光大,目前已经成为神经网络的标配(标配的意思是,还有其他配置,例如 leaky_relu,PReLU,ELU,Maxout 等,不过还是 ReLU 应用最广泛)。

ReLU 的神奇之处在于,它已经被证明很好、很强大,但它的数学公式可以算极简,如下:
在这里插入图片描述

ReLU 函数图像如下:
在这里插入图片描述

极简,极好。

ReLU 解决了 sigmoid/tahn 函数的梯度消失的问题,但较真的话,ReLU 也有一个问题,就是它在小于 0 那一段是没有梯度的,会导致神经元 “死掉”,事实上,实际证明这个问题不大,可能的原因是神经元可能处于 “死死活活” 的状态,这次是输入它死了,下次的输入它又复活了。

至于为什么 ReLU 这么简单,效果还这么好?嗯,这方面研究很多,我比较认可的解释是:咱生物身上的激活函数就是这么工作的。

下面列几个常见的激活函数,有兴趣的同学可以自行搜索研究。
在这里插入图片描述

Batch Normalization

Batch Normalization,简称 BN,目前跟 ReLU 一样,也算是神经网络的一个标配(RNN 除外,RNN 不适合用 BN,不过有类似的 Layer Normalization),加上 BN 之后,一般能够使得网络收敛速度更快,效果更好。

BN 也跟 ReLU 一样,有个特点:简单,强大。

BN 深层次的思想暂且不提,有兴趣的读者可以看原始论文(强烈建议看一看,Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift),BN 的简单思想就是将每一层神经网络的输入做一次归一化,使其均值为 0,方差为 1,这样可以最大限度的减小深层网络与线层网络之间的耦合,使得训练真正的深度网络成为可能(例如训练千层饼网络 ResNet-1202)。

另外 Batch Normalization 中的 Batch 指的是在 Batch 维度做归一化,属于纵向归一化,而 Layer Normalization 则是横向归一化,不依赖 batch 维度。这里不展开细讲,有兴趣的同学可以自己搜索相关文档深入。

需要注意的是,BN 的使用场景是神经网络输入数据的 batch 不能太小,太小的话效果可能会很差。还有就是需要注意 BN 在 train 和 inference 阶段的不同,在研究 BN 原理的时候需要搞懂这些。

BN 的另一个好处是使得 sigmoid 和 tahn 这种存在梯度饱和区的激活函数也可以用在超深神经网络中,虽然效果没有 ReLU 好 😃,但不加 BN 的话,用 sigmoid 和 tahn 训练超深网络根本没法收敛。

最后,虽然 BN 应用广泛,但受其启发,学术界还是提出了很多其他的 Normalization 方法,比如 Instance Normalizaion,Weight Normalizaion,RNN 可用的 Layer Normalization,CNN 专用的 Group Normalization,有兴趣的可以研究看看。最后,放一张图,一图胜万言:

在这里插入图片描述

图片来自于论文 Group Normalization

Dropout

经典正则化方法有 L1, L2 正则,这里不讲,神经网络中还有一种经典的正则化方法,就是 Dropout,也是扛把子 Hinton 提出来的。特点么,也是一个:简单,强大。

Dropout 一般用于全连接层(Fully Connected Layer),在 CNN 中用的少,RNN 中的 Dropout 需要特殊处理,不展开。

下面以全连接层的 Dropout 为例,如图所示:

在这里插入图片描述

思想就是,在前向传播的过程中随机 drop 掉一些连接,注意,重点是随机。

另外,dropout 很容易让人忽视的一点是其在 train 和 test 阶段的不同,假设 dropout 保留的神经元比例是 p,如果在 train 阶段不做任何处理,那么在 inference 阶段输出就要乘上 p,如下图所示:在这里插入图片描述
当然,很多深度学习框架会选择在 train 的时候乘上 1/p,在 inference 阶段不做处理,目的是减少 inference 时间,TensorFlow 就是这样处理的。

对 dropout 有效的解释也很多,有一种是,每次随机 dropout 一些连接,使得每次的网络结构不一样,相当同时在训练很多不同的网络,最后 inference 的结果是这些网络做 ensemble 的结果;另一种是,随机 dropout 一些连接,可以减小同一层神经元之间耦合度,dropout 逼迫每个神经元都只能依赖自己,大大减小了互相耦合造成的过拟合情况。

有兴趣可以看看 dropout 原始论文:Dropout: A Simple Way to Prevent Neural Networks from Overfitting

权重初始化

不同于简单的 LR 模型,神经网络参数众多,损失函数平面存在非常多的局部最优点,所以参数初始化是非常重要的(不过随着 BN 的出世,神经网络对初始化参数的敏感程度大大降低了)。

常用的有两种权重初始化方法: Glorot/Xavier 初始化和 MSRA 初始化。

Glorot/Xavier 初始化针对的是激活函数为 sigmoid 的情况,MSRA 初始化则针对激活函数为 ReLU 的情况做了优化。

TensorFlow 中变量默认的初始化方法是 Glorot/Xavier 初始化。

Glorot/Xavier 初始化方法是将权重按均值为 0,方差为
在这里插入图片描述

的分布进行初始化,其中 n_in 为输入神经元个数,n_out 是输出神经元的个数。这个公式是基于 sigmoid 激活函数推导出来的。

MSRA 初始化针对 ReLU 激活函数做了修正,只需要将 Glorot/Xavier 初始化方差乘以 2 就可以了。

有兴趣可以看看原始论文:
Xavier Initialization: Understanding the difficulty of training deep feedforward neural networks

MSRA Initialization: Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification

总结

从线性模型到神经网络,我们发现其实神经网络可以近似简单粗暴的理解为多个 LR 的组合体。后面我们继续探索了神经网络更深入更细节的东西,包含激活函数、Batch Normalization、dropout、权重初始化。每个点其实还可以更深入挖掘,限于篇幅,这里不展开,有兴趣可以自行探索。

最后给一个很好玩的网站:
http://playground.tensorflow.org
试试加多少层、多少神经元可以完美分开各个数据集,enjoy!

神经网络是一种模拟人脑神经系统的计算模型,它由多层神经元组成,能够通过学习调整权重和偏置等参数,从而实现图像识别、语音识别、自然语言处理等复杂任务。下面将从神经元、网络结构、激活函数、损失函数、优化器、正则化等方面详细介绍神经网络算法。 一、神经元 神经元是神经网络的基本单元,它接收多个输入信号,通过加权和运算和激活函数的处理,产生一个输出信号。神经元中的权重和偏置等参数可以通过训练调整,从而实现对输入信号的分类、回归等任务。神经元的公式如下: $$ y=f(\sum_{i=1}^n w_ix_i+b) $$ 其中,$y$表示神经元的输出,$f$表示激活函数,$w$表示权重,$x$表示输入信号,$b$表示偏置。 二、网络结构 神经网络的结构主要包括输入层、隐藏层和输出层,其中隐藏层可以包括多个层次。输入层接收输入数据,输出层产生输出结果,隐藏层通过多层神经元进行信息处理。神经网络的结构可以通过调整隐藏层数、每层神经元数量、激活函数等参数来优化网络性能。 三、激活函数 激活函数是神经元中的非线性函数,它通过对输入信号进行变换,产生非线性输出,从而使神经网络能够处理更加复杂的数据。常用的激活函数包括 sigmoid、ReLU、Tanh 等。激活函数的选择可以根据任务需求和网络性能进行调整。 四、损失函数 损失函数是神经网络中的一个重要指标,它用于衡量模型预测结果与实际结果之间的差距。常用的损失函数包括均方误差、交叉熵等。损失函数的选择可以根据任务需求和网络性能进行调整。 五、优化器 优化器是神经网络中的一个重要组件,它用于调整模型中的权重和偏置等参数,从而使损失函数最小化。常见的优化器包括随机梯度下降、Adam、Adagrad 等。优化器的选择可以根据任务需求和网络性能进行调整。 六、正则化 正则化是神经网络中的一个重要技术,它用于解决过拟合问题,从而提高模型的泛化性能。常见的正则化方法包括 L1 正则化、L2 正则化、dropout 等。正则化的选择可以根据任务需求和网络性能进行调整。 总之,神经网络是一种强大的计算模型,它通过多层神经元和非线性激活函数等操作,实现对复杂数据的处理和分类等任务。随着深度学习技术的不断发展,神经网络也将在更多领域发挥重要作用,为人类带来更多的智能化服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值