1单层感知器概述单层感知器(Single Layer Perceptron)是最简单的神经网络。它包含输入层和输出层,而输入层和输出层是直接相连的。单层感知器属于感知器中最简单的一种分类器,属于机器学习的范畴。尽管单层感知器在网络结构上极其简单,但它所包含的组成部分却是后续各种复杂神经网络模型中都会包含的基础组件。比如激活函数、权重、偏置值、输入输出、损失函数、优化器等等。其实当我们把一个个复杂的神经网络模型拆分来看,也就是一个个单层感知器的有机统一。因此,最大限度地读懂单层感知器的工作原理,特别是关于单层感知器中权重系数的推导迭代过程,可以为后续的复杂网络模型的理解打下一个坚实的基础。接下来我们简单看一下一个典型的单层感知器的网络结构图,并依据这个图来做一些有关单层感知器的基本介绍:

图1 单层感知器结构图

2单层感知器基本知识点让我们对照着图1来仔细感受一下单层感知器的基本知识点:首先,单层感知器需要有输入,也即图中的x1,x2,x3等。注意,这里的输入通常都是说的一个数据样本X的各个特征分量,也就是我们在机器学习中所学习过的那样。其次,我们再看每个特征输入都会对应着一个输入节点,这个输入节点我们称之为输入神经元,而所有的输入神经元汇总在一排上,就构成了输入层神经元,简称输入层。然后,连接特征输入与每个输入神经元的都是一条带方向的直线,从输入指向输入神经元,我们称这个方向为前向,其反方向称之为后向。前向、后向是至关重要的两个方向,这在后面的BP算法介绍中尤其重要。再次,我们看到图1中还存在着输出节点,我们称之为输出神经元。输出神经元个数不限,最简单的就是如图1所示的一个,也可能存在着多个。注意:所谓的单层感知器并非指的是输出神经元个数为1的感知器模型,而是说除去输入节点和输出节点之外,再无其他类别的神经元,比如后面我们要提到的前馈神经网络等复杂神经网络中的各种隐藏层。因此,我们可以简单地理解为单层感知器其实就只有输入层和输出层,没有隐藏层。第四,在输入层神经元与输出层神经元之间也存在着一条带方向的连接线,所指也是从输入层到输出层。这也是前向。并且,在这些带方向的连接线上都存在着一个个被冠以wi的变量,这样的变量,我们称之为权重。如同我们在机器学习中学习广义线性模型时看到的那个数学公式那样,这里的权重就等价于那个数学公式中各个特征分量xi前的那个系数。其意义也是表征在某一层面上的某个特征的重要性。在图1中,三个权重值均为:0.3。此外,通常的神经网络模型(包括单层感知器),其每一层神经元都会有一个统一的偏置值,我们称之为b,英文简称为bias。这个偏置值能够起到一定的修正作用,比如当最终结算结果可能有些走极端时,它就好比是一位好心大叔,能够把它往回拉一点点,使之不至于太“离经叛道”。偏置值在图1中体现的形式为t=0.4。第五、在输出神经元上,我们通常看到的是一个完整的神经元节点,但实际其内部计算通常会被划分为两部分:第一部分:对该神经元的各个方向来的输入值进行线性加权求和,即:input=w1*x1+w2*x2+w2*x2+t注意,这里的t实际就是偏置值:b第二部分:对input进行某种函数映射,使得最终的输出结果落在一个指定的范围之内。通常这个范围都会在[-1,1]之间选择,可能是[0,1],也可能就是[-1,1]。甚至有可能是几个离散的取值,当然这些取值依然会在[-1,1]之间来取。为了能够做到这种映射结果,我们在这个输出神经元上使用一种被称之为非线性变换的函数。这样的一种映射函数也被称之为激活函数。在单层感知器中,比较常用到的激活函数为符号函数:

图2 单层感知器激活函数

从这个激活函数,我们不难看出一点:单层感知器天然就很适合做一个分类器来使用。而且当单层感知器的输出神经元个数大于1时,还能承担多分类器的重担。只需要我们对所有的真实标签采取One-Hot编码即可。比如我们有一个多分类问题,已知的数据类别有n种,则采用One-Hot编码,提供一个二进制位数为n的整数,某一位取值为1,则表示当前数据样本被识别成是某个类别:例如,第m位被置为1,则表示当前学习的数据的标签大概率是第m类。要做到这一点,就需要在单层感知器上设计出n个输出神经元。在每个神经元上都开展线性加权求和以及对求和结果开展符号函数变换,这样每个输出神经元都只能输出1或者-1。而我们把-1看成是0,即可满足上述要求。

第六,同样发生在输出神经元上的事情就是如何来衡量对每一个数据样本的学习结果好坏。此时我们通常利用一个叫损失函数的机制来帮助我们实现这样的好坏度量。

所谓损失函数,是指对于每一个输入数据的训练,总会产生一个预测值,但大多数情况下,这个预测结果并不绝对等于实际的真实结果。因此,在预测结果与真实结果之间就必然有一定的误差,我们称这样的误差为损失。利用这样的损失所建立的函数就称之为损失函数。

在单层感知器中,常用到的损失函数有这么几种:

MAE:平均绝对误差(误差的绝对值的平均值)。意思就是说如果输出层有L个神经元,每个神经元上都必然存在这一个误差,把这些误差取绝对值之后相加,再除以输出层神经元个数L,则为本次输入数据学习之后所得到的损失值。围绕这个损失值我们就可以建立一个相应的损失函数。

MSE:均方误差(误差的平方和的平均值)。也就是说让所有的误差值求平方之后再汇总求和,而后对求和结果除以L得到的平均值即为本次输入数据学习过后的损失值。

SSE:误差平方和,它与MSE的区别在于不再需要求平均值,其余计算过程保持不变。

在后续的复杂神经网络或深度学习模型中,上面这三种损失值的计算函数也通常会被用到。不过在高级的深度学习模型中,还存在着其他不同的损失值计算函数。这一点我们在介绍深度学习相关算法时也会重点提到。

损失函数,可以说是神经网络或者深度学习算法的根所在。正是因为存在着如何度量学习结果好坏的损失函数,我们才能够基于这个损失函数来推导出神经网络模型中的各个神经元上的权重参数和偏置值参数,并最终建立起一个高效的学习模型。

因此,损失函数是我们必须要重点掌握的。当然我们如果能够把损失函数的原理搞得通透固然最好,如果不能,也可以先记住有哪些损失函数及其对应的名称缩写,以便我们能够依葫芦画瓢地去使用其中某个损失函数。

第七,学习率:η。当我们计算出每一次输入数据学习过后的损失值时,我们希望利用这个损失值来反向推导各个神经元上的权重参数与偏置值参数的最新值。此时,我们在推导过程中就会考虑学习率的存在。

学习率是指导我们,在梯度下降法中,如何使用损失函数的梯度调整网络权重的超参数。

学习率如果过大,可能会使损失函数直接越过全局最优点,此时表现为loss过大或者为无穷大值;

学习率如果过小,损失函数的变化速度很慢,会大大增加网络模型训练的收敛复杂度,延长训练时间,并且很容易被困在局部最小值附近。

这是在一般意义上的一种数学解释。通常我们认为学习率就是一个以合理的速度来寻找最优的权重参数值和偏置值参数值的参数而已。

这个学习率通常会被设置得比较小,比如0.1、0.01、0.001、0.0001等。

学习率是不可或缺的,至少在现在的深度学习算法中,还真就找不出几个不用到学习率的地方。所以大家也需要对此有一个正确的认识。在每一次的DL训练时都要显示地指明学习率是多少。

PS:在后续的神经网络发展历程中,大拿们又对单层感知器的激活函数做了扩充处理。其实这一点我们在介绍机器学习等知识就曾专门提到过有关激活函数的知识,并且列举了当前常见的一些激活函数,这里再列举如下:

图3 常用的激活函数汇总表截图

在这种汇总表中,我们在后续的神经网络模型或深度学习模型中,广泛使用的又是诸如:sigmoid函数、relu函数、tanh函数、PRelu函数等。以后我们还会专门提到这些激活函数的妙用之处。在这里大家姑且记住有这些激活函数,以及这些激活函数的基本形式、取值范围即可。

以上五部分就是有关单层感知器的基本知识点所在。围绕着这些知识点,我们就可以来重点阐述其工作原理。

3单层感知器工作原理

在理解单层感知器的基本知识点之后,我们就需要来弄明白单层感知器的基本工作原理,看看单层感知器究竟学习的是个啥,又是如何学习的。弄清楚这个工作原理非常重要,因为我们已经不止一次说过:不管多么复杂的神经网络或深度学习模型,其核心要素就是由一个个神经元组成的。而单层感知器实际上我们就可以被简化为一个神经元(假如我们把输入神经元与各个特征输入融为一体的话。)。因此,弄懂单个神经元的工作原理就显得十分必要。此外它还是多层感知器、前馈神经网络等复杂神经网络模型中所用到的“误差反向传播”算法的一个理论基础所在:即如何通过输出层来反向推导出坐落在不同连接线上的各个权重参数值以及偏置值等。

可以简单地说就是:单层感知器也好、多层感知器也罢,甚至是更复杂的深度学习模型,其最终所要学习到的就是坐落在这些有向的连接不同神经元之间的连接线上的权重系数以及每一层神经元的一个偏置值。

注意:我们这里说的是连接不同神经元之间的连接线。因此不论在不再同一层,只要是神经元之间有一条有向的连接线,那就需要对该连接线上的权重展开学习。

现在我们就来聊一聊单层感知器的基本工作原理:

第一步:为输入数据、各个权重、偏置值赋值初始值,具体取值,各位随意取,但有一个经验很完美地表明:权重值、偏置值的初始值还是尽量小一点比较妥当。通常都会利用Numpy库或者TensorFlow库中的正态分布函数来帮我们选择一批初始权重。

第二步:利用图2中的output的表达式来开展输入特征的线性加权求和;

第三步:再选用图2的激活函数来对加权求和结果进行映射,得到的预测结果我们标记为oj,而该样本的真实结果,则即为:dj;j表示第j次的输入数据的学习。

第四步:求出本次学习结果的损失值:

                           (1)

第五步:利用公式(1)求出的损失值来更新权重参数与偏置值参数:

                                                                          (2)

这里的i表示的是第i个权重参数,j表示的是第j次的输入数据的学习。

同样的逻辑,我们可以计算偏置值的更新过程如下:

                                                                                             (3)

PS:请注意,由于我们这里采用的是符号函数作为激活函数,因此可以直接利用公式(2)和公式(3)来分别更新权重参数与偏置值参数。但在实际的复杂神经网络模型中,我们通常都会利用其它激活函数,且这些激活函数是可以求导数的。因此在其他场合下,我们将利用对激活函数的求导结果结合损失值来更新权重参数与偏置值参数。

第六步:判断当前的训练结束条件是否满足:

、模型训练过程中所产生的损失值已经小于我们给定的一个阈值:δ。如果已经小于,则本模型的训练过程结束。但在单层感知器中,我们使用的激活函数为符号函数,因此,在这里我们并不适用条件来作为判断模型训练是否结束的标准。采用的是下面这两条准则之一。

、在指定的训练次数之内,判断前后两次训练的权重之差是否已经小于给定的一个阈值:ε,如果已经小于,则判定本模型的训练过程结束;

、如果条件尚不满足,但已经训练了足够的训练次数,比如我们指定的最多500次训练,则同样结束本模型的训练。

第七步:如果判断模型训练结束条件不满足,则继续回到第二步,并继续新一轮学习过程。

4单层感知器的TensorFlow实现

理解了单层感知器的具体知识点以及工作原理之后,我们接下来就利用所学习的TensorFlow知识来实现一下这样的一个简单的单层感知器。在这里稍微说明一下,为了能够利用TensorFlow库中给我们提供的一个自动求导机制:tf.GradientTape()。我们在以下代码中所示的单层感知器实现中使用的激活函数为Sigmoid函数。此时我们就需要考虑对损失值进行求导了。至于利用Sigmoid函数怎么来求导,我们在多层感知器以及更为复杂的BP算法的介绍中会专门提到,这里仅简单列出以下Sigmoid函数的求导结果:

接下来我们就来看看这个简单的单层感知器的实际代码:

import tensorflow as tf

x = tf.Variable(tf.random.normal([5,3]))#5个样本,3个特征参数

y = tf.constant([0,1,0,1,0])#实际标签值

w = tf.Variable(tf.random.normal([3,1]))#3维将为1维

b = tf.Variable(tf.zeros([1]))

with tf.GradientTape() as tape:

output = x@w + b

out = tf.sigmoid(output )

loss = tf.reduce_mean(tf.losses.MAE(y,out))

res = tape.gradient(loss,[w,b])

dw = res [0]

db = res [1]

print('dw = ' + str(dw))

print('db = ' + str(db))

其运行结果截图如下:

代码简单解释如下:

tf.Variable:生成一个tf的张量;

tf.random.normal([5,3]):从标准正态分布中随机生成一个shape为5行3列的数组张量;

tf.constant:生成一个tf的张量,是一个常量;

tf.zeros([1]):生成一个shape为1一个元素的一维向量,元素值为0;

with tf.GradientTape() as tape:TensorFlow库中提供的一个自动求导机制的惯用写法,大家只需要这么记住即可;

x@w:在TensorFlow库中,提供的两个张量数组相乘运算符;注意:相乘的两个矩阵必须要满足一个要求:矩阵x的列数必须等于矩阵w的行数。

tf.sigmoid(output ):使用TensorFlow库中的sigmoid()函数来作为激活函数,对output结果进行激活处理;

tf.reduce_mean():计算用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。在这里主要计算损失值的平均值;

tf.losses.MAE(y,out):利用TensorFlow库中的losses模块内的MAE()函数(即:平均绝对误差)来计算损失值,需要提供真实值与预测值。由于真实值与预测值都是一个同shape大小的数组张量,故而可以使用tf.reduce_mean()函数来计算平均值。

tape.gradient(loss,[w,b]):利用TensorFlow库中的启动求导机制的gradient()函数来对损失函数开展求导运算。需要输入的参数有:

损失函数;

需要开展求导的参数列表,比如这里的权重参数与偏置值参数等。

res [0]/res [1]:自动求导结束之后,我们所计算出来的权重参数就被存储在求导结果的第0个元素上,偏置值则存放于第1个元素上。

以上就是一个单层感知器的具体代码实现以及代码简介。

这里顺带提一个小问题供大家思考,如果我们不使用TensorFlow的自动求导机制,且激活函数选择为符号函数sgn(),那么又该如何来实现?

5总结

到此为止,我们就简单介绍了有关单层感知器的基本原理、知识点、工作机制以及简单的代码实现与代码简介。

单层感知器天然适合开展线性可分的问题解决工作。但对于一些非线性问题,比如异或问题处理,就会显得很苍白无力。此外,单层感知器还缺乏泛化能力。对离群点的检测也需要花费更多的时间和精力。因此总得来说单层感知器在实际使用中还是存在比较大的局限性,特别是现在这种AI越来越普及的时代,已经很难再寻觅到有关单层感知器的使用场景,

但不管怎么说,单层感知器为我们打开了一扇通往神经网络乃至深度学习领域的大门。而且正是由于前辈们对单层感知器的不断完善改进,才有了后来的多层感知器等前馈神经网络、深度置信网络、卷积神经网络、循环神经网络等更加高级的神经网络算法。

因此,我们说单层感知器是我们理解研究其他神经网络的基础,其学习训练规则对于其他神经网络的权重训练有极为重要的意义。这里也希望大家多揣摩揣摩它的意义。

OK,本节知识的分享就到此为止,谢谢大家!下一节我们继续分享梯度下降算法、BP算法的相关知识,届时不见不散!

为什么在反向传播中感知器初始值不能为0_深度学习理论分享之——单层感知器简述...相关推荐

  1. 为什么在反向传播中感知器初始值不能为0_人工智能可以为我们做什么?世界皆可二分类...

    三大门派之符号主义 认为人工智能源于数理逻辑,其代表性的成果为启发式程序LT逻辑理论家,它证明了38条数学定理,表明了可以应用计算机研究人的思维过程,模拟人类智能活动.在这过程中,最重要的实际应用就是 ...

  2. Batch Normalization函数详解及反向传播中的梯度求导

    摘要 本文给出 Batch Normalization 函数的定义, 并求解其在反向传播中的梯度 相关 配套代码, 请参考文章 : Python和PyTorch对比实现批标准化Batch Normal ...

  3. 将上述代码中的crc初始值改为0

    要将上述代码中的CRC初始值改为0,只需要将crc的初始值从0xFFFF更改为0即可,代码如下: def crc16(data: bytes) -> int:crc = 0for byte in ...

  4. 推导反向传播中的dZ=A - y

    在吴恩达老师的反向传播课程中,涉及到如下公式: ,在向量化后为 ,下述为推导过程: 因为 ,且,在最后一层网络中 故 在逻辑回归中,损失函数 故 又因为,在文章中所述的网络结构中,最后一层激活函数g( ...

  5. 数组中没有给初始值_Array中的reduce()、filter()、map()几张图搞懂

    数组中reduce()函数与过滤filter()和映射map()有什么区别? 先来看看reduce()这个函数,废话不多说,直接上代码 在这里,你很好奇为什么是11,让我们来看下,首先reduce() ...

  6. matlab中memory模块初始值,Matlab的memory模块消除代数环

    什么是代数环? 发生在两个或多个模块在输入端口具有信号直接传递而形成反馈的情况时,直接传递的模块在不知输入端口的值的情况下无法计算出输出端的值,也就是现在时刻的输出是依赖现在时刻的输入值来计算的.当这 ...

  7. 机器学习--多标签softmax + cross-entropy交叉熵损失函数详解及反向传播中的梯度求导

    https://blog.csdn.net/oBrightLamp/article/details/84069835 正文 在大多数教程中, softmax 和 cross-entropy 总是一起出 ...

  8. SQL中变量赋初始值的重要性

    首先准备一些测试数据, create table tynametable ( id int, typename nvarchar(10) ) insert into tynametable value ...

  9. java char 默认值_java 中char 的初始值

    jdk官方教程里有写 Default Values(缺省值) ----------------------------------------------------- |Data Type |Def ...

最新文章

  1. linux 入侵检测
  2. python 类-9. 类 — Python 3.9.0 文档
  3. 计算机动画---动画序列的设计
  4. CMake结合Visual Studio中开发Qt应用程序注意事项
  5. x3m文件怎么转换成mp3_视频中的音频怎么单独提取出来转换成mp3格式
  6. OpenGL剪切平面和双面渲染
  7. er图外键怎么表示_本周话题:取消考研复试最能实现相对公平?你怎么看?
  8. OCIEnvCreate 失败,返回代码为 -1的解决方法
  9. LeetCode:Restore IP Addresses
  10. html 怎么几秒后自动隐藏,js设定DIV显示时间并动态显示时间倒计时多少秒,倒计时完了之后该层自动隐藏。...
  11. Qt调用jrtplib实现单播、多播和广播
  12. hive if函数_数据仓库,Hive中使用 != 或 lt;gt;; 符号进行条件过滤时的坑
  13. 车辆运动控制(2)车辆横摆动力学建模
  14. java复习/学习流程
  15. 初探ViewBinding
  16. 遗传算法之:八皇后问题
  17. Wangle源码分析:Service
  18. 掌握python和js_新华字典:掌_“掌”的意思,五笔,笔画,拼音,五行_HttpCN
  19. endnote中CWYW无文件_文献管理工具(三):EndNote 操作指南(免费在线版)
  20. 程序员教你如何追女生

热门文章

  1. MMSE法用于MIMO系统
  2. 二十万字C/C++、嵌入式软开面试题全集宝典六
  3. SEO全套精品教程价值300元[159课]
  4. [云炬创业基础笔记]第六章商业模式测试11
  5. ustc小道消息20220122
  6. 云炬Android开发笔记 12基于WebView的混合App框架设计(包含浏览器与原生请求Cookie的处理)
  7. VTK修炼之道63:纹理映射体绘制_二维纹理映射
  8. 为TIF、JPG图片添加地理坐标/平面直角坐标
  9. C#反射技术之一动态读取和设置对象的属性值
  10. “sql2005管道的另一端上无任何进程”及附带一系列问题完整解决方法