多层全连接神经网络(四)---简单的前向网络

神经网络神经元概念部分有需要会单独再讲

激活函数

1. Sigmoid

        Sigmoid 非线性激活函数的数学表达式是 σ(z) = \frac{1}{1+e^{-x}},其图形如图 3.14所示。目前我们知道 Sigmoid 激活函数是将一个实数输入转化到 0~1 之间的输出,具体来说也就是将越大的负数转化到越靠近 0,越大的正数转化到越靠近 1。历史上 Sigmoid 函数频繁地使用,因为其具有良好的解释性。

        但是最近几年,Sigmoid 激活函数已经越来越少地被人使用了,主要是因为 Sigmoid 函数有以下两大缺点:
        (1) Sigmoid 函数会造成梯度消失。一个非常不好的特点就是 Sigmoid 函数在靠近 1 和 0 的两端时,梯度会几乎变成 0,我们前面讲过梯度下降法通过梯度乘上学习率来更新参数,因此如果梯度接近 0。那么没有任何信息来更新参数,这样就会造成模型不收敛。另外,如果使用 Sigmoid 函数,那么需要在初始化权重的时候也必须非常小心如果初始化的时候权重太大,那么经过激活函数也会导致大多数神经元变得饱和,没有办法更新参数。
        (2) Sigmoid 输出不是以 0 为均值,这就会导致经过 Sigmoid 激活函数之后的输出,作为后面一层网络的输入的时候是非 0 均值的,这个时候如果输入进人下一层神经元的时候全是正的,这就会导致梯度全是正的,那么在更新参数的时候永远都是正梯度。怎么理解呢?比如进入下一层神经元的输入是,参数是 w 和 b。那么输出就是 f = wx + b,这个时候\triangledown f(w) = x,所以如果是 0均值的数据,那么梯度就会有正有负。但是这个问题并不是太严重,因为一般神经网络在训练的时候都是按 batch (批)进行训练的,这个时候可以在一定程度上缓解这个问题,所以说虽然 0 均值这个问题会产生一些不好的影响,但是总体来讲跟上一个缺点:梯度消失相比还是要好很多。

2. Tanh

        Tanh 激活函数是上面 Sigmoid 激活函数的变形,其数学表达为tanh(x) = 2\sigma (2x) - 1,图形如图 3.15 所示。

        它将输入的数据转化到 -1 ~ 1 之间,可以通过图像看出它将输出变成了 0 均值在一定程度上解决了 Sigmoid 函数的第二个问题,但是它仍然存在梯度消失的问题。因此实际上 Tanh 激活函数总是比 Sigmoid 激活函数更好。

3. ReLU

        ReLU 激活函数 (Rectifed Linear Unit) 近几年变得越来越流行,它的数学表达式为 f(x) = max(0,x),换句话说,这个激活函数只是简单地将大于 0 的部分保留,将小于0的部分变成0,它的图形如图3.16所示。

        下面我们简单来介绍一下 ReLU 激活函数的优缺点 。

        ReLU 的优点:
        (1) 相比于 Sigmoid 激活函数和 Tanh 激活函数,ReLU 激活函数能够极大地加速随机梯度下降法的收敛速度,这因为它是线性的,且不存在梯度消失的问题。
        (2) 相比于 Sigmoid 激活函数和 Tanh 激活函数的复杂计算而言,ReLU 的计算方法更加简单,只需要一个阈值过滤就可以得到结果,不需要进行一大堆复杂的运算。
        ReLU 的缺点:
        训练的时候很脆弱,比如一个很大的梯度经过 ReLU 激活函数,更新参数之后,会使得这个神经元不会对任何数据有激活现象。如果发生这种情况之后,经过 ReLU 的梯度永远都会是0。也就意味着参数无法再更新了,因为 ReLU 激活函数本质上是一个不可逆的过程,因为它会直接去掉输入小于0的部分。在实际操作中可以通过设置比较小的学习率来避免这个小问题。

4. Leaky ReLU

        Leaky ReLU 激活函数是 ReLU 激活函数的变式,主要是为了修复 ReLU 激活函数中训练比较脆弱的这个缺点,不将 x<0 的部分变成 0,而给它一个很小的负的斜率比如 0.01,它的数学形式可以表现为 f(x) = I(x<0)(\alpha x) + I(x\geq 0)(x),其中a是一个很小的常数,这样就可以使得输入小于0的时候也有一个小的梯度。关于 Leaky ReLU 激活函数的效果,众说纷纭,一些实验证明很好,一些实验证明并不好。

        同时也有人提出可以对a进行参数化处理,也就是说可以在网络的训练过程中对a也进行更新,但是否对所有情况都有效,目前也不清楚。

5. Maxout

        另外一种激活函数的类型并不是f(wx+b)作用在一种输出结果的形式,而是max(w_{1}x+b_{1}, w_{2}x+b_{2})这种 Maxout 的类型,可以发现 ReLU 激活函数只是 Maxout 中w_{1}=0,b_{1}=0的特殊形式。因此 Maxout 既有着 ReLU 激活函数的优点,同时也避免了 ReLU激活函数训练脆弱的缺点。不过,它也有一个缺点,那就是它加倍了模型的参数,导致了模型的存储变大。

        通过上面的部分我们简单地介绍了一些激活函数的优缺点,在实际我们使用较多的还是ReLU激活函数,但是需要注意学习率的设定不要太大了;一定不要使用 Sigmoid 激活函数,可以试试 Tanh 激活函数,但是一般它的效果都比 ReLU 和 Maxout 差。最后一点,我们在实际使用中也很少使用混合类型的激活函数,也就是说一般在同一个网络中我们都使用同一种类型的激活函数

神经网络的结构

        神经网络是一个由神经元构成的无环图,换句话说一些神经元的输出会变成另外一些神经元的输入,环是不被允许的,因为这样会造成网络中的无限循环。同时神经网络一般是以层来组织的,最常见的神经网络就是全连接神经网络,其中两个相邻层中每一个层的所有神经元和另外一个层的所有神经元相连,每个层内部的神经元不相连,如图 3.17和图 3.18所示。

        在之前的线性模型和 Logistic 回归中,我们已经接触到了 nn.Linear(in,out),它就是在PyTorch 里用来表示一个全连接神经网络层的函数,比如输入层4个节点,输出2个节点,可以用nn.Linear(4,2) 来表示,同时 nn.Linear(in,out,bias=False) 可以不使用偏置,默认是 True。

         一般而言,N层神经网络并不会把输入层算进去,因此一个一层的神经网络是指没有隐藏层、只有输人层和输出层的神经网络。Logistic 回归就是一个一层的神经网络。

        输出层一般是没有激活函数的,因为输出层通常表示一个类别的得分或者回归的一个实值的目标,所以输出层可以是任意的实数。

模型的表示能力与容量

        前面我们通过脑神经结构引出了神经网络的层结构,如果从数学的角度来解释神经网络,那么神经网络就是由网络中的参数决定的函数簇。所谓的函数簇就是一系列的函数,这些函数都是由网络的参数决定的。提出了函数簇之后,我们就想明确这个函数簇的表达能力,也就是我们想知道是否有函数是这个函数簇无法表达的?

        这个问题在1989年就被人证明过,拥有至少一个隐藏层的神经网络可以逼近任何的连续函数。如果一个只有一层隐藏层的神经网络就能够逼近任何连续函数,为什么我们还要使用更多层的网络呢?
        这个问题可以这么去理解,理论上讲增加的网络层可以看成是一系列恒等变换的网络层,也就是说这些网络层对输入不做任何变换,这样这个深层的网络结构至少能够达到与这个浅层网络相同的效果;同时在实际使用中我们也发现更深层的网络具有更好的表现力,同时有着更好的优化结果。

        在实际中,我们可能会发现一个三层的全连接神经网络比一个两层的全连接神经网络表现更好,但是更深的网络结构,比如4层、5层、6层等对全连接神经网络效果提升就不大了。而与此对比的是卷积神经网络的深层结构则会有更好的效果,下一章我们会详细介绍。
        知道了多层网络有着比较好的表现能力之后,如何来设置网络的参数呢?比如我们应该设计为几层,每层的节点又应该设计为多少个等。首先需要注意的是如果我们增大网络的层数和每层的节点数,相当于在增大网络的容量,容量的增大意味着网络有着更大的潜在表现能力,可以用图3.19来说明一下不同网络容量训练之后的效果。

        上面三张图分别是三个网络模型做二分类得到的结果,每个网络模型都是一个隐藏层,但是每个隐藏层的节点数目不一样,从左到右分别是3个、6个和20个隐藏节点,这三个模型训练之后得到的结果完全不一样,可以看到隐藏节点越多的模型能够表示更加复杂的模型,然而根据我们想要的结果,其实最左边的模型才是最好的,最右边的模型虽然有着更加复杂的形状,但是它忽略了潜在的数据关系,将噪声的干扰放大了,这种效果被称为过拟合(overfittimg)。
        从最右边的图片我们可以看出虽然模型成功地将红色的点和绿色的点完全分开但是却付出了很大的代价,将区域分割成了很多分离的区域,最左边的图虽然模型没能将所有的点都完全分开,但是形成了两个大区域,在实际应用中,这样的结果抗噪能力和泛化能力反而更强。
        通过上面的讨论,我们知道了如果数据不太复杂,那么容量较小的模型反而有着更好的效果,是不是我们可以用小的模型去处理呢?答案并非如此,首先通过这样的方式没有办法很好地衡量到底多小的模型才算是小的模型,其次小的模型在使用如梯度下降法等训练的时候通常更难。

        因为神经网络的损失函数一般是非凸的,容量小的网络更容易陷入局部极小点而达不到最优的效果,同时这些局部最小点的方差特别大,换句话说,也就是每个局部最优点的差异都特别大,所以你在训练网络的时候训练10次可能得到的结果有很大的差异。但是对于容量更大的神经网络,它的局部极小点的方差特别小,也就是说训练多次虽然可能陷人不同的局部极小点,但是它们之间的差异是很小的,这样训练就不会完全依靠随机初始化
        所以我们更希望使用大容量的网络去训练模型,同时运用一些方法来控制网络的过拟合,这些方法在之后会详细讲解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/873398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++蓝屏整人代码

文章目录 &#x1f4d2;程序效果 &#x1f4d2;具体步骤 1.隐藏任务栏 2.调整cmd窗口大小 3.调整cmd窗口屏幕颜色 4.完整代码 &#x1f4d2;代码详解 &#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&a…

笔记 7 :linux 011 注释,函 bread () , get_hash_table () , find_buffer ()

&#xff08;57&#xff09;接着介绍另一个读盘块的函数 bread&#xff08;&#xff09;&#xff1a; &#xff08;58&#xff09;因为 函数 get_blk&#xff08;&#xff09;大量调用了其它函数&#xff0c;一版面列举不完&#xff0c;故对其调用的函数先行注释&#xff1a;ge…

【Linux】服务器安装SSH

【Linux】服务器安装SSH 【创作不易&#xff0c;求点赞关注收藏】&#x1f600; 在Ubuntu服务器上安装并配置SSH非常简单。你可以按照以下步骤进行操作&#xff1a; 1、更新软件包列表 sudo apt-get update2、安装OpenSSH服务器: sudo apt-get install openssh-server3、启…

鲁大师2024半年报电动车智能排行:九号继续霸榜,极核本田乘胜追击

鲁大师2024年半年报正式发布&#xff0c;本次季报包含电动车智能排行&#xff0c;测试的车型为市面上主流品牌的主流车型&#xff0c;共计30款&#xff0c;全部按照评测维度更广、更专业的鲁大师电动车智慧评测2.0进行评分&#xff0c;测试的成绩均来自于鲁大师智慧硬件实验室。…

口袋奇兵游戏攻略:云手机辅助战锤入侵策略指南!

在《口袋奇兵》中&#xff0c;战锤入侵是一个重要的游戏环节&#xff0c;了解如何有效地参与战锤入侵能够帮助玩家获取更多的资源和提升自己的战力。本文将详细介绍战锤入侵的策略和技巧&#xff0c;帮助玩家在战锤入侵活动中取得更好的成绩。除了找到强力的游戏辅助&#xff0…

粉尘传感器助力面粉厂安全生产

在面粉加工行业中&#xff0c;粉尘问题一直是一个不容忽视的难题。从原料的破碎、研磨到成品的包装&#xff0c;整个生产流程中都会伴随着大量的粉尘产生。这些粉尘不仅影响生产环境&#xff0c;更对工作人员的健康、设备的安全运行以及环境保护构成严重威胁。因此&#xff0c;…

食堂采购系统开发:从需求分析到上线实施的完整指南

本篇文章&#xff0c;笔者将详细介绍食堂采购系统从需求分析到上线实施的完整过程&#xff0c;旨在为开发团队和管理者提供一个系统化的指南。 一、需求分析 1.用户需求 常见的需求包括&#xff1a; -采购计划管理 -供应商管理 -库存管理 -成本控制 -报表生成 2.系统功…

PyTorch使用细节

model.eval() &#xff1a;让BatchNorm、Dropout等失效&#xff1b; with torch.no_grad() &#xff1a; 不再缓存activation&#xff0c;节省显存&#xff1b; 这是矩阵乘法&#xff1a; y1 tensor tensor.T y2 tensor.matmul(tensor.T)y3 torch.rand_like(y1) torch.matm…

初步认识HTML

目录 一. HTML概述 二. HTML基本语法 1. HTML的基本框架 2. 标签 2.1 标签分类 2.2 标签属性 三. 基本常用标签 3.1 标题标签 3.2 段落标签 3.3 换行标签 3.4 列表 3.5 超链接 四. 特殊符号转义 五. 表格 5.1 表格的基本构成标签 5.2 表格的基本结构 5.3 表格属…

js reduce 的别样用法

let mergedItems list.reduce((accumulator, currentItem) > {let existingItem accumulator.find((item) > item.manObject_name currentItem.manObject_name);if (existingItem) {existingItem.laborCostHand currentItem.laborCostHand; //劳务费existingItem.wor…

增量预训练和微调的区别

文章目录 前言一、增量预训练和微调的区别二、代码示例1. 增量预训练示例2. 微调示例3. 代码的区别 三、数据格式1. 增量预训练2. 微调3. 示例4. 小结 四、数据量要求1. 指导原则2. 示例3. 实际操作中的考虑4. 小结 前言 增量预训练是一种在现有预训练模型的基础上&#xff0c…

有了这5个高效视频剪辑工具,你一定会爱上剪辑

如果你是个剪辑新手&#xff0c;不知道如何挑选剪辑视频的工具&#xff0c;又或者是自己目前使用的剪辑工具不理想&#xff0c;想寻找新的剪辑软件&#xff1b;那就请你看看这篇文章&#xff0c;这里介绍的5款剪辑软件都是专业&#xff0c;简单&#xff0c;又高效的剪辑工具。 …

顺序表<数据结构 C版>

目录 线性表 顺序表 动态顺序表类型 初始化 销毁 打印 检查空间是否充足&#xff08;扩容&#xff09; 尾部插入 头部插入 尾部删除 头部删除 指定位置插入 指定位置删除 查找数据 线性表 线性表是n个相同特性的数据元素组成的有限序列&#xff0c;其是一种广泛运…

解决警告Creating a tensor from a list of numpy.ndarrays is extremely slow.

我的问题是创建一个列表x[]&#xff0c;然后不断读入数据使用x.append(sample)&#xff0c;chatgpt说这样转化比较低效&#xff0c;如果预先知道样本个数&#xff0c;可以用numpy来创建数组&#xff0c;再用索引x[i]sample赋值第二种方法更快&#xff0c;直接用numpy转化一下np…

04 Git与远程仓库

第4章&#xff1a;Git与远程仓库 一、Gitee介绍及创建仓库 一&#xff09;获取远程仓库 ​ 使用在线的代码托管平台&#xff0c;如Gitee&#xff08;码云&#xff09;、GitHub等 ​ 自行搭建Git代码托管平台&#xff0c;如GitLab 二&#xff09;Gitee创建仓库 ​ gitee官…

Gitee使用教程2-克隆仓库(下载项目)并推送更新项目

一、下载 Gitee 仓库 1、点击克隆-复制代码 2、打开Git Bash 并输入复制的代码 下载好后&#xff0c;找不到文件在哪的可以输入 pwd 找到仓库路径 二、推送更新 Gitee 项目 1、打开 Git Bash 用 cd 命令进入你的仓库&#xff08;我的仓库名为book&#xff09; 2、添加文件到 …

Spring-Boot基础--yaml

目录 Spring-Boot配置文件 注意&#xff1a; YAML简介 YAML基础语法 YAML:数据格式 YAML文件读取配置内容 逐个注入 批量注入 ConfigurationProperties 和value的区别 Spring-Boot配置文件 Spring-Boot中不用编写.xml文件&#xff0c;但是spring-Boot中还是存在.prope…

【Qt+opencv】基础的图像绘制

文章目录 前言line函数ellipse函数rectangle函数circle函数fillPoly函数putText函数总结 前言 在计算机视觉和图像处理领域&#xff0c;OpenCV是一个强大的库&#xff0c;提供了丰富的功能和算法。而Qt是一个跨平台的C图形用户界面应用程序开发框架&#xff0c;它为开发者提供…

参与开源项目 MySQL 的心得体会

前言 开源项目的数量和种类都在急剧增长&#xff0c;涵盖了从操作系统、数据库到人工智能、区块链等几乎所有的技术领域。这为技术的快速创新和迭代提供了强大的动力&#xff0c;使得新技术能够更快地普及和应用. 目录 经历 提升 挑战 良好的编程习惯 总结 经历 参与开源…

微信小程序-实现跳转链接并拼接参数(URL拼接路径参数)

第一种常用拼接方法&#xff1a;普通传值的拼接 //普通传值的拼接checkRouteBinttap: function (e) {wx.navigateTo({url: ../checkRoute/checkRoute?classId this.data.classInfo.classId "&taskId" this.data.classInfo.taskId,})}第二种&#xff1a;拼接…