各类神经网络学习:(四)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(Wihx+bih+Whhh+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(Uxt+Wst1+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} bihbhh
      • 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(WihTx+bih+WhhTht1+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(Uxt+Wst1+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} bihbhh

      • batch_first (bool):输入输出格式设置项,默认为 False -------- 如果为 True 则用户需要按照
                                      (batch_size, seq_len, input_size) 来构造数据格式,
                                     默认是 (seq_len, batch_size, input_size)

      • dropout :神经元随机丢弃概率( 0 ∼ 1 0\sim1 01),默认值:0 ------------- 如果非零,则在除最后一层之外的每个 RNN
                                      的输出上引入一个 Dropout 层,会在训练过程
                                      中随机丢弃一部分神经元(即将其输出置为零),
                                      dropout 的概率等于 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}) (Dnum_layers,N,Hout) ( D ∗ n u m _ l a y e r s , H o u t ) (D*num\_layers,H_{out}) (Dnum_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,DHout) ( L , D ∗ H o u t ) (L,D*H_{out}) (L,DHout) ------------------------当 batch_first=True 时为 ( N , L , D ∗ H o u t ) (N,L,D∗H_{out}) (N,L,DHout)
      • hidden :类型:tensor,形状: ( D ∗ n u m _ l a y e r s , N , H o u t ) (D*num\_layers,N,H_{out}) (Dnum_layers,N,Hout) ( D ∗ n u m _ l a y e r s , H o u t ) (D*num\_layers,H_{out}) (Dnum_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.rhkb.cn/news/39951.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…

Harbor镜像仓库迁移与高可用集群搭建HTTPS实现实战指南

实验环境 Ubuntu22.04操作系统 registry节点 10.0.0.91 master节点 10.0.0.92 backup节点 10.0.0.93 在企业信息化建设的不同演进阶段&#xff0c;私有镜像仓库的选型策略存在显著差异。近期主导完成某企业级容器镜像仓库升级项目&#xff0c;成功实现Docker Registry至Ha…

【Python】pillow库学习笔记3-Image.mode

提取颜色通道时&#xff0c;偶然换了个图片&#xff0c;结果在在运行代码时一直报错&#xff1a; from PIL import Image im Image.open(city2.png) r,g,b im.split() om Image.merge("RGB", (b,g,r)) om.save(cBGR.jpg)Traceback (most recent call last): File…

PDF打开密码教程:让您的文档更安全

在数字化办公时代&#xff0c;PDF 文件常包含敏感信息&#xff0c;这时候&#xff0c;给PDF文件设置打开密码就成了一种有效的保护措施。这样&#xff0c;只有输入正确密码的人才能查看内容&#xff0c;大大提高了文件的安全性。如果您对这方面不清楚&#xff0c;就来看看小编分…

SOFAActs 介绍-01-白盒测试框架 overview

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概览 SOFABoot-01-蚂蚁金服开源的 s…

Snipaste软件出现测量像素不准的问题

最近写一些前端布局的时候发现使用snipaste测量dom元素大小的时候出现和实际不符的情况。我平时写代码的时候是笔记本和一个显示屏&#xff0c;在笔记本上测量的时候发现总是和实际大小不符合&#xff0c;而在显示屏上测量的时候却并无差错&#xff0c;真是奇了怪了。 后来发现…

笔试专题(三)

文章目录 字符串中找出连续最长的数字串题解代码 拼三角题解代码 字符串中找出连续最长的数字串 题目链接 题解 1. 考察双指针 模拟 2. 算法思路&#xff1a;给定一个i 0&#xff0c;让i&#xff0c;如果遇到数字字符就创建一个变量j i&#xff0c;让j去遍历&#xff0c…

基于vue.js开发的家庭装修管理系统开发与设计(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本家庭装修管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Node.js语言进行编写&#xff0c;使用了VUE框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户的功能包括&#xff1a;注册、登录、浏览首页…

NAT网络地址转换与内网穿透

一、背景 前一篇文章提到PCDN&#xff0c; 也就是p2p技术CDN技术进行融合。 P2P技术有利于文件的快速分发。我们的CDN在控制节点分发数据的时候&#xff0c;向边缘节点传输数据&#xff0c;也是一种分发&#xff0c;还有各边缘节点强制同步数据等等&#xff0c;如果结合P2P技术…

【开源宝藏】30天学会CSS - DAY9 第九课 牛顿摆动量守恒动画

以下是一份逐步拆解教程&#xff0c;带你从零理解并复刻这个牛顿摆&#xff08;Pendulum of Newton&#xff09;动画效果&#xff0c;这是一个经典的物理演示模型&#xff0c;现在通过纯 HTML 和 CSS 实现出来&#xff0c;视觉效果炫酷、结构简洁。 &#x1f3af; 动画效果说明…

Chat2DB:一款强大的数据库管理工具,AI助力高效查询与分析

AI技术可谓是日新月异&#xff0c;其已经融入到社会的方方面面&#xff0c;今天就给大家分享一款数据库SQL客户端工具&#xff1a;Chat2DB。 1 简介 Chat2DB是一款开源的数据库管理工具&#xff0c;集成了AI 智能辅助功能&#xff0c;支持自然语言生成 SQL&#xff0c;帮助开发…

安全上网沙箱:多方面解决政企私的上网问题

在数字化的浪潮中&#xff0c;网络已成为我们工作与生活不可或缺的一部分。然而&#xff0c;网络的便捷也伴随着诸多安全隐患&#xff0c;尤其是对于企业、个人以及政企机构而言&#xff0c;安全上外网成为了至关重要的课题。 隔离保护&#xff1a;构建安全堡垒 沙箱技术在内网…

【react18】react项目使用mock模拟后台接口

前后端分离项目&#xff0c;后端还没有接口的时候&#xff0c;前端可以使用mockjs的技术实行假数据的模拟。这里使用的是mock的库msw实现这个业务. MSW msw是mock的工具&#xff0c;官网地址是在这里 使用步骤 1.安装msw npm install mswlatest --save-dev2.新建存放mock接…

2、pytest核心功能(进阶用法)

目录 1、标记&#xff08;Markers&#xff09;&#xff1a; 自定义插件 内置标记 2、夹具&#xff08;Fixtures&#xff09;&#xff1a; 夹具得用法 夹具作用域 3、钩子&#xff08;hook&#xff09;&#xff1a; 这篇是最重要的 测试文件中需要用到的 总的来说 有以下…

《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型

《TCP/IP网络编程》学习笔记 | Chapter 21&#xff1a;异步通知 I/O 模型 《TCP/IP网络编程》学习笔记 | Chapter 21&#xff1a;异步通知 I/O 模型同步与异步同步异步对比同步 I/O 的缺点异步 I/O 的优点 理解异步通知 I/O 模型实现异步通知 I/O 模型WSAEventSelect 函数和通知…

【2025】基于springboot+vue的医院在线问诊系统设计与实现(源码、万字文档、图文修改、调试答疑)

基于Spring Boot Vue的医院在线问诊系统设计与实现功能结构图如下&#xff1a; 课题背景 随着互联网技术的飞速发展和人们生活水平的不断提高&#xff0c;传统医疗模式面临着诸多挑战&#xff0c;如患者就医排队时间长、医疗资源分配不均、医生工作压力大等。同时&#xff0c;…

报错 standard_init_linux.go:228: exec user process caused: exec format error

docker logs 容器名 报错&#xff1a; standard_init_linux.go:228: exec user process caused: exec format error 或者 standard_init_linux.go:228: exec user process caused: input/output error 排查思路 1、检查源镜像的框架是否正确&#xff0c;是否amd64&#x…

26考研——图_图的存储(6)

408答疑 文章目录 二、图的存储图的存储相关概念邻接矩阵存储方式邻接矩阵的定义顶点的度计算邻接矩阵的特点邻接矩阵的局限性 应用场景邻接矩阵的幂次意义&#xff08;了解即可&#xff09; 邻接表存储方式邻接表定义邻接表结构邻接表的特点 邻接矩阵和邻接表的适用性差异十字…

机器学习(八)

一&#xff0c;基于协同过滤的推广算法&#xff1a; 算法原理&#xff1a; 基于用户的协同过滤(计算用户相似度→找出相似用户→根据相似用户的喜好推荐物品) 基于物品的协同过滤(计算物品相似度→找出用户喜欢的物品→推荐相似物品) 构造矩阵进行分解(将用户-物品评分矩阵分解…

云原生算力引擎:分布式推理的流体动力学

引言&#xff1a;算力黑洞的引力扰动 OpenAI推理集群日处理4.5亿次请求&#xff0c;CUDA 12.3实现μs级张量切换。特斯拉Dojo超算芯片间延迟0.5ns&#xff0c;阿里巴巴PAI平台节省58%训练时长。HuggingFace模型库下载量突破3亿次&#xff0c;AWS Inferentia芯片能效比提升8倍。…