成都网页设计的网站建设,网站开发调研,怎么提高网站访问速度,wordpress.exe习题6-4 推导LSTM网络中参数的梯度#xff0c; 并分析其避免梯度消失的效果 习题6-3P 编程实现下图LSTM运行过程 1. 使用Numpy实现LSTM算子 import numpy as np
# 创建一个numpy数组x#xff0c;它是一个4x4的矩阵#xff0c;包含9个元素
x np.array([[1, 0, 0, 1],[3, …习题6-4 推导LSTM网络中参数的梯度 并分析其避免梯度消失的效果 习题6-3P 编程实现下图LSTM运行过程 1. 使用Numpy实现LSTM算子 import numpy as np
# 创建一个numpy数组x它是一个4x4的矩阵包含9个元素
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]])# 创建i_w数组它是一个权重向量用于计算输入门
i_w np.array([0, 100, 0, -10])# 创建o_w数组它是一个权重向量用于计算输出门
o_w np.array([0, 0, 100, -10])# 创建f_w数组它是一个权重向量用于计算忘记门
f_w np.array([0, 100, 0, 10])# 创建c_w数组它是一个权重向量用于计算候选细胞状态
c_w np.array([1, 0, 0, 0])# 定义sigmoid函数它是一个激活函数用于将输入映射到[0, 1]范围内
def sigmoid(x):y 1 / (1 np.exp(-x))if y 0.5:return 1else:return 0# 初始化变量temp为0它是用来存储临时结果的
temp 0# 初始化空列表y和c分别用来存储每个时间步的输出和细胞状态
y []
c []
# 对于x中的每个元素i进行循环处理
for i in x:c.append(temp) # 将当前细胞状态添加到列表c中temp_c np.sum(np.multiply(i, c_w)) # 计算候选细胞状态它是通过将输入i与权重向量c_w相乘然后求和得到的temp_i sigmoid(np.sum(np.multiply(i, i_w))) # 计算输入门它是通过将输入i与权重向量i_w相乘然后求和然后应用sigmoid函数得到的temp_f sigmoid(np.sum(np.multiply(i, f_w))) # 计算忘记门它是通过将输入i与权重向量f_w相乘然后求和然后应用sigmoid函数得到的temp_o sigmoid(np.sum(np.multiply(i, o_w))) # 计算输出门它是通过将输入i与权重向量o_w相乘然后求和然后应用sigmoid函数得到的temp temp_c * temp_i temp_f * temp # 更新细胞状态它是基于候选细胞状态、输入门和忘记门的计算结果得到的y.append(temp_o * temp) # 计算LSTM的输出它是基于输出门和新的细胞状态的乘积得到的并将结果添加到列表y中# 打印细胞状态列表c和输出列表y
print(memory, c)
print(y , y) 这段代码参考了同学的代码在这段代码中我自己跟着敲了一遍但是结果不对 经过自己勘察发现是激活函数那块代码写错了 然后此外发现
这一步有错误没有经过tanh 的激活于是添加代码
def tanh(x):return np.tanh(x)
并且 修改了一丢丢
temp tanh(temp_c )* temp_i temp_f * temp
y.append(temp_o *np.tanh(temp)) 结果是这样的 再修改代码 # 打印细胞状态列表c和输出列表y
print(memory, [round(cell) for cell in c])
print(y , [round(output) for output in y]) 2. 使用nn.LSTMCell实现 import torch
import torch.nn as nnx 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]], dtypetorch.float)
# 在x的第二个维度上增加一个维度这通常用于处理批次中的单个样本
x x.unsqueeze(1)# 设置输入和隐藏状态的尺寸
i_size 4
h_size 1# 创建一个LSTMCell这是一个基本的LSTM单元用于处理时间序列数据
lstm_cell nn.LSTMCell(input_sizei_size, hidden_sizeh_size, biasFalse)# 为LSTM单元设置权重。这里的权重是硬编码的通常这些权重是从训练过程中学习得到的。
lstm_cell.weight_ih.data torch.tensor([[0, 100, 0, 10],[0, 100, 0, -10],[1, 0, 0, 0],[0, 0, 100, -10]]).float()
# 设置隐层到隐层的权重初始为零
lstm_cell.weight_hh.data torch.zeros([4 * h_size, h_size])# 初始化隐层和细胞状态为零张量
hx torch.zeros(1, h_size)
cx torch.zeros(1, h_size)# 用于存储每个时间步的输出
outputs []# 在x的每个元素上运行LSTM单元
for i in range(len(x)):# 使用LSTM单元处理输入和当前状态返回下一个隐层状态和细胞状态 hx, cx lstm_cell(x[i], (hx, cx))# 将输出添加到outputs列表中 outputs.append(hx.detach().numpy()[0][0])# 将outputs列表中的每个元素四舍五入到最近的整数并存储到新的列表中
outputs_rounded [round(x) for x in outputs]# 打印四舍五入后的输出列表
print(outputs_rounded) 结果一致所以答案正确。
3. 使用nn.LSTM实现 import torch
import torch.nn as nnx 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]], dtypetorch.float)
# 在x的第二个维度上增加一个维度这通常用于处理批次中的单个样本
x x.unsqueeze(1)# 设置输入和隐藏状态的尺寸
i_size 4
h_size 1# 创建一个LSTMCell这是一个基本的LSTM单元用于处理时间序列数据
lstm nn.LSTM(input_sizei_size, hidden_sizeh_size, biasFalse)# 为LSTM单元设置权重。这里的权重是硬编码的通常这些权重是从训练过程中学习得到的。# 设置 LSTM 的权重矩阵
lstm.weight_ih_l0.data torch.tensor([[0, 100, 0, 10], [0, 100, 0, -10], [1, 0, 0, 0], [0, 0, 100, -10]]).float()
# 设置隐层到隐层的权重初始为零
lstm.weight_hh_l0.data torch.zeros([4 * h_size, h_size])
# 初始化隐层和细胞状态为零张量
hx torch.zeros(1,1, h_size)
cx torch.zeros(1,1, h_size)
# 前向传播
outputs, (hx, cx) lstm(x, (hx, cx))
outputs outputs.squeeze().tolist()
# 将outputs列表中的每个元素四舍五入到最近的整数并存储到新的列表中
outputs_rounded [round(x) for x in outputs]
# 打印四舍五入后的输出列表
print(outputs_rounded) 总结 1、推导还是那样先把流程中用到的所有式子写出来然后倒着找相关的往后推导
2、代码看的熬夜患者的跟着打了一遍其实第二个第三个很相似3使用了封装的nn.LSTM来定义和计算LSTM模型的前向传播而2代码使用nn.LSTMCell来手动计算LSTM的前向传播。
参考链接
PyTorch - torch.nn.LSTMCell (runebook.dev)
DL Homework 11-CSDN博客
【23-24 秋学期】NNDL 作业11 LSTM-CSDN博客