NNDL 作业11 LSTM [HBU ]

目录

习题6-4  推导LSTM网络中参数的梯度, 并分析其避免梯度消失的效果

>LSTM前向传播

>反向传播 求梯度

>梯度消失和梯度爆炸怎么来的?

>关键点:LSTM如何缓解梯度消失?

习题6-3P  编程实现下图LSTM运行过程

1. 使用Numpy实现LSTM算子

2. 使用nn.LSTMCell实现

3. 使用nn.LSTM实现

总结


引用的博客以及文章连接:

老师博客: 【23-24 秋学期】NNDL 作业11 LSTM-CSDN博客

DL Homework 11-CSDN博客

李宏毅机器学习笔记:RNN循环神经网络_李宏毅rnn笔记-CSDN博客

L5W1作业1 手把手实现循环神经网络-CSDN博客


习题6-4  推导LSTM网络中参数的梯度, 并分析其避免梯度消失的效果

强烈推荐我看的B站视频:2.前向传播的过程_哔哩哔哩_bilibili

我把这个系列来来回回听了两遍,照着UP主的思路手推了一遍,突然就感觉顿悟了。他讲的简单易懂,很细致,非常适合初学小白。

以下展示手推过程。分别是前向传播-->反向传播 梯度消失与爆炸-->如何缓解梯度消失(爆炸)。

>LSTM前向传播

先放上前向传播结论图,下图为UP主推导得出的结论

首先介绍LSTM结构,我在平板上画了一遍,这个图中LSTM共有三个门:

 f_{t} :遗忘门

 i_{t} :更新门  

 o_{t} :输出门

C_{t-1}是上一时刻输入进来的Cell记忆单元,h_{t-1}是上一时刻输入进来的隐藏状态,X_{t}是这一时刻的输入。注意最后的输出h_{t},有两个分支,一支作为输出(绿色支线),另一支作为下一时刻输入的隐藏状态。

\bigodot点乘,矩阵/向量对应位置相乘;

\bigoplus表示矩阵相加;

\sigma代表sigmoid,可以将值映射到[0,1]之间;

tanh即为tanh激活函数。

进行公式推导,先举例 推导f_{t}i_{t}

权重,输入,偏置项都已经标清楚了。sigmoid函数中的公式就是循环神经网络的前向传播公式,直接套用即可,但是一定要注意下角标,标清楚这是来自哪个门的路径角标。

以此类推,按照图中所给的结构图进行推导,照葫芦画瓢,很容易就能得到:

f_{t}=\sigma (f\bar{~}_{t})=\sigma (W_{xf}\cdot x_{t}+W_{hf}\cdot h_{t-1}+b_{f})

i_{t}=\sigma (i\bar{~}_{t})=\sigma (W_{xi}\cdot x_{t}+W_{hi}\cdot h_{t-1}+b_{i})

g_{t}=tanh(g\bar{~}_{t})=tanh(W_{xg}\cdot x_{t}+W_{hg}\cdot h_{t-1}+b_{g}) 

(这里使用g_{t}来表示支线上的c_{t}是因为避免与记忆单元c_{t}重合,所以赋了一个新的符号)

根据路径关系,可以得到c_{t}是由遗忘门和更新门进行矩阵相加得到的:


c_{t}=c_{t-1}\bigodot f_{t}+g_{t}\bigodot i_{t}

输出门: o_{t}=\sigma (o\bar{~}_{t})=\sigma (W_{xo}\cdot x_{t}+W_{ho}\cdot h_{t-1}+b_{o})

又因为c_{t}要分出一条支路,和输出门结果做点乘,才能得到t时刻的隐藏状态h_{t} :

m_{t}=tanh(c_{t})

h_{t}=o_{t} \bigodot m_{t}

其中h_{t}不仅可以作为t时刻的隐藏状态,也可以作为输出y_{t} (绿色分支的线),y_{t}的值可以根据任务需求进行设定,一般可以设: y_{t}=W_{yh}h_{t}+b_{y}

前向传播很好推导,就是根据现有的结构照葫芦画瓢,理清楚路径顺序和路径上的操作(比如sigmoid,tanh,点乘,相加),推出一个参数的公式来,其他参数推导公式也就大差不差了。

>反向传播 求梯度

我们以t=3 为例,三个时刻的LSTM模型结构如下图:

因为循环神经网络权重共享,所以在不同时刻 W的值都是相等的。

其中的S_{t}表示:

S_{1}=tanh(W_{x}X_{1}+W_{s}S_{0}+b_{1})

S_{2}=tanh(W_{x}X_{2}+W_{s}S_{1}+b_{1})

S_{3}=tanh(W_{x}X_{3}+W_{s}S_{2}+b_{1})

预测值(输出)为O_{t}为:

O_{1}=W_{0}S_{1}+b_{2}

O_{2}=W_{0}S_{2}+b_{2}

O_{3}=W_{0}S_{3}+b_{2}

L_{t}表示t时刻的损失Loss。当t=3时,L_{t}W_{xt}的梯度表示如下:

\frac{\partial L_{3}}{\partial W_{x}}=\frac{\partial L_{3}}{\partial W_{x3}}+\frac{\partial L_{3}}{\partial W_{x2}}+\frac{\partial L_{3}}{\partial W_{x1}}

那么我们可以分别得到t在各个值时的链式法则求梯度公式:

 \frac{\partial L_{3}}{\partial W_{x3}}=\frac{\partial L_{3}}{\partial O_{3}}\frac{\partial O_{3}}{\partial S_{3}}\frac{\partial S_{3}}{\partial W_{x3}}

\frac{\partial L_{3}}{\partial W_{x2}}=\frac{\partial L_{3}}{\partial O_{3}}\frac{\partial O_{3}}{\partial S_{3}}\frac{\partial S_{3}}{\partial S_{2}}\frac{\partial S_{2}}{\partial W_{x2}}

\frac{\partial L_{3}}{\partial W_{x3}}=\frac{\partial L_{3}}{\partial O_{3}}\frac{\partial O_{3}}{\partial S_{3}}\frac{\partial S_{3}}{\partial S_{2}}\frac{\partial S_{2}}{\partial S_{1}}\frac{\partial S_{1}}{\partial W_{x1}}

整合一下,除了t=3时刻的式子之外,t=2 t=1时刻的式子可以提出公因式,括号内有一个连乘式 可以得到:


\frac{\partial L_{3}}{\partial W_{x}}=\frac{\partial L_{3}}{\partial O_{3}}\frac{\partial O_{3}}{\partial S_{3}}\frac{\partial S_{3}}{\partial W_{x3}}+\sum_{k=1}^{2}\frac{\partial L_{3}}{\partial O_{3}}\frac{\partial O_{3}}{\partial S_{3}}(\prod_{j=k+1}^{3}\frac{\partial S_{j}}{\partial S_{j-1}})\frac{\partial S_{k}}{\partial W_{xk}}

故对任意t时刻下,有:

\frac{\partial L_{t}}{\partial W_{x}}=\frac{\partial L_{t}}{\partial W_{xt}}+...+\frac{\partial L_{t}}{\partial W_{x2}}+\frac{\partial L_{t}}{\partial W_{x1}}

即:

\frac{\partial L_{t}}{\partial W_{x}}=\frac{\partial L_{t}}{\partial O_{t}}\frac{\partial O_{t}}{\partial S_{t}}\frac{\partial S_{t}}{\partial W_{xt}}+\sum_{k=1}^{t-1}\frac{\partial L_{t}}{\partial O_{t}}\frac{\partial O_{t}}{\partial S_{t}}(\prod_{j=k+1}^{t}\frac{\partial S_{j}}{\partial S_{j-1}})\frac{\partial S_{k}}{\partial W_{xk}}

还有一点:S_{t}应为标量,这个公式才能成立。具体原因是 公式中使用了连乘。如果S_{t}为向量,就无法满足交换律,就不能写为连乘的形式了。 这是数学上的一些细节,我资历太浅 讲不明白(捂脸),想深入探究为何的请去看一遍UP的视频。

5.LSTM如何缓解梯度消失(公式推导)_哔哩哔哩_bilibili

>梯度消失和梯度爆炸怎么来的?

原因就在于这个公式:

\frac{\partial S_{j}}{\partial S_{j-1}}=tanh{}'(\theta _{j})W_{s}

上面这个公式是怎么来的?---上文我写到了S_{t}的表达式,截个图 放下面

会用复合函数求导的小伙伴一眼就可以看出来,这就是求了个复合函数,才得到了这个式子。

接下来,再回顾一下刚才我们求得的链式法则梯度公式

\frac{\partial L_{t}}{\partial W_{x}}=\frac{\partial L_{t}}{\partial O_{t}}\frac{\partial O_{t}}{\partial S_{t}}\frac{\partial S_{t}}{\partial W_{xt}}+\sum_{k=1}^{t-1}\frac{\partial L_{t}}{\partial O_{t}}\frac{\partial O_{t}}{\partial S_{t}}(\prod_{j=k+1}^{t}\frac{\partial S_{j}}{\partial S_{j-1}})\frac{\partial S_{k}}{\partial W_{xk}}

导致梯度爆炸和梯度消失的关键点就在于连乘我们连乘了好多个\frac{\partial S_{j}}{\partial S_{j-1}}, 而且又因为\frac{\partial S_{j}}{\partial S_{j-1}}=tanh{}'(\theta _{j})W_{s},所以参数W_{s}的设置就至关重要了:

>如果W_{s}>1,那么梯度值会越乘越大,很容易出现梯度爆炸现象。设想一下,比1大的数,经过了十几次方 或者几十次甚至几百 几千次方的连乘,这个值将变得超级大。

>如果W_{s}<1,相应的,梯度值会越乘越大,就会出现梯度消失现象。W越乘越接近0,链式求导就无法进行下去了。

所以调整W的值是非常关键的。

>关键点:LSTM如何缓解梯度消失?

 有了前面知识的铺垫,现在我们终于可以进入正题,那就是LSTM如何缓解梯度消失?

(看完了UP主的推导后  被UP深深的折服了,献上了我的一键三连。)

首先我们给出结论,如下图所示:我们需要调整\frac{\partial C_{t}}{\partial C_{t-1}},使得这一项接近于1,就能缓解梯度消失现象。    现在来探讨一下具体的原因。

(以上的图片为结论)

下图是我从up视频里截出来的,可见LSTM的参数非常非常多,看的人头晕。

仍然设t=3,我们如果想求出\frac{\partial L_{t}}{\partial f\bar{~}_{t}},就需要找到t=1,2,3各个时刻的梯度值。 

t=3时刻的偏导数最好求,因为只有一条路径可以到达f\bar{~}_{3}

但是t=1,2时刻的偏导数就变得超级难求,因为有很多条路径可以达到f\bar{~}_{2},我用平板画一画 ,大家体会一下(这一步需要对反向传播链式求导的过程很熟悉):

1. 第一条从L_{3}到达f\bar{~}_{2}的路经(红色+绿色):O\bar{~}_{3}-->h_{2}-->f\bar{~}_{2}

这条路径是从O\bar{~}_{3}入手的,仔细观察红色路径的重要拐弯节点。从O\bar{~}_{3}可以逆推到h_{2},再从h_{2}逆推到f\bar{~}_{2}

2. 第二条从L_{3}到达f\bar{~}_{2}的路径:

3. 第三条从L_{3}到达f\bar{~}_{2}的路径:

4. 第四条从L_{3}到达f\bar{~}_{2}的路径:

5. 第五条从L_{3}到达f\bar{~}_{2}的路径:

这五条路径 每一条都可以写出链式求导公式,太太太复杂了,我们理解了原理就行,公式推导无非就是换了一些角标,核心思想还是反向传播-链式求导。

这还只是t=2时刻的链式求导公式的构建过程,t=1时刻的更加复杂。UP整理的\frac{\partial L_{t}}{\partial f\bar{~}_{t}}最终链式求导公式为:

公式的关键点在这儿:

公式中的\frac{\partial C_{3}}{\partial C_{2}}即代表着一般表达式中的\frac{\partial C_{t}}{\partial C_{t-1}}\frac{\partial C_{t}}{\partial C_{t-1}}集合着所有链式求导的路径它是路径的'集合'形式。我们再回顾这个结论,结论从抽象变得具体了:

可以得到,我们需要控制W参数,使连乘项\frac{\partial C_{t}}{\partial C_{t-1}}约等于多个1相乘。

这样可以同时缓解梯度消失和梯度爆炸的问题。

最后 感谢UP主的视频讲解,十分感谢UP主提供了这么详细的讲解!他的公式推导过程很详细,十分推荐大家去看他的视频。


习题6-3P  编程实现下图LSTM运行过程

1. 使用Numpy实现LSTM算子

2. 使用nn.LSTMCell实现

3. 使用nn.LSTM实现

谢谢同班同学果大神的代码思路,我在第一题里花费了好多时间,反复听了一系列课、写博客、写公式,前几天也是在一直准备英语四六级。还好有果大神的现成代码,能让我借鉴复现一下(仅管有点小小的偷懒意味,但老师说过  学习的初始阶段就是不断地借鉴、模仿,哈哈哈 那我就借鉴一下同学写好的代码吧)

果大神博客:DL Homework 11-CSDN博客

1. 使用Numpy实现LSTM算子

代码的流程和我前文中所写的前向传播过程相匹配:
>首先赋初始值给输入X_{t}和权重W_{input},W_{output},W_{forget},W_{c}

>定义sigmoid函数,sigmoid函数的数学公式为Sigmoid(x)=\frac{1}{1+e^{-x}}

>开始循环,不断地保存上一时刻C_{t-1}的状态,并且进行三个门的点乘运算,更新记忆细胞状态

>输出,得到结果。

代码:

#numpy算子实现LSTM
import numpy as np#初始化输入序列,每行代表一个时间步的输入 [x1 x2 x3 label]
x = np.array([[1, 0, 0, 1],[3, 1, 0, 1],[2, 0, 0, 1],[4, 1, 0, 1],[2, 0, 0, 1],[1, 0, 1, 1],[3, -1, 0, 1],[6, 1, 0, 1],[1, 0, 1, 1]])#权重初始化
c_W = np.array([1, 0, 0, 0]) #细胞状态权重
inputGate_W = np.array([0, 100, 0, -10])#输入门权重
outputGate_W = np.array([0, 0, 100, -10])#输出门权重
forgetGate_W = np.array([0, 100, 0, 10])#遗忘门权重#sigmoid函数 用于LSTM中各种门的操作
def sigmoid(x):y = 1 / (1 + np.exp(-x))if y >= 0.5:return 1else:return 0temp = 0
y = []
c = []
for input in x:c.append(temp) #保存上一时刻的细胞状态temp_c = np.sum(np.multiply(input, c_W)) #新细胞状态的线性组合#输入门 遗忘门 输出门# multiply表示点乘运算  sigmoid将数值进行非线性变换temp_input = sigmoid(np.sum(np.multiply(input, inputGate_W)))temp_forget = sigmoid(np.sum(np.multiply(input, forgetGate_W)))temp_output = sigmoid(np.sum(np.multiply(input, outputGate_W)))temp = temp_c * temp_input + temp_forget * temp#更新细胞状态y.append(temp_output * temp)#通过输出门得到输出,保存下来
print("Memory:", c)
print("Y     :", y)

结果:

2. 使用nn.LSTMCell实现

从同学那里淘来的网址,中文版pytorch网站:PyTorch - torch.nn.LSTMCell (runebook.dev)

nn.LSTMCell的使用介绍如下 :

前向传播过程

参数介绍及形状展示

权重&偏置项

使用jupyter运行一下官网给的代码:

rnn = nn.LSTMCell(10, 20)  # (input_size, hidden_size)
input = torch.randn(2, 3, 10)  # (time_steps, batch, input_size)
hx = torch.randn(3, 20)  # (batch, hidden_size)
cx = torch.randn(3, 20)
output = []
for i in range(input.size()[0]):hx, cx = rnn(input[i], (hx, cx))output.append(hx)
output = torch.stack(output, dim=0)

了解了LSTMCell的基本运行原理后,开始使用LSTMCell实现所给示例:

import torch
import torch.nn as nn#输入数据 x 维度需要变换,因为LSTMcell接收的是(time_steps,batch_size,input_size)
x = torch.tensor([[1, 0, 0, 1],[3, 1, 0, 1],[2, 0, 0, 1],[4, 1, 0, 1],[2, 0, 0, 1],[1, 0, 1, 1],[3, -1, 0, 1],[6, 1, 0, 1],[1, 0, 1, 1]], dtype=torch.float)
#增加1个batch维度,x由原来的3*4的矩阵变为3*1*4的张量
x = x.unsqueeze(1)hidden_size=1#使用LSTMCell定义LSTM单元
lstm_cell = nn.LSTMCell(input_size=4, hidden_size=1, bias=False)lstm_cell.weight_ih.data = torch.tensor([[0, 100, 0, 10],  # forget gate[0, 100, 0, -10],  # input gate[1, 0, 0, 0],  # output gate[0, 0, 100, -10]]).float() #cell gate
lstm_cell.weight_hh.data = torch.zeros([4 * hidden_size, hidden_size])
# https://runebook.dev/zh/docs/pytorch/generated/torch.nn.lstmcell#初始化隐藏状态和细胞状态 初始值设为0
hx = torch.zeros(1, hidden_size)
cx = torch.zeros(1, hidden_size)outputs = []
for i in range(len(x)):hx, cx = lstm_cell(x[i], (hx, cx))#前向传播outputs.append(hx.detach().numpy()[0][0])#.detach()方法为确保tensor不计算梯度
outputs_rounded = [round(x) for x in outputs] #四舍五入到最接近的整数
print(outputs_rounded)

结果:

3. 使用nn.LSTM实现

nn.LSTM相较于nn.LSTMCell增加了 num_layers

PyTorch - torch.nn.LSTM (runebook.dev)

​​​​​​​

和nn.LSTMCell()的代码流程一样:

import torch
import torch.nn as nn# 输入数据 x 维度需要变换,因为 LSTM 接收的是 (sequence_length, batch_size, input_size)
x = torch.tensor([[1, 0, 0, 1],[3, 1, 0, 1],[2, 0, 0, 1],[4, 1, 0, 1],[2, 0, 0, 1],[1, 0, 1, 1],[3, -1, 0, 1],[6, 1, 0, 1],[1, 0, 1, 1]], dtype=torch.float)#增加1个batch维度,x由原来的3*4的矩阵变为3*1*4的张量
x = x.unsqueeze(1)#输入size 和 隐藏状态 size
input_size = 4
hidden_size = 1#定义LSTM模型
lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, bias=False)#设置权重矩阵
#只设置了输入到隐藏层的权重,而隐藏层到隐藏层的权重被设置为零。
lstm.weight_ih_l0.data = torch.tensor([[0, 100, 0, 10],  # forget gate[0, 100, 0, -10],  # input gate[1, 0, 0, 0],  # output gate[0, 0, 100, -10]]).float()  # cell gate
#隐藏层到隐藏层的权重设置为零
lstm.weight_hh_l0.data = torch.zeros([4 * hidden_size, hidden_size])#初始化隐藏状态和记忆状态
hx = torch.zeros(1, 1, hidden_size)
cx = torch.zeros(1, 1, hidden_size)# 前向传播
outputs, (hx, cx) = lstm(x, (hx, cx))
#通过.squeeze()方法去掉batch维度,得到一个一维的输出结果
outputs = outputs.squeeze().tolist()#四舍五入到最接近的整数
outputs_rounded = [round(x) for x in outputs]
print(outputs_rounded)

结果,和使用nn.LSTMCell()构建的结果一样:


总结

这次的作业 我将主要精力都放在LSTM原理理解和公式推导部分了,选了几个B站的课程试听,最终听完了我认为讲的最详细、最适合小白听的课程,来回听了两遍。自己画了流程图,手推了前向传播过程和简单的反向传播公式。我对一下的LSTM工作流程有了更深入的了解:

前向传播-->反向传播-->梯度爆炸梯度消失问题的来源-->缓解梯度消失的方法

   听的最酣畅淋漓的就是梯度爆炸梯度消失问题的来源与缓解方法。原来做作业的时候,要去分析为什么神经网络模型会出现梯度爆炸和梯度消失,得到的答案就是因为   “权重设置不恰当,导致反向传播链式求导的时候出现了多个权值连乘 使得梯度值要么 越来越小,最终消亡 梯度接近于零 无法进行更新,要么越来越大,梯度值爆炸式的上升,使得模型更新效果大减折扣” 。原因确实是这样的,但是背后的数学原理 我还是理解得一塌糊涂,没有进行过一步步的数学公式推导,所以根本就不清楚为啥会出现“权重连乘项”。 而这次的作业,我跟着B站的课,紧跟了一遍从模型构建一直到环节梯度消失的过程 ,为什么会出现权重连乘项的问题也就迎刃而解了。

代码部分借鉴了同学们的作业,利用辅助工具(其实是文心一言)帮我理清了代码的流程,走了一遍流程,照着手敲了一遍。主要问题还是--张量的形状设置,头晕脑胀,搞不清楚...得一遍又一遍的调整形状参数。哎,我的弱项就是写代码,必须要加把劲,努力做到从头到尾原创代码。

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

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

相关文章

力扣日记12.18-【二叉树篇】合并二叉树

力扣日记&#xff1a;【二叉树篇】合并二叉树 日期&#xff1a;2023.12.18 参考&#xff1a;代码随想录、力扣 617. 合并二叉树 题目描述 难度&#xff1a;简单 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xf…

【Axure RP9】实现登入效验及实现左侧菜单栏跳转各页面

目录 一 效验简介 1.1 校验好处 1.2 应用场景 二 登入校验 2.1 效果 2.2 实现流程 三 左边菜单栏左侧菜单栏跳转各页面 3.1 效果 3.2 实现图 一 效验简介 1.1 校验好处 提高安全性&#xff1a; 在传统的用户名和密码登录的基础上&#xff0c;引入了另一种或多种验证…

C++中的继承(二)

文章目录 前言多继承虚继承虚继承的底层组合 前言 上一篇文章我们C的正常继承其实已经讲完了&#xff0c;但是后面还有一个大坑。 实际当中继承有单继承和多继承。 单继承就是直接继承一个类。 只有一个直接父类的就叫做单继承。 如果是单继承那就比较简单。 现实世界除了有…

Docker部署MinIO对象存储服务器结合内网穿透实现远程访问

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

OpenCV技术应用(7)— 将图像转为热力图

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教大家如何将一幅图像转化成热力图&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 伪彩色处…

C++ Qt 开发:ListWidget列表框组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍ListWidget列表框组件的常用方法及灵活运用。…

centos下:mysql一些指令+mysql首次修改密码+mysql忘记密码修改

操作 查看mysql运行状态 systemctl status mysqld 停止mysql systemctl stop mysqld 启动mysql systemctl start mysqld 重启mysql systemctl restart mysqld 开启mysql开机自启动 systemctl enable mysqld 关闭mysql开机自启动 systemctl disable mysqld 查看具体的报错日…

AI创作系统ChatGPT网站源码,支持AI绘画,支持GPT语音对话+智能思维导图生成

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

网络编程『socket套接字 ‖ 简易UDP网络程序』

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; Linux学习之旅、神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f324;️前言&#x1f326;️正文1.预备知识1.1.IP地址1.2.端口号1.3.端口号与进…

超级计算机与天气预报:精准预测的科技革命

超级计算机与天气预报&#xff1a;精准预测的科技革命 一、引言 随着科技的飞速发展&#xff0c;超级计算机已经成为现代社会不可或缺的一部分。它们在科研、工业、军事等领域发挥着重要作用&#xff0c;其中天气预报是一个颇具代表性的应用领域。本文将探讨超级计算机在天气…

[ CTF ]【天格】战队WriteUp-第七届“强网杯”全国安全挑战赛

第七届“强网杯”全国安全挑战赛 2023.12.16~2023.12.17 文章目录 【Misc】Pyjail ! Its myFILTER !!!easyfuzz谍影重重2.0签到Pyjail ! Its myRevenge !!!server_8F6C72124774022B.py 问卷调查 【Reverse】ezre 【Web】happygame 【强网先锋】石头剪刀布TrieSpeedUpezreez_fmt…

最新AI创作系统ChatGPT系统源码+DALL-E3文生图+支持AI绘画+GPT语音对话功能

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

[linux]进程间通信-管道pipe的实际用法(写入/读取)

一、需求 现有两个进程A和B&#xff0c;B进程含较为独立且复杂的业务逻辑&#xff0c;A进程为主控进程&#xff0c;现A进程需要控制B进程执行对应的功能&#xff0c;且要保持响应及时。 二、分析 典型进程间通信案例&#xff0c;因此使用linux下的管道方法&#xff08;pipe&…

打响指针的第一枪:指针家族

前言 指针其实是我们学习C语言中最难的知识点&#xff0c;很多人在学习指针的时候会被绕晕&#xff0c;包括博主也是&#xff0c;当初百思不得其解&#xff0c;脑袋都要冒烟了&#xff0c;本来打算在学习指针的时候就写一篇博客&#xff0c;但是当初自己的能力还是没有办法去完…

SQL语句整理二--Mysql

文章目录 知识点梳理&#xff1a;1. mysql 中 in 和 exists 区别2. varchar 与 char 的区别 查看表结构&#xff1a;获取当前时间&#xff1a;查看建表语句&#xff1a;修改用户密码&#xff1a;查看所有用户&#xff1a;grant命令&#xff1a;判断当前数据库有多少连接数&…

WPF Icon矢量库 MahApps.Metro.IconPacks

文章目录 前言MahApps.Metro.IconPacksIconPacks.Browser简单使用简单使用案例代码Icon版本个人推荐 Icon自定义版权问题 前言 为了更快的进行开发&#xff0c;我找到了一个WPF的矢量图库。这样我们就不用去网上找别人的矢量库了 MahApps.Metro.IconPacks MahApps.Metro.Icon…

21.Servlet 技术

JavaWeb应用的概念 在Sun的Java Servlet规范中&#xff0c;对Java Web应用作了这样定义&#xff1a;“Java Web应用由一组Servlet、HTML页、类、以及其它可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的 Servlet容器 中运行。” Java Web应用中可以包含如下…

BearPi Std 板从入门到放弃 - 先天神魂篇(9)(RT-Thread DAC->ADC)

简介 RT-Thread DAC->ADC 使用, 就是DAC1输出模拟量, ADC1 读取模拟量转化成电压值, 基于开发板 &#xff1a; Bearpi Std(小熊派标准板)主芯片: STM32L431RCT6串口: Usart1DAC1: PA5, OUT2ADC1: PC2, IN3将板子上的E53 接口, 5 和 6用排线相连, 即实现内部DAC1->ADC1 …

P2P网络下分布式文件共享场景的测试

P2P网络介绍 P2P是Peer-to-Peer的缩写&#xff0c;“Peer”在英语里有“对等者、伙伴、对端”的意义。因此&#xff0c;从字面意思来看&#xff0c;P2P可以理解为对等网络。国内一些媒体将P2P翻译成“点对点”或者“端对端”&#xff0c;学术界则统一称为对等网络(Peer-to-Pee…

深入浅出RPC:选取适合自己的RPC

文章目录 1、RPC概念&&背景1.1、RPC背景 1.2、RPC是什么&#xff0c;什么时候需要用到&#xff1f;2、进程间的通信 - IPC与RPC2.1、什么是IPC2.2、IPC与RPC联系 3、RPC的实现3.1、RPC实现的基本思路3.2、RPC实现的扩展方向 4、RPC的选择 1、RPC概念&&背景 1.…