LSTM原理解读与实战
在RNN详解及其实战中,简单讨论了为什么需要RNN这类模型、RNN的具体思路、RNN的简单实现等问题。同时,在文章结尾部分我们提到了RNN存在的梯度消失问题,及之后的一个解决方案:LSTM。因此,本篇文章主要结构如下:
- LSTM 理解及简单实现
- LSTM 实战
- 经典 RNN 与 LSTM 对比
- 关于梯度消失
LSTM 理解
其实,将 LSTM 与 RNN 说成两个并不可取, LSTM 依然归属于 RNN 之下,相比于使用线性回归方式来处理序列问题, LSTM 其实是设计了一个模块来取代线性回归算法。
LSTM(Long Short-Term Memory),翻译过来是长短期记忆法,其核心思想可以说非常的简单:既然 RNN 只能保存短期的记忆,那我增加一个长期记忆,不就可以解决这个问题了名?因此,LSTM提出了长期记忆和短期记忆,通过调整长期记忆和短期记忆之间的比例,来维持长期记忆的可靠,降低 RNN 的梯度消失问题。可以看到下方结构图中,模型输入由两个升级到三个,分别是当前节点状态 X t \mathbf{X}_{t} Xt,长期记忆: C t − 1 \mathbf{C}_{t-1} Ct−1,短期记忆 H t − 1 \mathbf{H}_{t-1} Ht−1。输出状态依然是两个:节点当前状态 C t \mathbf{C}_{t} Ct,和节点当前隐藏状态 H t \mathbf{H}_{t} Ht。
那LSTM 是如何实现对长短记忆的控制呢?
这就不得不提众人所知的三个门:
- 遗忘门:控制保留多少上一时刻的单元节点到当前节点
- 记忆门:控制将当前时刻的多少信息记忆到节点中
- 输出门:控制输出多少信息给当前输出
我们在分析三个门之前,我们先了解 门 这一概念。
门
从简化图中可以看到, 门的感觉类似于电路中的一个开关,当开关按下,信息通过,而开关抬起,信息不再通过。实际也如此类似,门是一个全连接层,输入为一个向量,输出为一个位于 [0,1] 之间的值。
我们来设计一个非常简单的遗忘门:每次学习状态之后,都遗忘一定的已学习内容,注意,这里的遗忘门与 LSTM 的遗忘门无关,单纯理解 门 这一概念。
# 一个线性层 用来计算遗忘多少
gate_linear = nn.Linear(hidden_size, 1)
# 一个线性层 用来学习
study_linear = nn.Linear(hidden_size, hidden_size)
# 此刻 h_t 是上一时刻状态
# 输出为 0 - 1 的值
gate = gate_linear(h_t)
# h_t 经过 study_linear 进行学习
_h_t = study_linear(h_t)
# 在输出结果之前,经过 gate 导致内容受损,遗忘了一定的学习内容
h_t = gate * (_h_t)
可以看到,如果 g a t e gate gate 值为 0,则历史信息均会被遗忘,而如果值为1,则历史信息则会被完全保留,而 gate_linear
网络中的超参数会不断的学习,因此一个可以学习的开关门就出现了。
但是, g a t e gate gate 作为一个浮点型的数据,对于 临时结果矩阵变量 _ h _ t \_h\_t _h_t 而言,其遗忘控制是全局的,也就是,当 g a t e gate gate 为 0 时, 其最终结果 h _ t h\_t h_t 为全 0 矩阵。因此我们应该注意: LSTM 中并不采用这样的大闸门,而是采用对每个变量进行分别控制的小水龙头(神经网络激活函数 nn.Sigmode
)
而在 LSTM 中,门主要使用 S i g m o d Sigmod Sigmod 神经网络(再次注意,并非是激活函数,而是 Sigmod 神经网络)来完成。
下方是一个示例代码:
hidden_size = 5
sigmoid = nn.Sigmoid()
# 隐藏状态 为了方便计算,假定全 1
hidden_emb = torch.ones(hidden_size, hidden_size)
# 中间某一层神经网络
model = nn.Linear(hidden_size,hidden_size)
# 获取该层输出,此时尚未被门限制
mid_out = model(hidden_emb)
# 获取一个门 -- 注意:并非一定由该变量所控制
# 比如:也可以由上一时刻的隐藏状态控制
# 代码为: gate = sigmoid(hidden_emb)
gate = sigmoid(mid_out)
# 得到最终输出
final_out = gate * mid_out
在有了对门的基础知识后,接下来对遗忘门、记忆门、输出门进行分别分析。
遗忘门
遗忘门涉及部分如下图所示:
其中,下方蓝色表示三个门共用的输入部分,均为 [ h t − 1 \mathbf{h}_{t-1} ht−1, X t \mathbf{X}_{t} Xt],需要注意,这里由于三个门之间并不共享权重参数,因此公示虽然接近,但是一共计算了三次,遗忘门被标记为 f t f_t ft, 列出遗忘门公式为:
f t = σ ( W f ∗ [ h t − 1 , X t ] + b f ) f_t = \sigma(\mathbf{W_f} * [\mathbf{h}_{t-1},\mathbf{X}_{t}] + \mathbf{b_f}) ft=σ(Wf∗[ht−1,Xt]+bf)
输出结果为取值范围为 [ 0, 1 ] 的矩阵,主要功能是控制与之相乘的矩阵的遗忘程度。
将 f t f_t ft 与输入的上一长期状态 C t − 1 C_{t-1} Ct−1 相乘:
C t ′ = f t ∗ C t − 1 C_t' = f_t * C_{t-1} Ct′=ft∗Ct−1
一部分的 C t − 1 C_{t-1} Ct−1 就这样被遗忘了。
记忆门
记忆门涉及部分如下所示:
从图中可以看到,记忆门中相乘的两个部分均由 h t − 1 \mathbf{h}_{t-1} ht−1 与 X t \mathbf{X}_{t} Xt 得到,
其中,左侧控制记忆多少的部分,与遗忘门公式基本一致:
i t = σ ( W i ∗ [ h t − 1 , X t ] + b i ) i_t = \sigma(\mathbf{W_i} * [\mathbf{h}_{t-1},\mathbf{X}_{t}] + \mathbf{b_i}) it=σ(Wi∗[ht−1,Xt]+bi)
与遗忘门相通,输出结果为取值范围为 [ 0, 1 ] 的矩阵,主要功能是控制与之相乘的矩阵的记忆程度。
而右侧,则更换了激活函数,由 s i g m o i d sigmoid sigmoid 变成了 t a n h tanh tanh:
C t ~ = tanh ( W c ∗ [ h t − 1 , X t ] + b c ) \tilde{C_t} = \tanh(\mathbf{W_c} * [\mathbf{h}_{t-1},\mathbf{X}_{t}] + \mathbf{b_c}) Ct~=tanh(Wc∗[ht−1,Xt]+bc)
该公式负责的部分可以看做负责短期隐藏状态的更新,取值范围为 [ -1, 1 ]。
最终记忆门更新公式如下:
C t ′ ~ = i t ∗ C t ~ \tilde{C_t'}= i_t * \tilde{C_t} Ct′~=it∗Ct~
可以说 C t ′ ~ \tilde{C_t'} Ct′~ 是保留了一定内容的短期状态
状态更新
在通过遗忘门获取到了被遗忘一定内容的长期状态 C t ′ C_t' Ct′ 和 保留了一定内容的短期状态 C t ′ ~ \tilde{C_t'} Ct′~ 之后,可以通过加法直接结合
C t = C t ′ + C t ′ ~ C_t = C_t' + \tilde{C_t'} Ct=Ct′+Ct′~
输出门
输出门是三个门中最后一个门,当数据到达这里的时候,我们主要控制将长期状态中的内容 C t C_t Ct 保存一定内容到 h t h_t ht 中,这里不再赘述
o t = σ ( W o ∗ [ h t − 1 , X t ] + b o ) o_t = \sigma(\mathbf{W_o} * [\mathbf{h}_{t-1},\mathbf{X}_{t}] + \mathbf{b_o}) ot=σ(Wo∗[ht−1,Xt]+bo)
h t = o t ∗ tanh ( C t ) h_t = o_t * \tanh(C_t) ht=ot∗tanh(Ct)
模型总结
可以看到,所有公式的核心部分都是如此的相似:
W c ∗ [ h t − 1 , X t ] + b c \mathbf{W_c} * [\mathbf{h}_{t-1},\mathbf{X}_{t}] + \mathbf{b_c} Wc∗[ht−1,Xt]+bc
而这部分其实又只是简单的线性函数,所以 LSTM 比 RNN 高级的地方其实并不在于某一条公式,而是它调整了数据之间的流动,按照一定的比例进行融合,弱化了长距离下的梯度消失问题。
最后总的来看,LSTM 其实就是一个升级版本的的 RNN,他额外初始化了一个状态 C C C, 用来保存长期的记忆,控制远距离上的参数权重。而输出也基本类似于此。
LSTM 实战
实验说明
实验数据集采用 IMDB 数据集。主要由电影评论构成,长度不均,但是长度在 1000 左右的数据属于常见数据。数据集样本均衡,数共计 50000 个样本,训练和测试各有 25000 个样本,同时训练和测试的正负比例均为 1:1。
根据我们对 RNN 的了解,这样的长度是很难学习到有效的知识的,所以很适合比较 RNN 与 LSTM 之间的区别。
为了方便代码复现,在实现中借助了 torchtext
来完成数据下载及加载。
为了证明模型真的有学习到一定的内容,所以对比实验中部分参数可能存在部分区别,可以在本地调整到同一参数进行细致的对比实验。
模型实现
分析一下由我实现的 LSTM 模型,并以此了解 LSTM 模型。
# 定义基础模型
class LSTM(nn.Module):def __init__(self, input_size, hidden_size, num_classes):"""args:input_size: 输入大小hidden_size: 隐藏层大小num_classes: 最后输出的类别,在这个示例中,输出应该是 0 或者 1"""super(LSTM, self).__init__()self.input_size = input_sizeself.hidden_size = hidden_sizeself.num_layers = num_layersself.fc_i = nn.Linear(input_size + hidden_size, hidden_size)self.fc_f = nn.Linear(input_size + hidden_size, hidden_size)self.fc_g = nn.Linear(input_size + hidden_size, hidden_size)self.fc_o = nn.Linear(input_size + hidden_size, hidden_size)self.sigmoid = nn.Sigmoid()self.tanh = nn.Tanh()self.fc_out = nn.Linear(hidden_size, num_classes)def forward(self, x):# 初始化隐藏状态 -- 短期记忆h_t = torch.zeros(x.size(0), x.size(1), self.hidden_size).to(x.device)# 初始化隐藏状态 -- 长期记忆c_t = torch.zeros(x.size(0), x.size(1), self.hidden_size).to(x.device)# 输入与短期记忆相拼接combined = torch.cat((x, h_t), dim=2)# 记忆门 -- 输出矩阵内容为 0-1 之间的数字i_t = self.sigmoid(self.fc_i(combined))# 遗忘门 -- 输出矩阵内容为 0-1 之间的数字f_t = self.sigmoid(self.fc_f(combined))#g_t = self.tanh(self.fc_g(combined))# 输出门 -- 输出矩阵内容为 0-1 之间的数字o_t = self.sigmoid(self.fc_o(combined))# 长期状态 = 遗忘门 * 上一时刻的长期状态 + 记忆门* 当前记忆状态c_t = f_t * c_t + i_t * g_t# 隐藏状态 = 输出门 * 长期状态h_t = o_t * self.tanh(c_t)# 降维操作 h_t = F.avg_pool2d(h_t, (h_t.shape[1],1)).squeeze()# out = self.fc_out(h_t)return out
超参数及参数说明
MyLSTM 与 nn.LSTM
名称 | 值 |
---|---|
learning_rate | 0.001 |
batch_size | 32 |
epoch | 6(3) |
input_size | 64 |
hidden_size | 128 |
num_classes | 2 |
此时:
MyLSTM 参数量: 99074
nn.LSTM 参数量: 99328
由于我实现的 MyLSTM 与 nn.LSTM 有 254 的参数差,我本人并没能分析出来差别。 nn.LSTM
在实验时大概率比我的 MyLSTM 迭代更快,所以容易较早的过拟合,所以将其训练 epoch 砍半,也就是说 MyLSTM 使用 6 epoch 进行训练,而 nn.LSTM
使用 3 epoch 进行训练。两者可以达到基本相近的效果
另外在代码实现中 nn.LSTM
后面加了一个 nn.Linear
来实现二分类,参数量为 258, 所以 MyLSTM 和 LSTM 相差参数总量为 512。
nn.RNN
名称 | 值 |
---|---|
learning_rate | 0.0001 |
batch_size | 32 |
epoch | 12-18 |
input_size | 64 |
hidden_size | 128 |
num_classes | 2 |
此时:
nn.RNN 参数量: 25090
由于实验样本长度在 1000 上下, RNN 显示出来了极大的不稳定性,其中, 相较于 LSTM 更容易梯度爆炸、训练 epoch 更多、学习率需要调低等等问题,尽管如此依然不能保证稳定的良好结果。
举例来说,某学生学习阅读理解,要求根据文章内容回答文章的情感倾向,但是学生只喜欢看最后一句话,每次都根据最后一句话来回答问题,那么他基本上是等于瞎猜的,只能学到一点浅薄的知识。
实验结果
MyLSTM | nn.LSTM | nn.RNN |
---|---|---|
0.86 | 0.80 | 0.67 |
关于梯度问题
-
RNN问题中,总的梯度是不会消失的。即便梯度越传越弱,那也是远处的梯度逐渐消失,而近距离的梯度不会消失,因此,梯度总和不会消失。RNN 梯度消失的真正含义是:梯度被近距离梯度所主导,导致模型难以学到远距离的依赖关系。
-
LSTM 上有多条信息流路径,其中,元素相加的路径的梯度流是最稳定的,而其他路径上与基本的 RNN 相类似,依然存在反复相乘问题。
-
LSTM 刚刚提出时不存在遗忘门。这时候历史数据可以在这条路径上无损的传递,可以将其视为一条 高速公路,类似于 ResNet 中的残差连接。
-
但是其他路径上, LSTM 与 RNN 并无太多区别,依然会爆炸或者消失。由于总的远距离梯度 = 各个路径的远距离梯度之和,因此只要有一条路的远距离梯度没有消失,总的远距离梯度就不会消失。可以说,LSTM 通过这一条路拯救了总的远距离梯度。
-
同样,总的远距离梯度 = 各个路径的远距离梯度之和,虽然高速路上的梯度流比较稳定,但是其他路上依然存在梯度消失和梯度爆炸问题。因此,总的远距离梯度 = 正常梯度 + 爆炸梯度 = 爆炸梯度,因此 LSTM 依然存在梯度爆炸问题。 但是由于 LSTM 的道路相比经典 RNN 来说非常崎岖, 存在多次激活函数,因此 LSTM 发生梯度爆炸的概率要小得多。实践中通常通过梯度剪裁来优化问题。
相关文章:
LSTM原理解读与实战
在RNN详解及其实战中,简单讨论了为什么需要RNN这类模型、RNN的具体思路、RNN的简单实现等问题。同时,在文章结尾部分我们提到了RNN存在的梯度消失问题,及之后的一个解决方案:LSTM。因此,本篇文章主要结构如下ÿ…...
24.11.26 神经网络 参数初始化
神经网络 感知神经网络 神经网络(Neural Networks)是一种模拟人脑神经元网络结构的计算模型,用于处理复杂的模式识别、分类和预测等任务 生物学: 人脑可以看做是一个生物神经网络,由众多的神经元连接而成 树突&#…...
51单片机从入门到精通:理论与实践指南(一)
单片机在智能控制领域的应用已非常普遍,发展也很迅猛,学习和使用单片机的人员越来越多。虽然新型微控制器在不断推出,但51单片机价格低廉、易学易用、性能成熟,在家电和工业控制中有一定的应用,而且学好了51单片机&…...
wordpress获取文章总数、分类总数、tag总数等
在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值,如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值,本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…...
Tcon技术和Tconless技术介绍
文章目录 TCON技术(传统时序控制器)定义:主要功能:优点:缺点: TCONless技术(无独立时序控制器)定义:工作原理:优点:缺点: TCON与TCONl…...
WinFrom调用webapi接口另一个方法及其应用实例
1.调用接口方法 代码如下: public class WebAPI{#region WebAPI调用 public async Task<string> Call_Webapi(string Url, string Json) //url传入的是接口名称,json传入的是接口参数{string responseBody string.Empty; //responseBod…...
上海乐鑫科技一级代理商飞睿科技,ESP32-C61高性价比WiFi6芯片高性能、大容量
在当今快速发展的物联网市场中,无线连接技术的不断进步对智能设备的性能和能效提出了更高要求。为了满足这一需求,乐鑫科技推出了ESP32-C61——一款高性价比的Wi-Fi 6芯片,旨在为用户设备提供更出色的物联网性能,并满足智能设备连…...
【机器学习】数据集合集!
本文将为您介绍经典、热门的数据集,希望对您在选择适合的数据集时有所帮助。 1 privacy 更新时间:2024-11-26 访问地址: GitHub 描述: 此存储库包含 TensorFlow Privacy(一种 Python)的源代码 库,其中包…...
GitLab使用操作v1.0
1.前置条件 Gitlab 项目地址:http://******/req Gitlab账户信息:例如 001/******自己的分支名称:例如 001-master(注:master只有项目创建者有权限更新,我们只能更新自己分支,然后创建合并请求&…...
企业后端多租户管理平台
1 简介 此系统在企业后端管理系统上进行的更改,用于快速开发租户管理平台。项目中详细的功能请查看文章:企业后端系统通用模版_后端模板-CSDN博客 支持多租户,支持多租户切换,支持多租户数据隔离,支持多租户数据同步等…...
【模型学习之路】PyG的使用+基于点的任务
这一篇是关于PyG的基本使用 目录 前言 PyG的数据结构 演示 图的可视化 基于点的任务 任务分析 MLP GCN 前言 对图结构感兴趣的朋友可以学一下常用的有关图结构的库:networkx详细介绍 networkx 库,探讨它的基本功能、如何创建图、操作图以及其常…...
【ubuntu】数学人的环境搭建
Python 语言环境 python 的 pip 第三方库管理 sudo apt install python3-pippython 的 idle 界面 sudo apt install idle3R 语言环境 sudo apt install r-cran-zoo### RStudio 界面 ubuntu sudo snap install rstudio --classicJulia 语言环境 sudo snap install julia --…...
Android 常用命令和工具解析之Trace相关
目录 1、Perfetto基本用法 1.1 perfetto抓取命令 1.2 Perfetto主界面 1.3 Perfetto常用技巧 1.3.1 CPU的运行状态 1.3.2 CPU的频率 1.3.3 CPU的所有任务 1.3.4 判断是否低内存 1.3.5 CPU的负载计算 1.3.6 查看某进程是否运行在大核 1.3.7 CPU的大核占用率计算 2、应…...
使用IDEA构建springboot项目+整合Mybatis
目录 目录 1.Springboot简介 2.SpringBoot的工作流程 3.SpringBoot框架的搭建和配置 4.用Springboot实现一个基本的select操作 5.SpringBoot项目部署非常简单,springBoot内嵌了 Tomcat、Jetty、Undertow 三种容器,其默认嵌入的容器是 Tomcat,…...
Python学习34天
import random class Game: peo0 rob0 # # def __init__(self,peo,rob): # self.peopeo # self.robrob def Play(self): """ 石头剪刀布游戏,0代表石头,1代见到,2代表石头 …...
leetcode hot100【LeetCode 215.数组中的第K个最大元素】java实现
LeetCode 215.数组中的第K个最大元素 题目描述 给定一个整数数组 nums 和一个整数 k,请返回数组中第 k 个最大的元素。 请注意,要求排名是从大到小的,因此第 k 个最大元素是排序后的第 k 个元素。你需要设计一个高效的算法来解决这个问题。…...
科技赋能:企业如何通过新技术提升竞争力的策略与实践
引言 在当今瞬息万变的商业环境中,科技的迅猛发展正在重新定义行业的游戏规则。无论是小型企业还是跨国巨头,都感受到数字化转型的迫切需求。过去,企业竞争力更多依赖于成本控制、资源调配或市场覆盖,而如今,新技术的引…...
SAP开发语言ABAP开发入门
1. 了解ABAP开发环境和基础知识 - ABAP简介 - ABAP(Advanced Business Application Programming)是SAP系统中的编程语言,主要用于开发企业级的业务应用程序,如财务、物流、人力资源等模块的定制开发。 - 开发环境搭建 - 首先需…...
快速理解微服务中Ribbon的概念
一.基本概念 1.在微服务架构中,Ribbon 是一个客户端负载均衡器,用于控制服务间的通信方式。 2.Ribbon 是一个开源的库,最早由 Netflix 开发,用于实现客户端负载均衡。 3.Ribbon 主要解决的是在微服务架构中,多个服务…...
MTK主板_安卓主板方案_MTK联发科主板定制开发
联发科(MTK)主板以其强大的性能和多样化的功能而受到广泛关注。该平台包括多个型号,例如MT6761、MT8766、MT6762、MT6765、MT8768和MT8788等,均配置了四核或八核64位处理器,主频可高达2.0GHz。采用先进的12nm工艺,搭载Android 11.…...
Linux:文件管理(一)——文件描述符fd
目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说,如果在电脑上新建了一个空白文档࿰…...
Excel的图表使用和导出准备
目的 导出Excel图表是很多软件要求的功能之一,那如何导出Excel图表呢?或者说如何使用Excel图表。 一种方法是软件生成图片,然后把图片写到Excel上,这种方式,因为格式种种原因,导出的图片不漂亮,…...
Python + 深度学习从 0 到 1(00 / 99)
希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持! ⭐ 什么是深度学习? 人工智能、机器学习与…...
高级AI记录笔记(五)
学习位置 B站位置:红豆丨泥 UE AI 教程原作者Youtube位置:https://youtu.be/-t3PbGRazKg?siRVoaBr4476k88gct素材自备 改良近战AI格挡行为 把近战AI的格挡行为从行为树中单独一个任务分块中给删除掉,因为我们希望敌人在受到伤害后立即进行…...
uniapp vue2项目迁移vue3项目
uniapp vue2项目迁移vue3项目,必须适配的部分 一、main.js 创建应用实例 // 之前 - Vue 2 import Vue from vue import App from ./App Vue.config.productionTip false // vue3 不再需要 App.mpType app // vue3 不再需要 const app new Vue({ ...App }) …...
平安科技Java面试题及参考答案
多个线程 a++,单个线程不管别的线程怎么改变 a 的值,只管自己的 a 的值,但是只有一个对象 在 Java 中,当多个线程对同一个对象的共享变量 a 进行 a++ 操作时,如果不进行适当的同步处理,就会出现数据不一致的问题。因为 a++ 操作并非原子操作,它实际上包含了读取 a 的值、…...
Element UI 打包探索【1】
目录 第一个命令 第二个命令 node build/bin/iconInit.js node build/bin/build-entry.js node build/bin/i18n.js node build/bin/version.js 总结 最近在接触组件库的项目,所以特意拿来Element UI借鉴学习一下,它算是做前端的同学们离不开的一…...
【通俗理解】神经网络中步长缩小的奥秘:优化算法与卷积操作的影响
【通俗理解】神经网络中步长缩小的奥秘:优化算法与卷积操作的影响 关键词提炼 #神经网络 #步长缩小 #优化算法 #卷积操作 #AdaGrad #感受野 第一节:步长缩小的类比与核心概念【尽可能通俗】 在神经网络中,步长缩小就像是运动员在赛跑中逐…...
C语言:C语言实现对MySQL数据库表增删改查功能
基础DOME可以用于学习借鉴; 具体代码 #include <stdio.h> #include <mysql.h> // mysql 文件,如果配置ok就可以直接包含这个文件//宏定义 连接MySQL必要参数 #define SERVER "localhost" //或 127.0.0.1 #define USER "roo…...
2023.11 Graph-Enriched Biomedical Language Models: A Research Proposal
Proceedings of the 13th International Joint Conference on Natural Language Processing and the 3rd Conference of the Asia-Pacific Chapter of the Association for Computational Linguistics: Student Research Workshop, pages 82–92 November 1–4, 2023. ©20…...
HTML详解(1)
1.HTML定义 HTML:超文本标记语言。超文本:通过链接可以把多个网页链接到一起标记:标签,带括号的文本后缀:.html 标签语法:<strong>需加粗文字</strong> 成对出现,中间包裹内容&l…...
Taro 鸿蒙技术内幕系列(三) - 多语言场景下的通用事件系统设计
基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章将深入解析 Taro 如何实现使用 React 开发高性能鸿蒙应用的技术内幕 背景 在鸿蒙生态系统中,虽然原生应用通常基于 ArkTS 实现,但在实际研发过程中发现,使用 C…...
Java图书管理系统(简易保姆级)
前面学习了这么多知识,为了巩固之前的知识,我们就要写一个图书管理系统来帮助大家复习,让大家的知识融会贯通~~~ 话不多说,直接开始今天的内容~ 首先呢,我们要有一个大体的思路: 实现效果思路有两种情况&a…...
maven 中<packaging>pom</packaging>配置使用
在 Maven 项目的 pom.xml 文件中, 元素用于指定项目的打包类型。默认情况下,如果 元素没有被显式定义,Maven 会假设其值为 jar。但是,当您设置 pom 时,这意味着该项目是一个 POM(Project Object Model&…...
uniapp使用腾讯云获取位置转为省市区
腾讯云获取位置转为省市区 腾讯位置服务提供了多种SDK程序包,其中的JavaScript版本的SDK适用于微信小程序,所以我们下载这个SDK包。 下载地址 在小程序项目中,创建lib目录,把SDK文件放入其中 <script>var QQMapWX requ…...
【git实践】分享一个适用于敏捷开发的分支管理策略
文章目录 1. 背景2. 分支管理实践2.1. 敏捷开发中分支管理面临的问题2.2. 分支管理策略2.3. 还需要注意的一些问题 3.总结 1. 背景 在实际的开发工作中,我们往往会面临多任务并行研发,多个环境管理的情况,这种情况下,一个合适的分…...
rpm方式安装postgres数据库及普通用户管理数据库
一、安装postgres 数据库 下载rpm安装包 wget https://ftp.postgresql.org/pub/repos/yum/15/redhat/rhel-7.9-x86_64/postgresql15-libs-15.5-1PGDG.rhel7.x86_64.rpm wget https://ftp.postgresql.org/pub/repos/yum/15/redhat/rhel-7.9-x86_64/postgresql15-15.5-1PGDG.rh…...
使用PgBackRest备份远程PG数据库
文章目录 环境准备总体要求1. 在 PostgreSQL 服务器上配置1.1 配置 PostgreSQL1.2 配置 SSH 密钥1.4 安装PgBackRest1.4.1 使用源码编译1.4.2 直接安装 配置文件 2. 在 PgBackRest 服务器安装PgBackRest2.1 安装 PgBackRest2.2 创建必要的目录2.3 编辑配置文件2.4 配置 SSH 密钥…...
笔记mfc11
Subclass(子类化)是MFC中最常用的窗体技术之一。子类化完成两个工作:一是把窗体类对象attach到一个windows窗体实体中(即把一个窗体的hwnd赋给该类)。另外就是把该类对象的消息加入到消息路由中,使得该类可以捕获消息。 让edit能…...
Softing线上研讨会 | Ethernet-APL:推动数字时代的过程自动化
| (免费)线上研讨会时间:2024年11月19日 16:00~16:30 / 23:00~23:30 Ethernet-APL以10Mb/s的传输速率为过程工业中的现场设备带来了无缝以太网连接和本质安全电源,这不仅革新了新建工厂,也适用于改造现有工厂。 与现…...
Spring Boot 整合 ELK 全面指南:实现日志采集、分析与可视化
一、ELK简介 1.1 什么是ELK? ELK 是三个开源工具的组合: Elasticsearch:一个分布式全文搜索和分析引擎,用于存储和查询日志数据。Logstash:一个数据处理管道工具,用于收集、解析和处理日志数据。Kibana&…...
D80【 python 接口自动化学习】- python基础之HTTP
day80 requests请求加入headers 学习日期:20241126 学习目标:http定义及实战 -- requests请求加入headers 学习笔记: requests请求加入headers import requestsurlhttps://movie.douban.com/j/search_subjects params{"type":…...
在Windows环境下打包Qt C++项目为独立可执行文件的完整指南
目录 1. 配置Qt环境变量步骤: 2. 使用Release模式编译项目步骤: 3. 使用windeployqt工具收集依赖项步骤: 4. 精简复制后的文件目录方法一:使用windeployqt的选项方法二:手动删除不必要的文件方法三:使用静态…...
已存大量数据的mysql库实现主从各种报错----解决方案(看评论)
背景何谓“先死后生”本文使用技术1、实施流程图2、实施2.1、数据库备份2.2、搭建Mysql的Master-Slave2.2.1、准备工作2.2.2、开始部署2.2.3、账号配置2.2.4、slave 同步配置2.2.5、验证 2.3、Master做数据恢复 结语 背景 计划对已有大量数据的mysql库的主从搭建,使…...
Java爬虫:深入探索1688接口的奥秘
在数字化时代,数据成为了企业最宝贵的资产之一。对于电商企业来说,获取和分析数据的能力直接关系到其市场竞争力。阿里巴巴旗下的1688平台,作为中国领先的批发贸易平台,拥有海量的商家和商品信息,成为了众多企业获取数…...
Linux——基础命令(1)
目录 一、认识Linux 终端命令格式 查阅命令帮助信息 -help 辅助操作 自动补全 清屏和查看当前工作目录 二、基本命令 文件和目录常用命令 1.ls-查看文件与目录 2.cd切换目录 (1)touc创建文件或修改文件时间 (2)mkdir创…...
Java知识及热点面试题总结(一)
今天开始对Java进行总复习,主要针对热点面试题,我们再根据试题内容延申相关知识; 1.、Java中equals与“”的区别详解 讲二者区别之前,先大概讲解一下基本数据类型和引用类型的概念,当然,有一定基础的朋友…...
基于 AI 的软件工程: 超级程序员
徐昊 《AI时代的软件工程》-极客时间课程学习总结 帮助你更好地利用 LLM 提高效率,还可以站在一个更全面的立场上,讨论如何将 LLM 引入团队或是组织。 核心观点: AI 辅助业务建模:通过将模型转化为 Mermaid 格式,将我们的模型表达为大语言模型能够理解的形式。通过添加注…...
Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别
文章目录 Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别1. Jakarta EE 迁移2. Spring Security 配置方式的变化3. PasswordEncoder 加密方式的变化4. permitAll() 和 authenticated() 的变化5. 更强的默认安全设置6. Java 17 支持与语法提升7. PreAuthorize、…...
浦语提示词工程实践(LangGPT版,服务器上部署internlm2-chat-1_8b,踩坑很多才完成的详细教程,)
首先,在InternStudio平台上创建开发机。 创建成功后点击进入开发机打开WebIDE。进入后在WebIDE的左上角有三个logo,依次表示JupyterLab、Terminal和Code Server,我们使用Terminal就行。(JupyterLab可以直接看文件夹)…...