python - 我如何通过原始张量操作构建的 PyTorch LSTM 反向传播(例如,不是`nn.LSTM`)
问题描述
编辑:我的实现的问题是试图output
直接从隐藏状态中提取我的 IE 单热向量。我在顶部添加了一个致密层,它工作正常。
我正在尝试从 PyTorch 中更原始的操作中创建 LSTM,并使用torch.autograd
功能来反向传播错误。我希望它是“在线”的,h
并且c
随着时间的推移累积它们的状态,并且在每个时间步长都有 1 个字符输入和 1 个输出。
这是一个字符级的 rnn,所以:
我的词汇是 30 个字符(小写 az 和一些标点符号)
inp
是一个长度为 30 的 onehot 向量。h
并且c
长度为 30 + 100。前 30 个h
是我的“输出”我的损失将
target
单热编码的 char 与 . 的前 30 个索引进行比较h
。我积累
loss
了 10 多个步骤,然后不知道如何正确地反向支持它。以下是(糟糕的)尝试。
TL;博士。我如何正确地反向传播这个 LSTM?
def ff(inp, h, c):
xh = torch.cat((inp, h), 0)
f = (xh @ Wf + bf).sigmoid()
i = (xh @ Wi + bi).sigmoid()
g = (xh @ Wg + bg).tanh() # C-bar, in some literature
c = f * c + i * g
o = (xh @ Wo + bo).sigmoid()
h = o * c.tanh()
return h, c
loss = torch.zeros(1)
def bp(out, target, lr):
global Wf, Wi, Wg, Wo
global bf, bi, bg, bo
global h, c
global loss
# Accumulate loss every step
loss += (-target * out[:out_n].softmax(dim=0).log()).sum()
# Every 10 chars, run backprop
if i % 10 == 0:
loss.backward()
with torch.no_grad():
for param in [Wf, Wi, Wg, Wo, bf, bi, bg, bo]:
param -= lr * param.grad
param.grad.zero_()
h.detach_()
c.detach_()
loss.detach_()
loss = torch.zeros(1)
return loss
解决方案
推荐阅读
- java - 太多的 if 语句
- rabbitmq - 陈旧的 rabbitmq 数据队列文件占用了磁盘
- python - scapy 在 windows/parrotsec (pycharm) 上不起作用
- node.js - Ethereiun Solidity Contract - 挂钩问题之前
- c++ - C ++中无序集的内部工作是什么?它使用什么算法?
- c# - 如何使用多个列表框组合格式化代码
- wso2 - 使用发送调解器调用端点后,我收到以下错误响应
- html - 如何使用 tinymce 发布自定义 html 标签
- reactjs - 将 React 函数组件转换为 React 类组件
- java - 创建了新实例,但找不到符号错误仍然存在