各類神經網絡學習:(四)RNN 循環神經網絡(下集),pytorch 版的 RNN 代碼編寫

上一篇下一篇
RNN(中集)待編寫

代碼詳解

pytorch 官網主要有兩個可調用的模塊,分別是 nn.RNNCellnn.RNN ,下面會進行詳細講解。

RNN 的同步多對多、多對一、一對多等等結構都是由這兩個模塊實現的,只需要將對輸入和輸出進行調整就行。

nn.RNN 為例,它有兩個輸出,一個是 output ,一個是 hidden ,使用前者就是同步多對多結構,使用后者就是多對一結構(這種情形下 hidden 其實就是 output 的最后一個元素)(先說,后面慢慢看)。

1)pytorch版模塊調用

①nn.RNNCell(單步RNN)

官網鏈接:RNNCell — PyTorch 2.6 documentation

使用此函數,需要再手動實現時間循環

  • 對應公式:
    h ′ = t a n h ( W i h ? x + b i h + W h h ? h + b h h ) h^{'} = tanh(W_{ih}·x+b_{ih}+W_{hh}·h+b_{hh}) h=tanh(Wih??x+bih?+Whh??h+bhh?)
    這里和之前提到的 s t = g 1 ( U ? x t + W ? s t ? 1 + b s ) s_t=g1(U·x_t+W·s_{t-1}+b_s) st?=g1(U?xt?+W?st?1?+bs?) 是一個意思, s s s 就是 h h h ,只不過更細化了,稍微轉換一下即可。

  • 公式圖解:

    在這里插入圖片描述

  • 模塊解析:

    class torch.nn.RNNCell(input_size, hidden_size, bias=True, nonlinearity='tanh', device=None, dtype=None)
    # 實例化為:rnncell = torch.nn.RNNCell(10,20)
    
    • 類的參數解釋:
      • input_size (int):輸入 x x x 的特征數------------------------------------------ 其實就是 x x x 的維度,即向量 x x x 中的元素個數。
      • hidden_size (int):隱藏狀態 h h h 的特征數---------------------------------- 其實就是 h h h 的維度,即向量 h h h 中的元素個數。
      • bias (bool):偏置設置項,默認為 True ---------------------------------- 如果為 F a l s e False False 則不使用偏置 b i h 、 b h h b_{ih}、b_{hh} bih?bhh?
      • nonlinearity (str):激活函數設置項,默認為 'tanh' -------------- 可設置為 nonlinearity='relu'
    • 輸入,的類型及形狀:
      • input :類型:tensor,形狀: ( N , H i n ) (N,H_{in}) (N,Hin?) ( H i n ) (H_{in}) (Hin?) -------------------- 其中 N N N 就是 batch_size (批量), H i n H_{in} Hin? = input_size
      • hidden :類型:tensor,形狀: ( N , H o u t ) (N,H_{out}) (N,Hout?) ( H o u t ) (H_{out}) (Hout?) ---------------- 其中 H o u t H_{out} Hout? = hidden_size ,如果不提供就默認為 0 張量。
    • 輸出,的類型及形狀:
      • hidden :類型:tensor,形狀: ( N , H o u t ) (N,H_{out}) (N,Hout?) ( H o u t ) (H_{out}) (Hout?) ---------------- 其中 H o u t H_{out} Hout? = hidden_size ,此輸出代表了下一時刻的隱藏層狀態。
    • 其中的權重 W 、 b W、b Wb 都是自動初始化、可自學習的。
  • 調用展示:

    import torchcell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size)
    hidden = Cell(input, hidden)
    # hidden = Cell(input, hidden) 其實就是在調用 cell 中的 forword 函數,因為 cell 本身是個 class 類嘛
    
  • 完整樣例展示(構造數據集時會引入 seqlen ):

    有關 seqlen 的講解請看下面點②,其含義就是時間步。

    seqlen 是在使用 RNN 之前,構造數據集時需要設置的參數, nn.RNNCell 沒有調用此參數,但是在寫代碼時需要設置(其實可以不設置,因為畢竟也用不到這個參數,只是說后面的 nn.RNN 里用到了這個參數,索性就一起用了),模型會自動獲取 batch_sizeinput_size

    事實上,下方代碼中的循環次數就是 seqlen

    import torchbatch_size = 2
    seq_len = 3
    input_size = 4
    hidden_size = 2cell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size)  # 實例化dataset = torch.randn(seq_len, batch_size, input_size)  # 構造固定格式的數據集, (seq, batch, features)
    hidden = torch.zeros(batch_size, hidden_size)  # 初始化隱層狀態輸入for idx, input in enumerate(dataset):print('=' * 20, idx, '=' * 20)print('input size:', input.shape)hidden = cell(input, hidden)print('outputs size:', hidden.shape)print(hidden)-----------------------------------------------------------------------------------------------------------------------
    # 輸出結果為:
    ==================== 0 ====================
    input size: torch.Size([2, 4])
    outputs size: torch.Size([2, 2])
    tensor([[-0.9041, -0.9441],[ 0.7673, -0.7628]], grad_fn=<TanhBackward0>)
    ==================== 1 ====================
    input size: torch.Size([2, 4])
    outputs size: torch.Size([2, 2])
    tensor([[ 0.5290, -0.6024],[ 0.1011, -0.9541]], grad_fn=<TanhBackward0>)
    ==================== 2 ====================
    input size: torch.Size([2, 4])
    outputs size: torch.Size([2, 2])
    tensor([[ 0.5451,  0.4806],[-0.9263,  0.2988]], grad_fn=<TanhBackward0>)
    

    對于輸出結果的解析:

    因為隨機構造的數據集正好是只有 2 個樣本,且 batch_size = 2, seq_len=3 ,所以循環執行了 3 次。

②構造數據集的規范

如果對上面的 nn.RNNCell 樣例中參數尺寸不理解的,可以看這一節

1:

在這里插入圖片描述

2:

在這里插入圖片描述

記住: 循環次數 ≠ ≠ = batch_size * seq_len 。而且使用 nn.RNNCell 時編寫的循環次數不是之前 CNN 一樣的 epoch ,使用 nn.RNN 時才是。

對于語言建模而言: batchsize 相當于幾句話, seqlen 相當于每句話里有幾個字, inputsize 就是每個字的向量形式維度(one-hot編碼)。

③nn.RNN(重點)

官網鏈接:RNN — PyTorch 2.6 documentation

使用此函數,無需手動實現時間循環

可以理解為由多個 nn.RNNCell 組成的集成網絡。

  • 每一層的公式:
    h t = t a n h ( W i h T ? x + b i h + W h h T ? h t ? 1 + b h h ) h_t = tanh(W_{ih}^{T}·x+b_{ih}+W_{hh}^{T}·h_{t-1}+b_{hh}) ht?=tanh(WihT??x+bih?+WhhT??ht?1?+bhh?)
    這里也和之前提到的 s t = g 1 ( U ? x t + W ? s t ? 1 + b s ) s_t=g1(U·x_t+W·s_{t-1}+b_s) st?=g1(U?xt?+W?st?1?+bs?) 是一個意思, s s s 就是 h h h ,只不過更細化了,稍微轉換一下即可。

    公式里的轉置不用在意,權重都是內部自動初始化、更新的。公示圖解和 nn.RNNCCell 的差不多,就是多個轉置。

  • 模塊解析:

    class torch.nn.RNN(input_size, hidden_size, num_layers=1, nonlinearity='tanh', bias=True, batch_first=False, dropout=0.0, 		  bidirectional=False, device=None, dtype=None)
    
    • 類的參數解釋:

      • input_size (int):輸入 x x x 的特征數------------------------------------------ 其實就是 x x x 的維度,即向量 x x x 中的元素個數。

      • hidden_size (int):隱藏狀態 h h h 的特征數---------------------------------- 其實就是 h h h 的維度,即向量 h h h 中的元素個數。

      • num_layers (int):循環層數,默認為 1 ----------------------------------- 意味著將 num_layersRNN 堆疊在一起,后一個 RNN 接收第一個 RNN 的隱

        ? 層狀態輸出作為輸入,并且計算最終結果。

      • nonlinearity (str):激活函數設置項,默認為 'tanh' -------------- 可設置為 nonlinearity='relu'

      • bias (bool):偏置設置項,默認為 True ---------------------------------- 如果為 False 則不使用偏置 b i h 、 b h h b_{ih}、b_{hh} bih?bhh?

      • batch_first (bool):輸入輸出格式設置項,默認為 False -------- 如果為 True 則用戶需要按照 (batch_size, seq_len, input_size)

        ? 構造數據格式,默認是 (seq_len, batch_size, input_size)

      • dropout :一般不用考慮。

      • bidirectional (bool):雙向 RNN 設置項,默認為 False --------- 如果為 True ,則變成雙向 RNN

    • 輸入,的類型及形狀( D D D 一般都為 1 1 1 ):

      • input :類型:tensor,形狀: ( L , N , H i n ) (L,N,H_{in}) (L,N,Hin?) ( L , H i n ) (L,H_{in}) (L,Hin?) ----------- 其中 L L Lseq_len N N Nbatch_size (批量), H i n H_{in} Hin? = input_size

        ? 當 batch_first=True 時為 ( N , L , H i n ) (N,L,H_{in}) (N,L,Hin?)

      • hidden :類型:tensor,形狀: ( D ? n u m _ l a y e r s , N , H o u t ) (D*num\_layers,N,H_{out}) (D?num_layers,N,Hout?) ( D ? n u m _ l a y e r s , H o u t ) (D*num\_layers,H_{out}) (D?num_layers,Hout?) -----------------------------------------------------------------------

        ? 其中 H o u t H_{out} Hout? = hidden_size

        ? D = 2 i f b i d i r e c t i o n a l = T r u e o t h e r w i s e 1 D=2~~~if~bidirectional=True~~~otherwise~1 D=2???if?bidirectional=True???otherwise?1

        ? 如果不提供就默認為 0 張量。

    • 輸出,的類型及形狀( D D D 一般都為 1 1 1 ):

      • output:類型:tensor,形狀: ( L , N , D ? H o u t ) (L,N,D*H_{out}) (L,N,D?Hout?) ( L , D ? H o u t ) (L,D*H_{out}) (L,D?Hout?) ------------------------當 batch_first=True 時為 ( N , L , D ? H o u t ) (N,L,D?H_{out}) (N,L,D?Hout?)
      • hidden :類型:tensor,形狀: ( D ? n u m _ l a y e r s , N , H o u t ) (D*num\_layers,N,H_{out}) (D?num_layers,N,Hout?) ( D ? n u m _ l a y e r s , H o u t ) (D*num\_layers,H_{out}) (D?num_layers,Hout?) --------------- 此輸出代表了下一時刻的隱藏層狀態輸入。
    • 其中的權重 W 、 b W、b Wb 都是自動初始化、可自學習的。

    其實輸出 output 就是所有的隱層輸出狀態, hidden 就是最后一刻的隱層輸出狀態( num_layers >1 的稍有不同)。

  • 模塊使用圖解:

    • num_layers 默認為 1 時:

      調用展示:

      import torchcell= torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=1)
      out, hidden = cell(inputs, hidden)
      

      在這里插入圖片描述

      上圖中,就單個 RNN Cell 而言, x i x_i xi? 是輸入,左邊箭頭是隱層狀態輸入,右邊箭頭和上邊箭頭都是隱層狀態輸出。

      注意: 這里 RNN Cell 的個數就是 seq_len 的值。

    • num_layers > 1 時(令其=3):

      調用展示:

      import torchcell= torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=3)
      out, hidden = cell(inputs, hidden)
      

    在這里插入圖片描述

    上圖中,就最下面一排的單個 RNN Cell 而言, x i x_i xi? 是輸入,左邊箭頭是隱層狀態輸入,右邊箭頭和上邊箭頭都是隱層狀態輸出。

    就上面兩排的單個 RNN Cell 而言,下面一排 RNN Cell 的隱層狀態輸出是其輸入,左邊箭頭是隱層狀態輸入,右邊箭頭和上邊箭頭都是隱層狀態輸出。

  • 完整樣例展示:

    這里 nn.RNN 內部前向傳播的時間步數就是 seq_len 的值。

    import torchbatch_size = 2
    seq_len = 3
    input_size = 4
    hidden_size = 2
    num_layers = 1single_rnn = torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)#(seqLen, batchSize, inputSize) 
    inputs = torch.randn(seq_len, batch_size, input_size)
    hidden = torch.zeros(num_layers, batch_size, hidden_size)
    out, hidden = single_rnn(inputs, hidden)
    print('output size:', out.shape)
    print('output:', out)
    print('Hidden size:', hidden.shape)
    print('Hidden:', hidden)-----------------------------------------------------------------------------------------------------------------------
    # 輸出結果為:
    output size: torch.Size([3, 2, 2])
    output: tensor([[[ 0.5540, -0.3186],[ 0.1407, -0.9272]],[[ 0.8301,  0.5667],[ 0.9692, -0.4985]],[[ 0.7678,  0.6239],[-0.4899, -0.9761]]], grad_fn=<StackBackward0>)
    Hidden size: torch.Size([1, 2, 2])
    Hidden: tensor([[[ 0.7678,  0.6239],[-0.4899, -0.9761]]], grad_fn=<StackBackward0>)
    

2)單值序列預測實例

在訓練之前制作數據集時,通常是用前 m 個數據預測第 m+1 個數據,第 m+1 個數據作為真實值,前 m 個數據作為輸入得出的一個結果作為預測值(這 m+1 個數據就作為一個樣本)。如果 batch_size 不為 1 ,則 batch_size 個樣本就作為一次 epoch 的輸入。

數據集:某國際航班每月乘客量變化表,international-airline-passengers.csv,CSDN 都有提供下載的,下載之后不要改動。

目標:拿 12 個月的數據來預測下一個月的客流量。

完整代碼:

import torch
import torch.nn as nn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from torch.utils.data import TensorDataset, DataLoader
from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter(log_dir='runs/airline_model')# 1. 數據預處理
data = pd.read_csv('international-airline-passengers.csv', usecols=['Month', 'Passengers'])
data['Month'] = pd.to_datetime(data['Month'])
data.set_index('Month', inplace=True)# 2. 數據集劃分
train_size = int(len(data) * 0.8)
train_data = data[:train_size]
test_data = data[train_size:]# 3. 歸一化處理
scaler = MinMaxScaler(feature_range=(0, 1))
train_scaled = scaler.fit_transform(train_data)
test_scaled = scaler.transform(test_data)# 4. 創建滑動窗口數據集
def create_sliding_windows(data, window_size):X, Y = [], []for i in range(len(data) - window_size):X.append(data[i:i + window_size])Y.append(data[i + window_size])return np.array(X), np.array(Y)window_size = 12
X_train, y_train = create_sliding_windows(train_scaled, window_size)
X_test, y_test = create_sliding_windows(test_scaled, window_size)# 轉換為PyTorch張量 (batch_size, seq_len, features)
X_train = torch.FloatTensor(X_train).unsqueeze(-1)  # [samples, seq_len, 1]
X_train = X_train.squeeze(2) if X_train.dim() == 4 else X_train  # 消除多余維度
y_train = torch.FloatTensor(y_train)
X_test = torch.FloatTensor(X_test).unsqueeze(-1)
X_test = X_test.squeeze(2) if X_test.dim() == 4 else X_test
y_test = torch.FloatTensor(y_test)# 5. 構建RNN模型(使用tanh激活)
class AirlinePassengerModel(nn.Module):def __init__(self, input_size=1, hidden_size=50, output_size=1):super().__init__()self.rnn = nn.RNN(input_size=input_size,hidden_size=hidden_size,nonlinearity='tanh',batch_first=True,num_layers=1  # 顯式指定層數)self.fc = nn.Linear(hidden_size, output_size)def forward(self, x):out, _ = self.rnn(x)  # RNN層使用內置tanh激活out = self.fc(out[:, -1, :])  # 取最后一個時間步輸出return outmodel = AirlinePassengerModel()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)dummy_input = torch.randn(1, window_size, 1)
writer.add_graph(model,dummy_input)# 6. 訓練模型
train_loader = DataLoader(TensorDataset(X_train, y_train), batch_size=32, shuffle=True)epochs = 100
train_loss, val_loss = [], []for epoch in range(epochs):model.train()batch_loss = 0for X_batch, y_batch in train_loader:optimizer.zero_grad()y_pred = model(X_batch)loss = criterion(y_pred, y_batch)loss.backward()optimizer.step()batch_loss += loss.item()train_loss.append(batch_loss / len(train_loader))# 驗證步驟model.eval()with torch.no_grad():y_val_pred = model(X_test)loss = criterion(y_val_pred, y_test)val_loss.append(loss.item())print(f'Epoch {epoch + 1}/{epochs} | Train Loss: {train_loss[-1]:.4f} | Val Loss: {val_loss[-1]:.4f}')# 7. 預測與逆歸一化
model.eval()
with torch.no_grad():train_pred = model(X_train).numpy()test_pred = model(X_test).numpy()# 逆歸一化處理
train_pred = scaler.inverse_transform(train_pred)
y_train = scaler.inverse_transform(y_train.numpy().reshape(-1, 1))
test_pred = scaler.inverse_transform(test_pred)
y_test = scaler.inverse_transform(y_test.numpy().reshape(-1, 1))# 8. 可視化
# 訓練損失曲線可視化
plt.figure(figsize=(12, 5))
plt.plot(range(1, len(train_loss)+1), train_loss, 'b-', label='Train Loss')
plt.plot(range(1, len(val_loss)+1), val_loss, 'r--', label='Validation Loss')
plt.title('Training Process Monitoring\n(2025-03-11)', fontsize=14)
plt.xlabel('Epochs', fontsize=12)
plt.ylabel('Loss', fontsize=12)
plt.xticks(np.arange(0, len(train_loss)+1, 10))
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend()
plt.tight_layout()
plt.show()# 綜合預測結果可視化
plt.figure(figsize=(14, 6))# 原始數據曲線
plt.plot(data.index, data['Passengers'],label='Original Data',color='gray',alpha=0.4)# 訓練集預測曲線(需注意時間對齊)
train_pred_dates = train_data.index[window_size:train_size]
plt.plot(train_pred_dates, train_pred,label='Train Predictions',color='blue',linestyle='--')# 測試集預測曲線
test_pred_dates = test_data.index[window_size:]
plt.plot(test_pred_dates, test_pred,label='Test Predictions',color='red',linewidth=2)# 格式設置
plt.title('Time Series Prediction Results', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Passengers', fontsize=12)
plt.legend(loc='upper left')
plt.grid(True, linestyle=':', alpha=0.5)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()writer.close()

輸出訓練結果:

Epoch 1/100 | Train Loss: 0.0893 | Val Loss: 0.3493
Epoch 2/100 | Train Loss: 0.0473 | Val Loss: 0.1947
Epoch 3/100 | Train Loss: 0.0469 | Val Loss: 0.2113
Epoch 4/100 | Train Loss: 0.0387 | Val Loss: 0.2346
...
...
Epoch 95/100 | Train Loss: 0.0064 | Val Loss: 0.0304
Epoch 96/100 | Train Loss: 0.0052 | Val Loss: 0.0384
Epoch 97/100 | Train Loss: 0.0047 | Val Loss: 0.0434
Epoch 98/100 | Train Loss: 0.0048 | Val Loss: 0.0332
Epoch 99/100 | Train Loss: 0.0051 | Val Loss: 0.0285
Epoch 100/100 | Train Loss: 0.0051 | Val Loss: 0.0283

訓練及預測可視化:

在這里插入圖片描述

3)同步多對多序列預測實例

目標:給出輸入 'hello' ,給出其標簽 'ohlol' ,通過訓練使得輸入 'hello' ,模型能輸出 'ohlol'

  • nn.RNNCell

    import torch# ==================================================準備數據==================================================
    input_size = 4
    hidden_size = 4
    batch_size = 1
    # seq_len 在這里不用顯示定義, 模型會自動識別輸入的尺寸idx2char = ['e', 'h', 'l', 'o']  # 字母字典
    x_data = [1, 0, 2, 2, 3]  # x_data 表示的單詞是 hello, 在這里表示的是輸入 inputs
    y_data = [3, 1, 2, 3, 2]  # y_data 表示的單詞是 ohlol, 在這里表示的輸出標簽
    one_hot_lookup = [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]]  # 獨熱字典x_one_hot = [one_hot_lookup[x] for x in x_data]  # x_data 的獨熱編碼向量組, 形狀為:(seq_len, input_size)
    # 更改 x_one_hot 的形狀, 在中間加一個 batch_size 維度, 其中 -1 參數表示獲取列表中的元素個數(5個子列表, 那么個數就是5)
    inputs = torch.Tensor(x_one_hot).view(-1, batch_size, input_size)
    labels = torch.LongTensor(y_data).view(-1, 1)  # 形狀為(seq_len, batch_size)print(x_one_hot)
    print(labels)# ==================================================定義模型==================================================
    class MyModel(torch.nn.Module):def __init__(self, input_size, hidden_size, batch_size):super(MyModel, self).__init__()self.batch_size = batch_sizeself.input_size = input_sizeself.hidden_size = hidden_sizeself.rnncell = torch.nn.RNNCell(input_size=self.input_size, hidden_size=self.hidden_size)def forward(self, input, hidden):hidden = self.rnncell(input, hidden)return hiddendef init_hidden(self):return torch.zeros(self.batch_size, self.hidden_size)net = MyModel(input_size, hidden_size, batch_size)# ==================================================準備訓練==================================================
    criterion = torch.nn.CrossEntropyLoss()  # 交叉熵損失
    optimizer = torch.optim.Adam(net.parameters(), lr=0.1)  # Adam 優化器for epoch in range(15):loss = 0optimizer.zero_grad()hidden = net.init_hidden()print('Predicted string: ', end='')for input, label in zip(inputs, labels):hidden = net(input, hidden)# seq_len 個單元的損失要加起來得到總損失,并且還要添加 view 操作適配形狀# 這里的 -1 就是在自動填充 batch_size 的值loss += criterion(hidden.view(-1, hidden_size), label.view(-1))_, idx = hidden.max(dim=1)print(idx2char[idx.item()], end='')loss.backward()optimizer.step()print(', Epoch [%d/ 15] loss=%.4f' % (epoch+1, loss.item()))
    

    輸出結果:

    Predicted string: llllh, Epoch [1/15] loss=6.5481
    Predicted string: ollll, Epoch [2/15] loss=5.6356
    Predicted string: oolll, Epoch [3/15] loss=5.1777
    Predicted string: oolol, Epoch [4/15] loss=4.7279
    Predicted string: oolol, Epoch [5/15] loss=4.2586
    Predicted string: ohlol, Epoch [6/15] loss=3.8693
    Predicted string: ohlol, Epoch [7/15] loss=3.6075
    Predicted string: ohlol, Epoch [8/15] loss=3.3900
    Predicted string: ohlol, Epoch [9/15] loss=3.1333
    Predicted string: ohlol, Epoch [10/15] loss=2.8496
    Predicted string: ohlol, Epoch [11/15] loss=2.5996
    Predicted string: ohlol, Epoch [12/15] loss=2.4079
    Predicted string: ohlol, Epoch [13/15] loss=2.2640
    Predicted string: ohlol, Epoch [14/15] loss=2.1526
    Predicted string: ohlol, Epoch [15/15] loss=2.0646
    
  • 訓練過程圖解(尤其是尺寸的要求和變化):

    其中交叉熵損失的輸入輸出尺寸可以參考此篇博客:損失函數。

    在這里插入圖片描述

    在這里插入圖片描述

  • nn.RNN

    import torch# ==================================================準備數據==================================================
    input_size = 4
    hidden_size = 4
    batch_size = 1
    num_layers = 1
    # seq_len = 5 在這里不用顯示定義, 模型會自動識別輸入的尺寸idx2char = ['e', 'h', 'l', 'o']  # 字母字典, 復雜情形可以是單詞字典
    x_data = [1, 0, 2, 2, 3]  # x_data 表示的單詞是 hello, 在這里表示的是輸入 input
    y_data = [3, 1, 2, 3, 2]  # y_data 表示的單詞是 ohlol, 在這里表示的輸出標簽
    one_hot_lookup = [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]]  # 獨熱字典x_one_hot = [one_hot_lookup[x] for x in x_data]  # x_data 的獨熱編碼向量組, 形狀為:(seq_len, input_size)
    # 更改 x_one_hot 的形狀, 在中間加一個 batch_size 維度, 其中 -1 參數表示獲取 seq_len, 就是列表中的元素個數(5個子列表, 那么個數就是5)
    inputs = torch.Tensor(x_one_hot).view(-1, batch_size, input_size)
    labels = torch.LongTensor(y_data)print(x_one_hot)
    print(inputs)
    print(labels)# ==================================================定義模型==================================================
    class Single_RNN(torch.nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers=1):super(Single_RNN, self).__init__()self.num_layers = num_layersself.batch_size = batch_sizeself.input_size = input_sizeself.hidden_size = hidden_sizeself.rnn = torch.nn.RNN(input_size=self.input_size, hidden_size=self.hidden_size, num_layers=self.num_layers)def forward(self, input, hidden):output, hidden = self.rnn(input, hidden)# 輸出設置成 2 維張量,return output.view(-1, self.hidden_size)def init_hidden(self):return torch.zeros(self.num_layers, self.batch_size, self.hidden_size)net = Single_RNN(input_size, hidden_size, batch_size, num_layers)# ==================================================準備訓練==================================================
    criterion = torch.nn.CrossEntropyLoss()  # 交叉熵損失
    optimizer = torch.optim.Adam(net.parameters(), lr=0.05)  # Adam 優化器for epoch in range(15):optimizer.zero_grad()hidden = net.init_hidden()  # 初始化 h0outputs = net(inputs, hidden)loss = criterion(outputs, labels)loss.backward()optimizer.step()_, idx = outputs.max(dim=1)idx = idx.data.numpy()  # 將 idx 變成numpy數組, 元素和尺寸不變print('Predicted: ', ''.join([idx2char[x] for x in idx]), end='')print(', Epoch [%d/ 15] loss=%.4f' % (epoch + 1, loss.item()))

    輸出結果:

    Predicted:  ohooe, Epoch [1/ 15] loss=1.2800
    Predicted:  ohooo, Epoch [2/ 15] loss=1.1455
    Predicted:  ohooo, Epoch [3/ 15] loss=1.0370
    Predicted:  ohloo, Epoch [4/ 15] loss=0.9497
    Predicted:  ohlol, Epoch [5/ 15] loss=0.8746
    Predicted:  ohlol, Epoch [6/ 15] loss=0.8034
    Predicted:  ohlol, Epoch [7/ 15] loss=0.7356
    Predicted:  ohlol, Epoch [8/ 15] loss=0.6763
    Predicted:  ohlol, Epoch [9/ 15] loss=0.6283
    Predicted:  ohlol, Epoch [10/ 15] loss=0.5905
    Predicted:  ohlol, Epoch [11/ 15] loss=0.5614
    Predicted:  ohlol, Epoch [12/ 15] loss=0.5392
    Predicted:  ohlol, Epoch [13/ 15] loss=0.5220
    Predicted:  ohlol, Epoch [14/ 15] loss=0.5073
    Predicted:  ohlol, Epoch [15/ 15] loss=0.4934
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73020.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73020.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73020.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度學習篇---深度學習中的范數

文章目錄 前言一、向量范數1.L0范數1.1定義1.2計算式1.3特點1.4應用場景1.4.1特征選擇1.4.2壓縮感知 2.L1范數&#xff08;曼哈頓范數&#xff09;2.1定義2.2計算式2.3特點2.4應用場景2.4.1L1正則化2.4.2魯棒回歸 3.L2范數&#xff08;歐幾里得范數&#xff09;3.1定義3.2特點3…

星越L_燈光操作使用講解

目錄 1.開啟前照燈 2左右轉向燈、遠近燈 3.auto自動燈光 4.自適應遠近燈光 5.后霧燈 6.調節大燈高度 1.開啟前照燈 2左右轉向燈、遠近燈 3.auto自動燈光 系統根據光線自動開啟燈光

Stable Diffusion lora訓練(一)

一、不同維度的LoRA訓練步數建議 2D風格訓練 數據規模&#xff1a;建議20-50張高質量圖片&#xff08;分辨率≥10241024&#xff09;&#xff0c;覆蓋多角度、多表情的平面風格。步數范圍&#xff1a;總步數控制在1000-2000步&#xff0c;公式為 總步數 Repeat Image Epoch …

AI 生成 PPT 網站介紹與優缺點分析

隨著人工智能技術不斷發展&#xff0c;利用 AI 自動生成 PPT 已成為提高演示文稿制作效率的熱門方式。本文將介紹幾款主流的 AI PPT 工具&#xff0c;重點列出免費使用機會較多的網站&#xff0c;并對各平臺的優缺點進行詳細分析&#xff0c;幫助用戶根據自身需求選擇合適的工具…

使用Systemd管理ES服務進程

Centos中的Systemd介紹 CentOS 中的 Systemd 詳細介紹 Systemd 是 Linux 系統的初始化系統和服務管理器&#xff0c;自 CentOS 7 起取代了傳統的 SysVinit&#xff0c;成為默認的初始化工具。它負責系統啟動、服務管理、日志記錄等核心功能&#xff0c;顯著提升了系統的啟動速…

【一維前綴和與二維前綴和(簡單版dp)】

1.前綴和模板 一維前綴和模板 1.暴力解法 要求哪段區間&#xff0c;我就直接遍歷那段區間求和。 時間復雜度O(n*q) 2.前綴和 ------ 快速求出數組中某一個連續區間的和。 1&#xff09;預處理一個前綴和數組 這個前綴和數組設定為dp&#xff0c;dp[i]表示&#xff1a;表示…

在Windows和Linux系統上的Docker環境中使用的鏡像是否相同

在Windows和Linux系統上的Docker環境中使用的鏡像是否相同&#xff0c;取決于具體的運行模式和目標平臺&#xff1a; 1. Linux容器模式&#xff08;默認/常見場景&#xff09; Windows系統&#xff1a; 當Windows上的Docker以Linux容器模式運行時&#xff08;默認方式&#xf…

植物來源藥用天然產物的合成生物學研究進展-文獻精讀121

植物來源藥用天然產物的合成生物學研究進展 摘要 大多數藥用天然產物在植物中含量低微&#xff0c;提取分離困難&#xff1b;而且這些化合物一般結構復雜&#xff0c;化學合成難度大&#xff0c;還容易造成環境污染。基于合成生物學技術獲得藥用天然產物具有綠色環保和可持續發…

JavaScript |(五)DOM簡介 | 尚硅谷JavaScript基礎實戰

學習來源&#xff1a;尚硅谷JavaScript基礎&實戰丨JS入門到精通全套完整版 筆記來源&#xff1a;在這位大佬的基礎上添加了一些東西&#xff0c;歡迎大家支持原創&#xff0c;大佬太棒了&#xff1a;JavaScript |&#xff08;五&#xff09;DOM簡介 | 尚硅谷JavaScript基礎…

瀏覽器工作原理深度解析(階段二):HTML 解析與 DOM 樹構建

一、引言 在階段一中&#xff0c;我們了解了瀏覽器通過 HTTP/HTTPS 協議獲取頁面資源的過程。本階段將聚焦于瀏覽器如何解析 HTML 代碼并構建 DOM 樹&#xff0c;這是渲染引擎的核心功能之一。該過程可分為兩個關鍵步驟&#xff1a;詞法分析&#xff08;Token 化&#xff09;和…

The Illustrated Stable Diffusion

The Illustrated Stable Diffusion 1. The components of Stable Diffusion1.1. Image information creator1.2. Image Decoder 2. What is Diffusion anyway?2.1. How does Diffusion work?2.2. Painting images by removing noise 3. Speed Boost: Diffusion on compressed…

yarn 裝包時 package里包含sqlite3@5.0.2報錯

yarn 裝包時 package里包含sqlite35.0.2報錯 解決方案&#xff1a; 第一步&#xff1a; 刪除package.json里的sqlite35.0.2 第二步&#xff1a; 裝包&#xff0c;或者增加其他的npm包 第三步&#xff1a; 在package.json里增加sqlite35.0.2&#xff0c;并運行yarn裝包 此…

一個免費 好用的pdf在線處理工具

pdf24 doc2x 相比上面能更好的支持數學公式。但是收費

buu-bjdctf_2020_babystack2-好久不見51

整數溢出漏洞 將nbytes設置為-1就會回繞&#xff0c;變成超大整數 從而實現棧溢出漏洞 環境有問題 from pwn import *# 連接到遠程服務器 p remote("node5.buuoj.cn", 28526)# 定義后門地址 backdoor 0x400726# 發送初始輸入 p.sendlineafter(b"your name…

DHCP 配置

? 最近發現&#xff0c;自己使用虛擬機建立的集群&#xff0c;在斷電關機或者關機一段時間后&#xff0c;集群之間的鏈接散了&#xff0c;并且節點自身的 IP 也發生了變化&#xff0c;發現是 DHCP 的問題&#xff0c;這里記錄一下。 DHCP ? DHCP&#xff08;Dynamic Host C…

股指期貨合約的命名規則是怎樣的?

股指期貨合約的命名規則其實很簡單&#xff0c;主要由兩部分組成&#xff1a;合約代碼和到期月份。 股指期貨合約4個字母數字背后的秘密 股指期貨合約一般來說都是由字母和數字來組合的&#xff0c;包含了品種代碼和到期的時間&#xff0c;下面我們具體來看看。 咱們以“IF23…

OSPF 協議詳解:從概念原理到配置實踐的全網互通實現

什么是OSPF OSPF&#xff08;開放最短路徑優先&#xff09;是由IETF開發的基于鏈路狀態的自治系統內部路由協議&#xff0c;用來代替存在一些問題的RIP協議。與距離矢量協議不同&#xff0c;鏈路狀態路由協議關心網絡中鏈路活接口的狀態&#xff08;包括UP、DOWN、IP地址、掩碼…

深入探究 JVM 堆的垃圾回收機制(二)— 回收

GC Roots 枚舉需要遍歷整個應用程序的上下文&#xff0c;而在進行可達性分析或者垃圾回收時&#xff0c;如果我們還是進行全堆掃描及收集&#xff0c;那么會非常耗時。JVM 將堆分為新生代及老生代&#xff0c;它們的回收頻率及算法不一樣。 1 回收算法 在進行可達性分析時&am…

藍橋杯 之 數論

文章目錄 習題質數找素數 數論&#xff0c;就是一些數學問題&#xff0c;藍橋杯十分喜歡考察&#xff0c;常見的數論的問題有&#xff1a;取模&#xff0c;同余&#xff0c;大整數分解&#xff0c;素數&#xff0c;質因數&#xff0c;最大公約數&#xff0c;最小公倍數等等 素…

Unity Shader編程】之渲染流程之深度及pass詳解

關于透明物體的渲染&#xff0c;首先需要了解以下部分 深度緩沖區深度寫入深度測試pass渲染和深度測試的過程深度測試和顏色混合過程 ** 一&#xff0c;深度緩沖區 ** 深度即物體距離相機的距離&#xff0c;深度寫入即是把物體的距離相機信息記錄下來&#xff0c;寫入一個名…