简介/目录:
神经元模型
人工神经网络
常见代价函数/损失函数
梯度下降
正向/反向传播
神经网络训练
人工神经元
上图为一般的人工神经元的结构,下述简单介绍一下其结构:
人工神经元的输入的x为来自上一级神经元的输出或输入层的低维特征,每一个神经元内存在n个w 与对应的输入的x相乘,这里可以表示为两个矩阵的内积(w的转置与x相乘),结果为一个标量,后加一个偏执b,偏执的目的是使得模型不完全根据输入的参数发生变化,提升模型的稳定性。
最后套一个()为激活函数,使得神经元的输出与输入成非线性的关系,这里激活函数非常重要,由于神经元的本身的计算的输入与输出为线性关系,如果不加非线性的因素,多层神经元的累加会失去意义,如:
所以我们需要对神经元的输出前加一个激活函数,即一点非线性的因素,这里给出一些常见的激活函数:
上图每个函数右侧的图的横坐标是函数输入的值,纵坐标为激活函数的输出值,不同的激活函数有不同的映射区间,导致适合的使用场景不同,具体的需要看我们希望输出的数映射的区间是什么:
例如,我们有两个标签,其中-1对应猫,1对应狗,那我们需要tanh,因为他会将神经元的输出值确定在(-1,1)的区间中,如果是0/1作为标签的话,我们需要使用sigmoid,因为他的输出的区间是(0,1),上述的两个激活函数tanh与sigmoid更适合二分类的任务,当然能完成二分类就意味着一定可以完成多分类的任务(例如在手写数字识别的任务过程中,识别0的话就将1-9看为一类,0单独作为一类,只不过面对不同的数时分类的方式不同而已,简而言之对于一个类别只有两个可能“是”or“不是”)。
除了tanh与sigmoid,其他的relu,leaky-relu,softplus中最常用的是relu,因为简单,负数就输出0,正数就是本身,但简单的同时,会存在一个很严重的问题dead-relu,当输入全为负数时,模型无法更新了,因为全为0,这里就需要使用leaky-relu,他会在负数输入时,给模型一点的反馈,以至于不会陷入无法更新的死循环,然后softplus对比relu更加平滑,但是同时增加了计算量,因为我们更新模型时需要通过求偏导进行参数更新,神经元数量太多时一点点的计算量累加后都会导致训练时间过长,所以需要灵活选择激活函数。
人工神经网络
上图是一个神经元构成的神经网络,神经网络就是多层的神经元的堆叠,在神经网络中我们的层数通常只指的是计算层(隐藏层+输出层),图中的计算式是第l层(从左往右,此时图中的最后一层)的第i个(从上往下)神经元中的计算过程,是当前神经元的计算结果,fl()是激活函数,
里面的则是当前神经元的计算结果,计算结果是当前神经元内的w(一个神经元内的w的数量与上一层所有的神经元数相同,因为需要一一相乘)与上一层所有的神经元计算结果的两个矩阵的内积,再加上偏执b,神经元内部的操作是和第一部分神经元的操作一模一样的,只不过这里是换了字母。
这张图片的计算是面对一个神经元层看的,图中的棕色方块是当前层的所有神经元(假如m个)的所有w(假设单个神经元有n个w),那么是一个m*n的矩阵,只代表当前层的所有w,而它与上一层神经元的计算结果进行矩阵乘法再加上则相当于本层神经元的参数计算。
本图上半部分是对神经元计算的解释接上图,是m*n的矩阵(其中存放一个神经元层所有的w),是m*1的矩阵(其中是神经元层中从上往下每一个神经元的偏执b),与则是对于单个神经元而言,他们数量由上一层神经元数个n决定。
图片的下半部表示方法可以进行简化,可以将合并于(列数加1),注意这里只是将偏执省略,并非不加偏执。
上图给出神经网络模型,二分类可以有一个或两个输出,多分类一般根据类别决定输出数。
代价函数/损失函数
损失函数与代价函数不同的人对他们有不同的认识,这里就只默认两者都代表训练过程中的Loss
他的作用是根据神经网络的输出y^,计算输出与我们的标准值y的相似分数,此分数是更新模型的根据。
MSE:对奇异值更关注/MAE:对奇异值不太关注
Quant:适合有偏估计即同方向的不同值的预测结果对损失的影响不同。
交叉熵损失是对于分类任务较为适合的损失,上图给出了二分类与多分类的损失函数。
这里注意:损失函数关于y^为凸函数,以确保一定要有最优解,但是关于网络中的参数w与b我们不确定他们直接的凹凸关系(由于存在激活函数)。
梯度下降
梯度下降的本质:一种使用梯度去迭代更新权重参数使目标函数最小化的方法。
对于一个函数,梯度是函数值上升最快的方向。
由于希望损失函数尽可能小,我们的问题找最优解是一个最小值点,对于一个函数我们需要在所有可更新参数(网络中的w与b)作为自变量去找他们在函数中的最优解法(找全局的最小值),所以梯度反向的方向是我们找极小值的方向,我们通过不断给模型新的输入变量,计算损失后,根据损失函数不断更新w与b,直到找到一个极小值,然后重新随机初始化一个点,再重复更新参数的过程,尽可能找到多个极小值,再挑选出其中的最小值,这就是梯度下降的方法解释。
对于梯度下降法,现在有三种常用的办法,各有优劣这里给出:
正向/反向传播
正向传播是根据输入值(低维度特征)经过神经元网络后得到输出的过程
反向传播则是根据最后的损失函数对神经网络中每一个神经元的w与b求出偏导数后更新的过程
以下为基本公式包括链式法则与常量对于矩阵求导得到的结果,且结果矩阵与原矩阵规格一样
注意我们求的是损失函数关于某一个w或b的偏导数,下图是公式虽然公式有一点复杂,但是本质就是在求函数对神经元的参数的偏导数。
神经网络训练
神经网络的训练完整流程如下:
了解上述理论基础后,我们就可以手搓一个pytorch了,当然还需要一些额外的算法支持和cuda的编程加快训练速度,不过这些知识作为深度学习的基础需要牢牢掌握,后续继续更新python实现神经网络框架的内容