首页 > 其他分享 >【简单的基于循环神经网络(RNN)的模型(深度学习经典代码实现)】

【简单的基于循环神经网络(RNN)的模型(深度学习经典代码实现)】

时间:2024-11-14 22:15:55浏览次数:3  
标签:loss RNN self torch 神经网络 input hidden 代码 size

import torch
#Code – Parameters
input_size = 4
hidden_size = 4
num_layers = 1
batch_size = 1
seq_len = 5
#Code – Prepare Data
idx2char = ['e', 'h', 'l', 'o']
x_data = [1, 0, 2, 2, 3]
y_data = [3, 1, 2, 3, 2]
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]
inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size, input_size)
labels = torch.LongTensor(y_data)
#Code – Design Model
class Model(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size, num_layers=1):
        super(Model, self).__init__()
        self.num_layers = num_layers
        self.batch_size = batch_size
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.rnn = torch.nn.RNN(input_size=self.input_size,
                                hidden_size=self.hidden_size,
                                num_layers=num_layers)

    def forward(self, input):
        hidden = torch.zeros(self.num_layers,
                             self.batch_size,
                             self.hidden_size)
        out, _ = self.rnn(input, hidden)
        return out.view(-1, self.hidden_size)

net = Model(input_size, hidden_size, batch_size, num_layers)
#Code – Loss and Optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.05)
#Code – Training Cycle
for epoch in range(15):
    optimizer.zero_grad()
    outputs = net(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    _, idx = outputs.max(dim=1)
    idx = idx.data.numpy()
    print('Predicted: ', ''.join([idx2char[x] for x in idx]), end='')
    print(', Epoch [%d/15] loss = %.3f' % (epoch + 1, loss.item()))

这段代码实现了一个简单的基于循环神经网络(RNN)的模型,用于处理序列数据并进行预测。通过不断地训练迭代,利用定义的损失函数和优化器来优化模型参数,以提高预测的准确性。

代码详细解释:

  1. 导入必要的库
import torch

导入了 torch 库,它是一个广泛应用于深度学习的框架,提供了丰富的张量操作、神经网络模块以及优化算法等功能,用于构建和训练各种神经网络模型。
2. 定义代码参数

input_size = 4
hidden_size = 4
num_layers = 1
batch_size = 1
seq_len = 5

这里定义了一系列模型相关的参数:
input_size:表示输入数据的特征维度,即每个时间步输入到模型中的数据特征数量,这里设置为 4。
hidden_size:代表隐藏层的大小,也就是循环神经网络(RNN)内部隐藏状态的维度,设置为 4。
num_layers:指定了 RNN 的层数,这里设置为 1,表示使用单层的 RNN 结构。
batch_size:确定了每次训练时处理的数据批量大小,这里是 1,意味着每次只处理一个样本数据。
seq_len:表示输入序列的长度,即数据在时间维度上的长度,这里设置为 5。
3. 准备数据

idx2char = ['e', 'h', 'l', 'o']
x_data = [1, 0, 2, 2, 3]
y_data = [3, 1, 2, 3, 2]
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]
inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size, input_size)
labels = torch.LongTensor(y_data)

idx2char:是一个字符列表,用于将模型输出的索引转换为对应的字符,以便后续展示预测结果。
x_data 和 y_data:分别是输入数据和对应的目标数据的索引表示。例如,x_data 中的每个值对应着 idx2char 中的一个字符索引。
one_hot_lookup:构建了一个查找表,用于将索引转换为对应的独热编码(One-Hot Encoding)向量。独热编码可以将类别型数据转换为机器更易处理的向量形式,每个向量只有一个元素为 1,其余为 0,对应着不同的类别。
x_one_hot:通过列表推导式,根据 x_data 中的索引从 one_hot_lookup 中获取对应的独热编码向量,将输入数据转换为独热编码形式。
inputs:将 x_one_hot 转换为 torch.Tensor 类型,并通过 view 方法调整其形状,使其符合模型输入的要求,即形状为 (seq_len, batch_size, input_size)。这样就将输入数据整理成了适合输入到 RNN 模型中的格式,其中 seq_len 表示序列长度,batch_size 表示批量大小,input_size 表示输入特征维度。
labels:将 y_data 转换为 torch.LongTensor 类型,作为模型训练时的目标标签,用于与模型输出进行对比计算损失值。
4. 设计模型

class Model(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size, num_layers=1):
        super(Model, self).__init__()
        self.num_layers = num_layers
        self.batch_size = batch_size
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.rnn = torch.nn.RNN(input_size=self.input_size,
                                hidden_size=self.hidden_size,
                                num_layers=num_layers)

    def forward(self, input):
        hidden = torch.zeros(self.num_layers,
                             self.batch_size,
                             self.hidden_size)
        out, _ = self.rnn(input, hidden)
        return out.view(-1, self.hidden_size)
net = Model(input_size, hidden_size, batch_size, num_layers)

在 Model 类的构造函数 init 中:
首先通过 super(Model, self).init() 调用父类 torch.nn.Module 的构造函数,以初始化模型的一些基本属性和方法。
然后定义了模型自身的一些属性,如 num_layers、batch_size、input_size、hidden_size,并创建了一个 torch.nn.RNN 对象 self.rnn,用于处理整个序列的循环神经网络计算,根据之前定义的参数设置了其输入大小、隐藏层大小和层数等属性。
在 forward 方法中:
首先创建一个全零的隐藏状态张量 hidden,其形状由 num_layers、batch_size 和 hidden_size 决定,用于作为 RNN 模型的初始隐藏状态。
然后将输入数据 input 和隐藏状态 hidden 传递给 self.rnn 进行前向传播计算,得到输出 out 和更新后的隐藏状态(这里我们暂时不关心更新后的隐藏状态,所以用 _ 忽略它)。
最后将输出 out 的形状通过 view 方法调整为 (-1, hidden_size),以便后续与目标标签进行对比计算损失值等操作,其中 -1 表示自动根据其他维度计算该维度的大小。
5. 定义损失和优化器

criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.05)

criterion:定义了损失函数为 torch.nn.CrossEntropyLoss(),它常用于多分类问题,能够根据模型输出的预测概率分布和实际的目标标签计算损失值。
optimizer:选择了 torch.optim.Adam 作为优化器,它会根据设定的学习率(这里为 0.05)对模型的参数(通过 net.parameters() 获取)进行优化,以使得损失函数在训练过程中逐渐减小。
6. 训练周期

for epoch in range(15):
    optimizer.zero_grad()
    outputs = net(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    _, idx = outputs.max(dim=1)
    idx = idx.data.numpy()
    print('Predicted: ', ''.join([idx2char[x] for x in idx]), end='')
    print(', Epoch [%d/15] loss = %.3f' % (epoch + 1, loss.item()))

在这个循环中,进行了 15 次训练迭代(epoch):
每次迭代开始时,通过 optimizer.zero_grad() 清除上一次迭代中模型参数的梯度信息,以便重新计算本次迭代的梯度。
然后将输入数据 inputs 传递给模型 net 进行前向传播计算,得到模型输出 outputs。
接着通过 criterion(outputs, labels) 计算模型输出与目标标签之间的损失值 loss。
之后通过 loss.backward() 进行反向传播,计算模型参数关于损失函数的梯度。
再通过 optimizer.step() 根据计算得到的梯度更新模型的参数。
最后通过 outputs.max(dim=1) 获取输出在维度 1 上的最大值及其索引 idx,将索引转换为 numpy 数组形式,然后利用 idx2char 将索引转换为对应的字符并拼接成字符串,通过 print 输出预测的字符串内容,同时输出当前 epoch 的相关信息,包括 epoch 编号和损失值。

运行结果:
Predicted: hhell, Epoch [1/15] loss = 1.347
Predicted: lhlol, Epoch [2/15] loss = 1.192
Predicted: lhlol, Epoch [3/15] loss = 1.059
Predicted: lhlol, Epoch [4/15] loss = 0.954
Predicted: lhlol, Epoch [5/15] loss = 0.876
Predicted: lhlol, Epoch [6/15] loss = 0.823
Predicted: lhlol, Epoch [7/15] loss = 0.787
Predicted: lhlol, Epoch [8/15] loss = 0.760
Predicted: lhlol, Epoch [9/15] loss = 0.738
Predicted: lhlol, Epoch [10/15] loss = 0.717
Predicted: lhlol, Epoch [11/15] loss = 0.697
Predicted: lhlol, Epoch [12/15] loss = 0.678
Predicted: lhlol, Epoch [13/15] loss = 0.661
Predicted: ohlol, Epoch [14/15] loss = 0.644
Predicted: ohlol, Epoch [15/15] loss = 0.629

标签:loss,RNN,self,torch,神经网络,input,hidden,代码,size
From: https://blog.csdn.net/RG_xwz/article/details/143770727

相关文章