RNN循环神经网络及其梯度消失笔记

 资料来源

【重温系列】RNN循环神经网络及其梯度消失 手把手公式推导+大白话讲解

 带时间序列的任务场景

 

标准神经网络建模的弊端

 RNN循环神经网络

网络结构

多输入,多输出

这里的就是对应识别人名的任务,输入就是这里的x1,x2,输出的自然就是0或1了

这种串联的结构,后面的状态会受到前面状态的影响

单元

输入的部分有一个我们的x还有前一个状态a^{t-1}

然后这两个进来之后要分别乘以一个相应的权重,再加上我们的一个偏置项b_{a}

然后再通过tanh激活函数,由此来生成下一个状态就叫做a^{t},然后再继续传给下一个单元

这里我们还有一个输出的\hat{y}^{t},,在这之间还有一个权重矩阵w_{y},相乘之后再加上一个偏置项w_{y},然后才能输出我们的\hat{y}^{t}。这里的\hat{y}^{t}要看我们的任务是如何定义的,如果我们是一个多分类就接一个softmax,如果是二分类就接一个sigmoid。

我们的这里是一个多输入,多输出的一个结构我们也完全可以是多输入,然后在最后一个节点进行输出。

比如上面的情感分类,我们输入的是一段话,上面输出的是一个评分的预测。

那么我们如何去理解这个单元呢?

我们可以用人脑来进行比喻,a^{t-1}比如是跟男朋友吵架的一个状态,是很恼火的,x^{t}是你的闺蜜进行了一顿输出,输入到了你的大脑,然后两者结合就产生了一个意识,就生成了一个新的状态,新的状态也就是说要跟男朋友分手,那么这个就是新的状态。然后这个softmax就是将想法落实成真正的一个行动,就是产生的一个结果。W_{ax}这些参数/权重就可以想象成人脑当中的各种神经,各种连接或者是思维习惯。

特点

前向传播

损失函数

损失函数的作用

损失函数在机器学习和深度学习中扮演着至关重要的角色,它是评估模型预测与真实值之间差距的指标。损失函数的选择对于模型的训练和性能至关重要。下面是损失函数的一些用途和常见类型:

  1. 模型训练: 在模型训练过程中,损失函数被用来度量模型的预测值与真实值之间的差距。通过最小化损失函数,我们可以使得模型的预测值逐渐接近真实值,从而提高模型的准确性。

  2. 模型评估: 损失函数也可以用来评估模型的性能。在训练过程中,我们通常会在训练集上计算损失函数的值,并在验证集或测试集上进行评估,以了解模型的泛化能力和性能。

  3. 优化算法: 优化算法(如梯度下降)使用损失函数的梯度来更新模型的参数,以最小化损失函数的值。损失函数的梯度指导着优化算法沿着参数空间中的哪个方向更新参数,从而使损失函数逐渐减小。

常见的损失函数包括:

  • 均方误差(Mean Squared Error, MSE): 用于回归任务,计算预测值与真实值之间的平方差的均值。
  • 交叉熵损失(Cross-Entropy Loss): 用于分类任务,特别是在多分类任务中,衡量模型对于真实类别的预测与真实情况之间的差距。
  • 对数损失(Log Loss): 也称为逻辑损失,是交叉熵损失在二分类任务中的特例,通常用于评估二分类模型的性能。
  • Hinge Loss: 用于支持向量机(SVM)中的分类任务,对于正确分类的样本,损失为0,对于错误分类的样本,损失为真实类别与最近边界的距离。
  • Huber Loss: 一种鲁棒的回归损失函数,相比于均方误差对异常值更具鲁棒性。

单个时间步的损失函数

如果是多输入,多输出的一个结构,一个输入就对应了一个输出,每个时间步就有一个y的输出,因此我们要对单个时间步进行损失的计算

比如我们这里举的例子,判断是否为人名,这里的输出\hat{y}^{t}要么是0,要么是1,那么我们这里的softmax就可以用sigmoid来代替。

如果是二分类任务,我们的损失就可以用交叉熵损失

就像是这个样子

整个序列的损失函数

然后我们整个序列的损失函数就是把所有时间步的损失加起来

这里就有一个求和符号,对应就是把我们的所有损失加起来。

反向传播

有了损失函数我们据需要进行反向传播,更新我们的这些参数。

我们需要更新的参数有哪些呢?

首先就比如说我们的W_{aa},W_{ax},b_{a}W_{ya},b_{y}这三个就是我们要更新的参数

由于需要用到我们的链式法则,对这些参数进行更新的时候,我们需要对a^{t},就是对上面的那些参数去进行求梯度,求导的这样的一个过程,所以我们需要把这些求导的公式整理一下

为什么要求梯度?

梯度在反向传播参数更新中起着关键作用,主要原因如下:

  1. 指示参数更新方向: 梯度告诉我们在参数空间中,损失函数增加最快的方向。在梯度下降优化算法中,我们希望最小化损失函数,因此需要朝着梯度的负方向更新参数,以减小损失函数的值。

  2. 确定参数更新步长: 梯度的大小表示了损失函数在当前参数值处的斜率,即损失函数变化的速度。因此,梯度的大小也指示了参数更新的步长,通常我们会使用学习率(learning rate)来调节梯度的大小,以控制参数更新的幅度,避免更新步长过大或过小。

  3. 优化模型参数: 通过梯度下降更新参数,可以不断优化模型,使其逼近或达到最优解。通过反复迭代计算梯度并更新参数,我们可以逐步降低损失函数的值,从而改善模型的性能。

总之,求梯度是反向传播参数更新中至关重要的一步,它为我们提供了更新方向和步长的信息,指导着模型在参数空间中不断优化,以使损失函数达到最小值或接近最小值。

具体应该怎么做

反向传播具体应该怎么做还是应该结合我们具体是使用是什么样的损失函数,故这里无法详细展开

但里面使用的东西是一样的,就是说不管我们是使用的是什么损失函数,这一个部分求梯度都是这样做的

tanh

-1——1范围的一个取值

RNN的梯度消失

缺点

 现象

让我们以一个形象的例子来说明RNN序列太长时容易导致梯度消失的问题。

假设你正在阅读一本书,其中的每个段落都描述了一场连续发生的事件,而你需要理解整个故事情节。我们可以将这个阅读过程类比为RNN模型处理长序列的过程。

现在,假设这本书有1000页,每一页都是前一页的延续,而你需要从第一页开始,逐页阅读直到最后一页。每一页对应RNN模型中的一个时间步,而阅读整本书就是处理整个序列的过程。

然而,由于这本书非常长,你需要记住很多之前发生的事件,才能理解后面的情节。这就好比在RNN中,网络需要保持对长期依赖关系的记忆,以便正确地预测后续的输出。

现在,想象一下,你阅读到书的中间部分,已经读了几百页。由于书中的情节非常复杂,你可能会逐渐忘记之前的事件,因为你的记忆容量是有限的。在RNN中,类似的情况发生在梯度传播过程中,由于梯度不断地乘以权重矩阵,长序列中较早的事件对梯度的影响会逐渐减弱,最终导致梯度消失。

因此,就像在阅读长篇小说时,你可能会忘记之前的情节一样,在处理长序列时,RNN模型可能会遗忘较早的信息,导致难以理解整个序列。这就是RNN序列太长时容易导致梯度消失的形象例子。

举例

简化一下序列,但其实还是跟之前一样

S就是这里生成的状态

我们对单个时间求梯度

对我们的网络参数求梯度 参数有W_{x},W_{s},W_{0},b_{1},b_{2}

整理一下

我们可以看到这里面有许多的连乘项,从这里我们可以看出,第三个节点的梯度值的更新会受到第二个时间节点,比如X_{2}X_{1},当然还有他自己的X_{3}这些输入的影响,包括他们的一些梯度值等等,前后也是关联的,就是说后面所作的一些决定,是受到前面的一些因素的影响的,因此模型在学习这些参数的时候,也需要把前面的集合起来

然后变成一个累加的形式

中间连乘的方式可以用这种符号进行改写 

任意时刻下的梯度公式

任意时刻我们用t来代替,数字3全用t来代替

这个式子就有可能导致我们的梯度爆炸跟梯度消失

梯度爆炸

首先我们看中间的这一项

我们知道其求导之后的范围是0-1之间

故其不会导致梯度爆炸,但是有一定的概率导致梯度消失,但不是主要原因

比方说我们的连乘项比较少的时候并且求得的梯度值比较接近1的时候,那么他的梯度消失并不会特别严重。

主要的就是我们的最后一项,W_{S}^{k-1}也是一个连乘的一个项,当我们的W_{S}^{k-1}很小的时候,比如是0.1,0.01等等,比较接近于0.当这个地方进行一系列的连乘之后,就会导致这里非常接近于0.

当是一个比1大的数,2、3、4、5等等就会导致梯度爆炸。

所以导致梯度爆炸跟梯度消失最主要的原因就是W_{S}^{k-1}

假设t=20的时候

如果这时候我们W_{S}是一个比1小的一个数的话,他的17次方就近似等于0了,那么前面的东西就厄密什么意义了

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

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

相关文章

针对有容量的电动汽车路由问题的灵活交叉的修正遗传算法

英文:Modified Genetic Algorithm with Flexible Crossover for The Capacitated Electric Vehicle Routing Problem 摘要 本文提出了一种对遗传算法的修改,用一种叫做灵活交叉操作的新技术来解决有容量的电动汽车路由问题(CEVRP&#xff0…

二百二十七、Linux——通过shell脚本判断HDFS文件是否存在,如果存在则删除HDFS文件

一、目的 在用脚本去实现对HDFS中过期的ODS层原始数据进行删除后,发现还需要在脚本中对HDFS文件是否存在进行判断,否则如果HDFS文件不存在那么任务执行就会报错 报错原因是这一天的HDFS文件并不存在 原有脚本 #! /bin/bash source /etc/profile nowda…

python爬虫之Appium 的使用

Appium 是一个跨平台移动端自动化测试工具,可以非常便捷地为 iOS 和 Android 平台创建自动化测试用例。它可以模拟 App 内部的各种操作,如点击、滑动、文本输入等,只要我们手工操作的动作 Appium 都可以完成。在前面我们了解过 Selenium&…

使用 Docker 设置 PySpark Notebook

使用 Docker 设置 PySpark Notebook 第 1 步:拉取 Docker 镜像 首先拉取jupyter/all-spark-notebook包含 Spark 3.5.0 的镜像。 docker pull jupyter/all-spark-notebook:spark-3.5.0 第 2 步:设置您的工作区 在运行 Docker 映像之前,我们…

开源大数据集群部署(十四)Ranger集成Hbase

作者:櫰木 在hd1.dtstack.com主机上执行 在hmaster和back master上进行安装和执行 解压ranger-2.3.0-hbase-plugin [roothd1.dtstack.com ranger-plugin]# cd /root/bigdata [roothd1.dtstack.com ranger-plugin]# tar -zvxf ranger-2.3.0-hbase-plugin -C /opt配…

Unity编辑器功能Inspector快捷自动填充数据和可视化调试

我们有时候可能需要在面板增加一些引用,可能添加脚本后要手动拖动,这样如果有大量的脚本拖动也是不小的工作量 实例 例如:我的脚本需要添加一个Bone的列表,一个个拖动很麻烦。 实现脚本 我们可以用这样的脚本来实现。 public…

小程序API能力集成指南——画布API汇总(一)

RJS Canvas Canvas Canvas 实例, 在 RJS 中可通过 getCanvasById 获取。 属性 number width:画布宽度 number height:画布高度 方法 如下。 1、getContext Canvas.getContext(string contextType) RenderingContext Canvas.getContext(string c…

利用 Redis 和 Lua 实现高效的限流功能

简介 在现代系统中,限流是一种重要的机制,用于控制服务端的流量并保护系统免受恶意攻击或请求泛滥的影响。本文将介绍如何利用 Redis 和 Lua 结合实现高效的限流功能。 一、什么是限流 限流指的是对系统中的请求进行控制和调节,确保系统在…

Cluade3干货:超越GPT,模型特点分析+使用教程|2024年3月更新

就在刚刚,Claude 发布了最新的大模型 Claude3,并且一次性发布了三个模型,分别是 Claude 3 Haiku:(日本俳句 )Claude 3 Sonnet(英文十四行诗)Claude 3 Opus(古典乐作品集…

docker-compose Install rustdesk

RustDesk RustDesk 是一款开源的远程支持和远程桌面工具,它旨在为用户提供便捷的远程协助和远程访问功能。 默认情况下,hbbs 监听21115(tcp), 21116(tcp/udp), 21118(tcp),hbbr 监听21117(tcp), 21119(tcp)。务必在防火墙开启这几个端口, 请注意21116同时要开启TCP和UDP。…

streamlit初学-用streamlit实现云台控制界面

用streamlit实现云台控制界面 效果图PC上的效果手机上的效果 源码: 本文演示了,如何用streamlit做一个云台控制界面。功能包括:用户登录,事件的处理,图片的更新 版本信息: streamlit_authenticator: 下载链接streamlit : 1.31.1python: 3.11 修改点: streamlit_authenticato…

AndroidStudio安装Android模拟器AVD及遇到的问题解决

打开DeiviceManager 创建虚拟机 选个常规的1080*1920分辨率 这里就遇到一个报错: Android SDK is up to date. Running Android Emulator hypervisor driver installer [SC] ControlService 失败 1062: 服务尚未启动。 [SC] DeleteService 成功 [SC] 由于发生错误…

在线部署ubuntu20.04服务器,安装jdk、mysql、redis、nginx、minio

查看服务器版本为20.04 lsb_release -a服务器初始账号密码 sxd / 123456 首先,更改自身密码都输入123456 sudo passwd 创建最高权限root账号,密码为 123456 su root 更新源列表 sudo apt-get update 安装 openssh-server和vim,途中输入y sudo ap…

Python爬虫:设置随机 User-Agent

Python爬虫:设置随机 User-Agent 在Python中编写爬虫时,为了模拟真实用户的行为并防止被服务器识别为爬虫,通常需要设置随机的User-Agent。你可以使用fake-useragent库来实现这一功能。首先,你需要安装fake-useragent库&#xff…

通过Apple Configurator 2导出iOS ipa包

通过Apple Configurator 2导出iOS ipa包 安装Apple Configurator 2 从Mac AppStore安装Apple Configurator 2 下载ipa 准备工作: 1、 电脑已经安装了Apple Configurator 2 2、 手机已经安装了目标软件 3、 Apple 账号已经下载过目标软件 打开后连接设备&#xf…

如何快速分析OB集群日志,敏捷诊断工具obdiag分析能力实践——《OceanBase诊断系列》之四

1. 前言 obdiag是OceanBase的敏捷诊断工具。1.2版本中,obdiag支持快速收集诊断信息,但仅有收集能力是不够的,还需要有分析能力。因此在obdiag的1.3.0版本中,我们加入了OB集群的日志分析功能。用户可以一键进行集群的OB日志的分析…

Redis核心数据结构之SDS(二)

SDS与C字符串的区别 杜绝缓冲区溢出 除了获取字符串长度的复杂度高之外&#xff0c;C字符串不记录自身长度带来的另一个问题是 容易造成缓冲区溢出(buffer overflow).例如<string.h>/strcat函数可以将src字符串 中的内容拼接到dest字符串的末尾: char *strcat(char *d…

c++中多种类型sort()排序的用法(数组、结构体、pair、vector)

c中多种类型sort排序的用法 一、对数组排序1、默认排序2、自定义排序 二、对结构体进行排序三、对pair进行排序1、默认排序2、自定义排序 四、对vector进行排序1、默认排序2、去重排序3、自定义排序 一、对数组排序 1、默认排序 默认从小到大进行排序 #include <bits/std…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:拖拽控制)

设置组件是否可以响应拖拽事件。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 ArkUI框架对以下组件实现了默认的拖拽能力&#xff0c;支持对数据的拖出或拖入响应&#xff0c;开发者只需要将这些组件…

Xcode 15 适配 MonkeyDev

升级到Xcode15后,使用Xcode创建MonkeyApp后,运行会报错,本篇文章主要讲述此过程遇到的错误和解决办法。 问题1:找不到libc++.dylib文件 问题描述: Build input files cannot be found: /usr/lib/libstdc++.dylib, /usr/lib/libc++.dylib. Did you forget to declare th…