用numpy实现lstm代码
时间: 2023-11-11 09:06:11 浏览: 135
numpy复现算法lstm算法内含数据集以及教程
好的,以下是一个简单的LSTM的numpy实现代码:
```python
import numpy as np
class LSTM:
def __init__(self, input_size, hidden_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.Wf = np.random.randn(hidden_size, input_size + hidden_size)
self.Wi = np.random.randn(hidden_size, input_size + hidden_size)
self.Wc = np.random.randn(hidden_size, input_size + hidden_size)
self.Wo = np.random.randn(hidden_size, input_size + hidden_size)
self.bf = np.zeros((hidden_size, 1))
self.bi = np.zeros((hidden_size, 1))
self.bc = np.zeros((hidden_size, 1))
self.bo = np.zeros((hidden_size, 1))
self.c = np.zeros((hidden_size, 1))
self.h = np.zeros((hidden_size, 1))
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def tanh(self, x):
return np.tanh(x)
def forward(self, x):
concat = np.concatenate((self.h, x), axis=0)
ft = self.sigmoid(self.Wf.dot(concat) + self.bf)
it = self.sigmoid(self.Wi.dot(concat) + self.bi)
ct_hat = self.tanh(self.Wc.dot(concat) + self.bc)
self.c = ft * self.c + it * ct_hat
ot = self.sigmoid(self.Wo.dot(concat) + self.bo)
self.h = ot * self.tanh(self.c)
return self.h
def backward(self, dh, dc):
ot = self.sigmoid(self.Wo.dot(np.concatenate((self.h, x), axis=0)) + self.bo)
dho = dh * self.tanh(self.c)
dct = dc + dho * ot * (1 - self.tanh(self.c) ** 2)
dit = dct * ct_hat * self.sigmoid(self.Wi.dot(np.concatenate((self.h, x), axis=0)) + self.bi) * (1 - self.sigmoid(self.Wi.dot(np.concatenate((self.h, x), axis=0)) + self.bi))
dft = dct * self.c * self.sigmoid(self.Wf.dot(np.concatenate((self.h, x), axis=0)) + self.bf) * (1 - self.sigmoid(self.Wf.dot(np.concatenate((self.h, x), axis=0)) + self.bf))
dot = dh * self.tanh(self.c) * self.sigmoid(self.Wo.dot(np.concatenate((self.h, x), axis=0)) + self.bo) * (1 - self.sigmoid(self.Wo.dot(np.concatenate((self.h, x), axis=0)) + self.bo))
dc_next = dct * ft
dconcat = np.concatenate((dit, dft, dot), axis=0)
dWf = dft.dot(np.concatenate((self.h, x), axis=0).T)
dWi = dit.dot(np.concatenate((self.h, x), axis=0).T)
dWc = dct.dot(np.concatenate((self.h, x), axis=0).T)
dWo = dot.dot(np.concatenate((self.h, x), axis=0).T)
dbf = np.sum(dft, axis=1, keepdims=True)
dbi = np.sum(dit, axis=1, keepdims=True)
dbc = np.sum(dct, axis=1, keepdims=True)
dbo = np.sum(dot, axis=1, keepdims=True)
dh_prev = dconcat[:self.hidden_size, :]
dx = dconcat[self.hidden_size:, :]
return dh_prev, dc_next, dWf, dWi, dWc, dWo, dbf, dbi, dbc, dbo, dx
```
其中 `LSTM` 类中包含 `__init__` 初始化函数, `sigmoid` 和 `tanh` 激活函数, `forward` 前向传播函数和 `backward` 反向传播函数。
在 `__init__` 中初始化 LSTM 的参数并随机初始化权重, `forward` 函数为单个 LSTM 单元的前向传播过程, `backward` 函数为单个 LSTM 单元的反向传播过程。在反向传播过程中,我们需要传入 `dh` 表示上一层的梯度和 `dc` 表示当前时刻的梯度。
需要注意的是,在实际应用中通常采用 batch 处理,即同时对多个样本进行计算,因此我们需要在实现中增加 batch 维度,并对相应的变量进行修改。同时,这里我们只实现了单层 LSTM,如果需要实现多层 LSTM,可以将多个 LSTM 单元组合在一起进行计算。
阅读全文