Python LSTM 实现:从零开始构建你的序列模型
LSTM(Long Short-Term Memory,长短时记忆)是一种特殊的循环神经网络(Recurrent Neural Network,RNN),用于序列数据的建模和预测。它能够有效地处理长序列数据,并且可以避免梯度消失的问题。
下面是一个简单的 Python 实现 LSTM 的代码:
import numpy as np
class LSTM:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# 初始化LSTM的权重和偏置
self.Wf = np.random.randn(input_size + hidden_size, hidden_size)
self.bf = np.zeros((1, hidden_size))
self.Wi = np.random.randn(input_size + hidden_size, hidden_size)
self.bi = np.zeros((1, hidden_size))
self.Wc = np.random.randn(input_size + hidden_size, hidden_size)
self.bc = np.zeros((1, hidden_size))
self.Wo = np.random.randn(input_size + hidden_size, hidden_size)
self.bo = np.zeros((1, hidden_size))
self.Wy = np.random.randn(hidden_size, output_size)
self.by = np.zeros((1, output_size))
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def tanh(self, x):
return np.tanh(x)
def forward(self, x, h_prev, c_prev):
# 合并输入和上一个隐藏状态
concat = np.hstack((x, h_prev))
# 计算遗忘门
ft = self.sigmoid(np.dot(concat, self.Wf) + self.bf)
# 计算输入门
it = self.sigmoid(np.dot(concat, self.Wi) + self.bi)
# 计算新的单元状态
c_hat = self.tanh(np.dot(concat, self.Wc) + self.bc)
c = ft * c_prev + it * c_hat
# 计算输出门
ot = self.sigmoid(np.dot(concat, self.Wo) + self.bo)
# 计算隐藏状态
h = ot * self.tanh(c)
# 计算输出
y = np.dot(h, self.Wy) + self.by
# 保存当前状态
self.cache = (x, h_prev, c_prev, ft, it, c_hat, c, ot, h)
return y, h, c
def backward(self, dy, dh_next, dc_next):
# 从缓存中获取当前状态
x, h_prev, c_prev, ft, it, c_hat, c, ot, h = self.cache
# 反向传播输出层
dWy = np.dot(h.T, dy)
dby = np.sum(dy, axis=0, keepdims=True)
dh = np.dot(dy, self.Wy.T) + dh_next
# 反向传播隐藏层
dot = dh * self.tanh(c)
dot *= ot * (1 - ot)
dWo = np.dot(np.hstack((x, h_prev)).T, dot)
dbo = np.sum(dot, axis=0, keepdims=True)
dh_prev = np.dot(dot, self.Wo.T)
dc = dh * ot * (1 - self.tanh(c) ** 2)
dc += dc_next
dit = dc * c_hat
dit *= it * (1 - it)
dWi = np.dot(np.hstack((x, h_prev)).T, dit)
dbi = np.sum(dit, axis=0, keepdims=True)
dh_prev += np.dot(dit, self.Wi.T)
dft = dc * c_prev
dft *= ft * (1 - ft)
dWf = np.dot(np.hstack((x, h_prev)).T, dft)
dbf = np.sum(dft, axis=0, keepdims=True)
dh_prev += np.dot(dft, self.Wf.T)
dc_prev = dc * ft
# 更新权重和偏置
self.Wf -= dWf
self.bf -= dbf
self.Wi -= dWi
self.bi -= dbi
self.Wc -= dWc
self.bc -= dbc
self.Wo -= dWo
self.bo -= dbo
self.Wy -= dWy
self.by -= dby
return dh_prev, dc_prev
在这个实现中,我们使用numpy库来实现矩阵运算。我们首先初始化LSTM的权重和偏置,然后定义sigmoid和tanh函数来计算遗忘门、输入门、输出门和新的单元状态。我们还实现了前向传播和反向传播函数来计算损失和更新权重和偏置。
要使用这个LSTM模型,你可以按照以下步骤进行:
- 创建一个LSTM对象,指定输入、隐藏和输出大小:
lstm = LSTM(input_size=10, hidden_size=20, output_size=1)
- 执行前向传播并获取输出:
x = np.random.randn(1, 10) # 输入数据
h_prev = np.zeros((1, 20)) # 上一个隐藏状态
c_prev = np.zeros((1, 20)) # 上一个单元状态
y, h, c = lstm.forward(x, h_prev, c_prev) # 前向传播
- 计算损失并执行反向传播:
loss = np.sum((y - y_true) ** 2) # 计算损失
dy = 2 * (y - y_true) # 损失函数对输出的导数
dh_next = np.zeros((1, 20)) # 下一个隐藏状态的导数
dc_next = np.zeros((1, 20)) # 下一个单元状态的导数
lstm.backward(dy, dh_next, dc_next) # 反向传播
这就是一个简单的 Python 实现 LSTM 的示例。请注意,这只是一个简单的示例,实际上LSTM模型的实现可能会更加复杂。
原文地址: https://www.cveoy.top/t/topic/nvNZ 著作权归作者所有。请勿转载和采集!