CNN的基本神经元结构:
发现输入是独立的,不能够联系上下文
对于一个句子:我想要手机,最好是苹果。
独立:输入苹果,得到可能是水果苹果
联系上下文:输入苹果,他会联系到上下文是手机,因此得到苹果手机
这种联系上下文就是一种时序(序列)
对于股票预测,不能够只看此刻信息,还需要看前一天的甚至更久之前的信息进行运用,这也是一种时序,至今对时序信息有个大概的了解了
因此我们想要对时序信息进行运用,便引出RNN
RNN经典结构:
n-to-n:用于翻译这种自然语言处理
n-to-one:以此为例
隐藏状态 ht:存储和传递前面时间步的信息,是 RNN 用来捕获序列上下文的重要机制。
其中Xt也就是序列信息{“我”,“想要”,”手机“,”最好是“,”苹果“}
y也是带回来的苹果
首先初始化h0,然后按照下面公式进行更新ht
输出:
前向传播的代码实现:
import numpy as np
class SimpleRNN:
def __init__(self, input_size, hidden_size, output_size):
# 初始化权重和偏置
self.hidden_size = hidden_size
self.W_x = np.random.randn(input_size, hidden_size) * 0.01 # 输入到隐藏层的权重
self.W_h = np.random.randn(hidden_size, hidden_size) * 0.01 # 隐藏层到隐藏层的权重
self.b_h = np.zeros((1, hidden_size)) # 隐藏层的偏置
self.W_y = np.random.randn(hidden_size, output_size) * 0.01 # 隐藏层到输出的权重
self.b_y = np.zeros((1, output_size)) # 输出层的偏置
def forward(self, x):
"""
前向传播计算 RNN 的输出
:param x: 输入序列,形状为 (batch_size, seq_len, input_size)
:return: 输出结果和最后的隐藏状态
"""
batch_size, seq_len, input_size = x.shape
h = np.zeros((batch_size, self.hidden_size)) # 初始化隐藏状态为 0
outputs = [] # 存储每个时间步的输出
for t in range(seq_len):
x_t = x[:, t, :] # 当前时间步的输入 (batch_size, input_size)
# 隐藏状态更新 h_t = tanh(W_x * x_t + W_h * h_{t-1} + b_h)
h = np.tanh(np.dot(x_t, self.W_x) + np.dot(h, self.W_h) + self.b_h)
# 输出计算 y_t = W_y * h_t + b_y
y_t = np.dot(h, self.W_y) + self.b_y
outputs.append(y_t)
# 将所有时间步的输出堆叠成一个张量
outputs = np.stack(outputs, axis=1) # (batch_size, seq_len, output_size)
return outputs, h # 返回输出结果和最后的隐藏状态
# 定义超参数
input_size = 3
hidden_size = 4
output_size = 2
batch_size = 1
seq_len = 5
# 初始化 RNN 模型
rnn = SimpleRNN(input_size, hidden_size, output_size)
# 随机生成输入序列 (batch_size, seq_len, input_size)
x = np.random.randn(batch_size, seq_len, input_size)
# 前向传播
outputs, h_final = rnn.forward(x)
# 打印结果
print("输入数据形状:", x.shape) # (1, 5, 3)
print("输出数据形状:", outputs.shape) # (1, 5, 2)
print("最后隐藏状态形状:", h_final.shape) # (1, 4)
输出:
# 随机生成输入序列 (batch_size, seq_len, input_size) # x = np.random.randn(batch_size, seq_len, input_size) 输入数据形状: (1, 5, 3) 的形状为:(batch_size,seq_len,output_size) 输出数据形状: (1, 5, 2) #也就是h的形状 最后隐藏状态形状: (1, 4)