PyTorch 循環神經網絡(RNN)
循環神經網絡(Recurrent Neural Networks, RNN)是一類神經網絡架構,專門用于處理序列數據,能夠捕捉時間序列或有序數據的動態信息,能夠處理序列數據,如文本、時間序列或音頻。
RNN 在自然語言處理(NLP)、語音識別、時間序列預測等任務中有著廣泛的應用。
在 RNN 中,數據不僅沿著網絡層級流動,還會在每個時間步驟上傳播到當前的隱層狀態,從而將之前的信息傳遞到下一個時間步驟。
隱狀態(Hidden State): RNN 通過隱狀態來記住序列中的信息。
隱狀態是通過上一時間步的隱狀態和當前輸入共同計算得到的。
公式:

- ht:當前時刻的隱狀態。
- ht-1:前一時刻的隱狀態。
- Xt:當前時刻的輸入。
- Whh、Wxh:權重矩陣。
- b:偏置項。
- f:激活函數(如 Tanh 或 ReLU)。
輸出(Output): RNN 的輸出不僅依賴當前的輸入,還依賴于隱狀態的歷史信息。

- yt:在時間步 t 的輸出向量(可選,取決于具體任務)。
- Why:是隱藏狀態到輸出的權重矩陣。。
循環神經網絡(RNN)在處理序列數據時的展開(unfold)視圖如下:

import torch import torch.nn as nn import torch.optim as optim import matplotlib.pyplot as plt import numpy as np # 數據集:字符序列預測(Hello -> Elloh) char_set = list("hello") char_to_idx = {c: i for i, c in enumerate(char_set)} idx_to_char = {i: c for i, c in enumerate(char_set)} # 數據準備 input_str = "hello" target_str = "elloh" input_data = [char_to_idx[c] for c in input_str] target_data = [char_to_idx[c] for c in target_str] # 轉換為獨熱編碼 input_one_hot = np.eye(len(char_set))[input_data] # 轉換為 PyTorch Tensor inputs = torch.tensor(input_one_hot, dtype=torch.float32) targets = torch.tensor(target_data, dtype=torch.long) # 模型超參數 input_size = len(char_set) hidden_size = 8 output_size = len(char_set) num_epochs = 200 learning_rate = 0.1 # 定義 RNN 模型 class RNNModel(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(RNNModel, self).__init__() self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x, hidden): out, hidden = self.rnn(x, hidden) out = self.fc(out) # 應用全連接層 return out, hidden model = RNNModel(input_size, hidden_size, output_size) # 定義損失函數和優化器 criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) # 訓練 RNN losses = [] hidden = None # 初始隱藏狀態為 None for epoch in range(num_epochs): optimizer.zero_grad() # 前向傳播 outputs, hidden = model(inputs.unsqueeze(0), hidden) hidden = hidden.detach() # 防止梯度爆炸 # 計算損失 loss = criterion(outputs.view(-1, output_size), targets) loss.backward() optimizer.step() losses.append(loss.item()) if (epoch + 1) % 20 == 0: print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}") # 測試 RNN with torch.no_grad(): test_hidden = None test_output, _ = model(inputs.unsqueeze(0), test_hidden) predicted = torch.argmax(test_output, dim=2).squeeze().numpy() print("Input sequence: ", ''.join([idx_to_char[i] for i in input_data])) print("Predicted sequence: ", ''.join([idx_to_char[i] for i in predicted])) # 可視化損失 plt.plot(losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("RNN Training Loss Over Epochs") plt.legend() plt.show()


浙公網安備 33010602011771號