【深度学习】PyTorch深度学习实践 - Lecture_12_Basic_RNN

news2024/11/24 12:45:19

文章目录

  • 一、RNN介绍
    • 1.1 RNN为什么能处理有序数据?
    • 1.2 RNNCell内部剖析
  • 二、How to use RNNCell In PyTorch
    • 2.1 参数分析
    • 2.2 PyTorch代码实现
  • 三、How to use RNN In PyTorch
    • 3.1 参数分析
    • 3.2 NumLayers
    • 3.3 PyTorch代码实现
    • 3.4 其他参数
  • 四、Example1:Using RNNCell
    • 4.1 问题描述
    • 4.2 字符向量化
    • 4.3 RNNCell 结构描述
    • 4.4 PyTorch代码实现
  • 五、Example2:Using RNN Module
    • 5.1 题目描述
    • 5.2 PyTorch代码实现
  • 六、Embedding
    • 6.1 Embedding引入
    • 6.2 Embedding Layer
    • 6.3 Using Embedding and Linear Layer
    • 6.4 PyTorch代码
  • 七、课后练习1:使用LSTM
    • 7.1 初识LSTM
    • 7.2 PyTorch代码
  • 八、课后练习2:使用GRU
    • 8.1 初识GRU
    • 8.2 PyTorch代码


一、RNN介绍

1.1 RNN为什么能处理有序数据?

RNN的特点在于其可以用来处理有顺序要求的分类任务,例如自然语言处理、时间序列预测等。
Q:那么RNN为什么可以处理有序数据呢?
A:因为其具有一个特殊结构,称之为RNNCell。

如下图所示,在RNNCell最左端输入是h0,h0可以看作是先验知识,例如我们希望根据图片和要求的主题来输出对应文字,那么我们可以在最左端加一个CNN提取图片特征,然后加一个LinearLayer将其转化为一维张量h0传入最左边的RNNCell,而要求的主题就通过一定编码方式(如OneHot编码)转化为x1、x2、x3等数值型数据依次传入每个RNNCell。

观察下图,我们不难发现,h0和x1在第一个RNNCell的转化后输出为h1,h1又作为第二个RNNCell的输入与x2一起被转化输出为h2,以此类推…

所以,由于RNNCell的这种串联结构,x1、x2、x3、x4的输入顺序不同,会导致最右端的RNNCell输出不同,这样就使得RNN可以有效处理有序的数据啦!
在这里插入图片描述

1.2 RNNCell内部剖析

通过1.1节的学习,大家一定很好奇h0和x1被输入第一个RNNCell后发生了什么?输出的h1是通过怎样的运算得到的?RNNCell内部是什么?这一节,我就带大家剖析一下RNNCell的内部!

我们以h0、x1作为输入,h1作为输出来进行讲解

很明显,通常情况下,h0和x1的尺寸是不一样的,然而他们后面却需要进行相加的操作(相加操作的前提是两个张量的尺寸一样),为了让他们尺寸一样,我们可以固定h0的尺寸不变,对x1进行左乘或者右乘的操作改变它的尺寸,假设x1尺寸为(1,4),h0尺寸为(1,2),那么我们可以让x1右乘一个尺寸为(4,2)的矩阵,这样就可以将x1的尺寸转化为(1,2)啦

同时,h0也需要乘上一个和自身最大维度值相同的方阵,然后还要加上一个偏置b,类似于LinearLayer中做的wx+b的线性变换

最后,两个调整后的张量进行相加,送入tanh激活函数进行激活,从RNNCell输出
在这里插入图片描述

二、How to use RNNCell In PyTorch

2.1 参数分析

batchSize:每条输入数据的行数(相当于图片的高)
inputSize:每条输入数据的列数(相当于图片的宽)
seqLen:输入数据总条数(相当于图片的数量)
hiddenSize:输出的隐藏层的列数
在这里插入图片描述
在这里插入图片描述

2.2 PyTorch代码实现

在这里插入图片描述

import torch

batch_size = 1
seq_len = 3
input_size = 4
hidden_size = 2

rnn_cell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size)

dataset = torch.randn(seq_len, batch_size, input_size)
hidden = torch.zeros(batch_size, hidden_size)

for idx, input in enumerate(dataset):
    print('=' * 20, idx, input.shape, '=' * 20)
    print('inputs size: ', input.shape, input)

    hidden = rnn_cell(input, hidden)

    print('outputs size: ', hidden.shape)
    print('hidden: ', hidden)

输出:

==================== 0 torch.Size([1, 4]) ====================
inputs size:  torch.Size([1, 4]) tensor([[ 0.2541, -1.2645,  0.7802,  0.6456]])
outputs size:  torch.Size([1, 2])
hidden:  tensor([[-0.6157, -0.8336]], grad_fn=<TanhBackward>)
==================== 1 torch.Size([1, 4]) ====================
inputs size:  torch.Size([1, 4]) tensor([[ 0.1633, -2.2329, -1.4008,  0.8531]])
outputs size:  torch.Size([1, 2])
hidden:  tensor([[-0.7916, -0.9344]], grad_fn=<TanhBackward>)
==================== 2 torch.Size([1, 4]) ====================
inputs size:  torch.Size([1, 4]) tensor([[-0.3875, -0.1787,  0.1510,  0.3284]])
outputs size:  torch.Size([1, 2])
hidden:  tensor([[-0.6885, -0.9451]], grad_fn=<TanhBackward>)

三、How to use RNN In PyTorch

3.1 参数分析

在这里插入图片描述
在这里插入图片描述

3.2 NumLayers

下图所示 NumLayers = 3,RNN纵向的层数

注意:在1.1节示例图中的NumLayers=1
在这里插入图片描述

3.3 PyTorch代码实现

在这里插入图片描述

import torch

batch_size = 1
seq_len = 3
input_size = 4
hidden_size = 2
num_layers = 1

rnn = torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)

inputs = torch.randn(seq_len, batch_size, input_size)
hidden = torch.zeros(num_layers, batch_size, hidden_size)

output, hidden = rnn(inputs, hidden)

print('output size: ', output.shape)
print('output: ', output)
print('hidden size: ', hidden.shape)
print('hidden: ', hidden)

输出:

output size:  torch.Size([3, 1, 2])
output:  tensor([[[-0.5995, -0.6150]],

        [[-0.7170,  0.6757]],

        [[-0.5708, -0.6134]]], grad_fn=<StackBackward>)
hidden size:  torch.Size([1, 1, 2])
hidden:  tensor([[[-0.5708, -0.6134]]], grad_fn=<StackBackward>)

3.4 其他参数

在这里插入图片描述

四、Example1:Using RNNCell

4.1 问题描述

训练一个模型,实现序列到序列的转化,如"hello" 转化为 “ohlol”
在这里插入图片描述

4.2 字符向量化

由于"hello"是字符型数据,不能直接进行计算,所以我们首先需要对其进行向量化
在这里插入图片描述
由上图可以看出,InputSize = 4

4.3 RNNCell 结构描述

在这里插入图片描述

在这里插入图片描述

4.4 PyTorch代码实现

import torch


class RNNModel(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size):
        super(RNNModel, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.batch_size = batch_size
        self.rnn_cell = torch.nn.RNNCell(input_size=self.input_size, hidden_size=self.hidden_size)

    def forward(self, input, hidden):
        hidden = self.rnn_cell(input, hidden)
        return hidden

    def init_hidden(self):
        return torch.zeros(self.batch_size, self.hidden_size)


if __name__ == '__main__':
    input_size = 4
    hidden_size = 4
    batch_size = 1

    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[i] for i in x_data]

    inputs = torch.Tensor(x_one_hot).view(-1, batch_size, input_size)
    labels = torch.LongTensor(y_data).view(-1, 1)

    # 声明RNN模型
    rnn = RNNModel(input_size, hidden_size, batch_size)
    # 损失函数
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器
    optimizer = torch.optim.Adam(rnn.parameters(), lr=0.05)

    # 开始循环迭代训练
    for epoch in range(15):
        loss = 0
        optimizer.zero_grad()
        hidden = rnn.init_hidden()
        print("Predicted String: ", end='')
        for input, label in zip(inputs, labels):
            hidden = rnn(input, hidden)
            loss += criterion(hidden, label)
            _, 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: hhool , Epoch [1/15] loss=6.7361
Predicted String: hhooo , Epoch [2/15] loss=6.0646
Predicted String: hhooo , Epoch [3/15] loss=5.5975
Predicted String: ohooo , Epoch [4/15] loss=5.2145
Predicted String: ohooo , Epoch [5/15] loss=4.9139
Predicted String: ohool , Epoch [6/15] loss=4.6862
Predicted String: ohool , Epoch [7/15] loss=4.4854
Predicted String: ohool , Epoch [8/15] loss=4.2690
Predicted String: ohlol , Epoch [9/15] loss=4.0282
Predicted String: ohlol , Epoch [10/15] loss=3.7796
Predicted String: ohlol , Epoch [11/15] loss=3.5468
Predicted String: ohlol , Epoch [12/15] loss=3.3460
Predicted String: ohlol , Epoch [13/15] loss=3.1812
Predicted String: ohlol , Epoch [14/15] loss=3.0479
Predicted String: ohlol , Epoch [15/15] loss=2.9385

可以看出,从第9代开始,预测出的字符串就已经正确了(ohlol)

五、Example2:Using RNN Module

5.1 题目描述

题目和4.1节的一样

5.2 PyTorch代码实现

import torch


class RNNModel(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size, num_layers=1):
        super(RNNModel, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.batch_size = batch_size
        self.num_layers = num_layers
        self.rnn = torch.nn.RNN(input_size=self.input_size, hidden_size=self.hidden_size, num_layers=self.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)


if __name__ == '__main__':
    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]
    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[i] for i in x_data]

    inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size, input_size)
    labels = torch.LongTensor(y_data)

    # 声明RNN模型
    rnn_model = RNNModel(input_size, hidden_size, batch_size, num_layers)
    # 损失函数
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器
    optimizer = torch.optim.Adam(rnn_model.parameters(), lr=0.05)

    # 开始循环迭代训练
    for epoch in range(15):
        optimizer.zero_grad()
        outputs = rnn_model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        _, idx = outputs.max(dim=1)
        idx = idx.data.numpy()
        print("Predicted String: ", ''.join([idx2char[x] for x in idx]), end='')
        print(' , Epoch [%d/15] loss=%.4f' % (epoch + 1, loss.item()))

输出:

Predicted String:  hhhhh , Epoch [1/15] loss=1.5084
Predicted String:  hhhhl , Epoch [2/15] loss=1.3756
Predicted String:  lhhhl , Epoch [3/15] loss=1.2340
Predicted String:  lhlhl , Epoch [4/15] loss=1.0910
Predicted String:  lhlhl , Epoch [5/15] loss=0.9662
Predicted String:  lhlhl , Epoch [6/15] loss=0.8737
Predicted String:  ohlhl , Epoch [7/15] loss=0.8107
Predicted String:  ohlol , Epoch [8/15] loss=0.7672
Predicted String:  ohlol , Epoch [9/15] loss=0.7348
Predicted String:  ohlol , Epoch [10/15] loss=0.7087
Predicted String:  ohlol , Epoch [11/15] loss=0.6867
Predicted String:  ohlol , Epoch [12/15] loss=0.6677
Predicted String:  ohlol , Epoch [13/15] loss=0.6505
Predicted String:  ohlol , Epoch [14/15] loss=0.6340
Predicted String:  ohlol , Epoch [15/15] loss=0.6170

六、Embedding

6.1 Embedding引入

让我们先来聊聊OneHot编码的缺点:

  • One-Hot一般是高维度的(维度灾难)
  • One-Hot是稀疏的
  • One-Hot是硬编码(hard-coded),是依照规则确定的,不是学习出来的

我们希望有一种编码方式,可以具有以下优点:

  • 低纬度的
  • 稠密的
  • 是从data中学习出来的

符合以上优点的 一个流行的有效的编码方式叫做 Embedding(嵌入式的)
在这里插入图片描述

6.2 Embedding Layer

在这里插入图片描述
在这里插入图片描述

6.3 Using Embedding and Linear Layer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.4 PyTorch代码

import torch


class RNNModel(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size, num_layers=1, embedding_size=1):
        super(RNNModel, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.batch_size = batch_size
        self.num_layers = num_layers
        self.embedding_size = embedding_size
        self.emb = torch.nn.Embedding(self.input_size, self.embedding_size)
        self.rnn = torch.nn.RNN(input_size=self.embedding_size, hidden_size=self.hidden_size, num_layers=self.num_layers,
                                batch_first=True)
        self.fc = torch.nn.Linear(self.hidden_size, num_class)

    def forward(self, x):
        hidden = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
        x = self.emb(x)
        x, _ = self.rnn(x, hidden)
        x = self.fc(x)
        return x.view(-1, num_class)


if __name__ == '__main__':
    input_size = 4
    hidden_size = 8
    batch_size = 1
    num_layers = 2
    seq_len = 5
    embedding_size = 10
    num_class = 4  # 类别数

    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]
    ]

    inputs = torch.LongTensor(x_data)
    labels = torch.LongTensor(y_data)

    # 声明RNN模型
    rnn_model = RNNModel(input_size, hidden_size, batch_size, num_layers, embedding_size)
    # 损失函数
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器
    optimizer = torch.optim.Adam(rnn_model.parameters(), lr=0.05)

    # 开始循环迭代训练
    for epoch in range(15):
        optimizer.zero_grad()
        outputs = rnn_model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        _, idx = outputs.max(dim=1)
        idx = idx.data.numpy()
        print("Predicted String: ", ''.join([idx2char[x] for x in idx]), end='')
        print(' , Epoch [%d/15] loss=%.4f' % (epoch + 1, loss.item()))

输出:

Predicted String:  lllll , Epoch [1/15] loss=1.3103
Predicted String:  lllll , Epoch [2/15] loss=1.0623
Predicted String:  ohlll , Epoch [3/15] loss=0.8335
Predicted String:  ohlol , Epoch [4/15] loss=0.6188
Predicted String:  ohlol , Epoch [5/15] loss=0.4204
Predicted String:  ohlol , Epoch [6/15] loss=0.2688
Predicted String:  ohlol , Epoch [7/15] loss=0.1727
Predicted String:  ohlol , Epoch [8/15] loss=0.1132
Predicted String:  ohlol , Epoch [9/15] loss=0.0757
Predicted String:  ohlol , Epoch [10/15] loss=0.0518
Predicted String:  ohlol , Epoch [11/15] loss=0.0362
Predicted String:  ohlol , Epoch [12/15] loss=0.0259
Predicted String:  ohlol , Epoch [13/15] loss=0.0190
Predicted String:  ohlol , Epoch [14/15] loss=0.0142
Predicted String:  ohlol , Epoch [15/15] loss=0.0109

七、课后练习1:使用LSTM

7.1 初识LSTM

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2 PyTorch代码

import torch


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

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


if __name__ == '__main__':
    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]
    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[i] for i in x_data]

    inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size, input_size)
    labels = torch.LongTensor(y_data)

    # 声明RNN模型
    rnn_model = RNNModel(input_size, hidden_size, batch_size, num_layers)
    # 损失函数
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器
    optimizer = torch.optim.Adam(rnn_model.parameters(), lr=0.05)

    # 开始循环迭代训练
    for epoch in range(60):
        optimizer.zero_grad()
        outputs = rnn_model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        _, idx = outputs.max(dim=1)
        idx = idx.data.numpy()
        print("Predicted String: ", ''.join([idx2char[x] for x in idx]), end='')
        print(' , Epoch [%d/15] loss=%.4f' % (epoch + 1, loss.item()))

输出:

Predicted String:  ooooo , Epoch [1/15] loss=1.4331
Predicted String:  ooooo , Epoch [2/15] loss=1.3742
Predicted String:  ooooo , Epoch [3/15] loss=1.3251
Predicted String:  ooooo , Epoch [4/15] loss=1.2809
Predicted String:  ooooo , Epoch [5/15] loss=1.2427
Predicted String:  ooooo , Epoch [6/15] loss=1.2102
Predicted String:  ooooo , Epoch [7/15] loss=1.1820
Predicted String:  ooooo , Epoch [8/15] loss=1.1564
Predicted String:  ooooo , Epoch [9/15] loss=1.1316
Predicted String:  ooooo , Epoch [10/15] loss=1.1060
Predicted String:  ooooo , Epoch [11/15] loss=1.0784
Predicted String:  ooool , Epoch [12/15] loss=1.0484
Predicted String:  ooool , Epoch [13/15] loss=1.0172
Predicted String:  ohool , Epoch [14/15] loss=0.9869
Predicted String:  ohool , Epoch [15/15] loss=0.9592
Predicted String:  ohool , Epoch [16/15] loss=0.9343
Predicted String:  ohool , Epoch [17/15] loss=0.9114
Predicted String:  oholl , Epoch [18/15] loss=0.8901
Predicted String:  oholl , Epoch [19/15] loss=0.8702
Predicted String:  oholl , Epoch [20/15] loss=0.8517
Predicted String:  oholl , Epoch [21/15] loss=0.8344
Predicted String:  oholl , Epoch [22/15] loss=0.8181
Predicted String:  oholl , Epoch [23/15] loss=0.8028
Predicted String:  oholl , Epoch [24/15] loss=0.7885
Predicted String:  oholl , Epoch [25/15] loss=0.7754
Predicted String:  ohlll , Epoch [26/15] loss=0.7639
Predicted String:  ohlll , Epoch [27/15] loss=0.7539
Predicted String:  ohlll , Epoch [28/15] loss=0.7454
Predicted String:  ohlll , Epoch [29/15] loss=0.7382
Predicted String:  ohlll , Epoch [30/15] loss=0.7317
Predicted String:  ohlll , Epoch [31/15] loss=0.7251
Predicted String:  ohlll , Epoch [32/15] loss=0.7182
Predicted String:  ohlll , Epoch [33/15] loss=0.7112
Predicted String:  ohlll , Epoch [34/15] loss=0.7043
Predicted String:  ohlll , Epoch [35/15] loss=0.6978
Predicted String:  ohlll , Epoch [36/15] loss=0.6916
Predicted String:  ohlll , Epoch [37/15] loss=0.6857
Predicted String:  ohlll , Epoch [38/15] loss=0.6800
Predicted String:  ohlll , Epoch [39/15] loss=0.6747
Predicted String:  ohlll , Epoch [40/15] loss=0.6697
Predicted String:  ohlll , Epoch [41/15] loss=0.6651
Predicted String:  ohlll , Epoch [42/15] loss=0.6609
Predicted String:  ohlll , Epoch [43/15] loss=0.6570
Predicted String:  ohlll , Epoch [44/15] loss=0.6535
Predicted String:  ohlll , Epoch [45/15] loss=0.6503
Predicted String:  ohlll , Epoch [46/15] loss=0.6473
Predicted String:  ohlll , Epoch [47/15] loss=0.6445
Predicted String:  ohlll , Epoch [48/15] loss=0.6418
Predicted String:  ohlll , Epoch [49/15] loss=0.6392
Predicted String:  ohlll , Epoch [50/15] loss=0.6366
Predicted String:  ohlll , Epoch [51/15] loss=0.6339
Predicted String:  ohlll , Epoch [52/15] loss=0.6312
Predicted String:  ohlll , Epoch [53/15] loss=0.6284
Predicted String:  ohlll , Epoch [54/15] loss=0.6255
Predicted String:  ohlll , Epoch [55/15] loss=0.6225
Predicted String:  ohlll , Epoch [56/15] loss=0.6193
Predicted String:  ohlol , Epoch [57/15] loss=0.6161
Predicted String:  ohlol , Epoch [58/15] loss=0.6129
Predicted String:  ohlol , Epoch [59/15] loss=0.6097
Predicted String:  ohlol , Epoch [60/15] loss=0.6067

八、课后练习2:使用GRU

8.1 初识GRU

在这里插入图片描述

8.2 PyTorch代码

import torch


class RNNModel(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size, num_layers=1):
        super(RNNModel, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.batch_size = batch_size
        self.num_layers = num_layers
        self.rnn = torch.nn.GRU(input_size=self.input_size, hidden_size=self.hidden_size, num_layers=self.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)


if __name__ == '__main__':
    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]
    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[i] for i in x_data]

    inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size, input_size)
    labels = torch.LongTensor(y_data)

    # 声明RNN模型
    rnn_model = RNNModel(input_size, hidden_size, batch_size, num_layers)
    # 损失函数
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器
    optimizer = torch.optim.Adam(rnn_model.parameters(), lr=0.05)

    # 开始循环迭代训练
    for epoch in range(40):
        optimizer.zero_grad()
        outputs = rnn_model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        _, idx = outputs.max(dim=1)
        idx = idx.data.numpy()
        print("Predicted String: ", ''.join([idx2char[x] for x in idx]), end='')
        print(' , Epoch [%d/15] loss=%.4f' % (epoch + 1, loss.item()))

输出:

Predicted String:  eehhe , Epoch [1/15] loss=1.4254
Predicted String:  ehool , Epoch [2/15] loss=1.3263
Predicted String:  lhool , Epoch [3/15] loss=1.2477
Predicted String:  lhool , Epoch [4/15] loss=1.1825
Predicted String:  lhool , Epoch [5/15] loss=1.1252
Predicted String:  lhool , Epoch [6/15] loss=1.0737
Predicted String:  lhool , Epoch [7/15] loss=1.0279
Predicted String:  lhool , Epoch [8/15] loss=0.9880
Predicted String:  lhool , Epoch [9/15] loss=0.9532
Predicted String:  ohlll , Epoch [10/15] loss=0.9225
Predicted String:  ohlll , Epoch [11/15] loss=0.8949
Predicted String:  ohlll , Epoch [12/15] loss=0.8695
Predicted String:  ohlll , Epoch [13/15] loss=0.8457
Predicted String:  ohlll , Epoch [14/15] loss=0.8229
Predicted String:  ohlll , Epoch [15/15] loss=0.8005
Predicted String:  ohlll , Epoch [16/15] loss=0.7783
Predicted String:  ohlll , Epoch [17/15] loss=0.7564
Predicted String:  ohlll , Epoch [18/15] loss=0.7349
Predicted String:  ohlll , Epoch [19/15] loss=0.7138
Predicted String:  ohlll , Epoch [20/15] loss=0.6932
Predicted String:  ohlll , Epoch [21/15] loss=0.6733
Predicted String:  ohlll , Epoch [22/15] loss=0.6545
Predicted String:  ohlll , Epoch [23/15] loss=0.6372
Predicted String:  ohlll , Epoch [24/15] loss=0.6219
Predicted String:  ohlll , Epoch [25/15] loss=0.6086
Predicted String:  ohlll , Epoch [26/15] loss=0.5968
Predicted String:  ohlll , Epoch [27/15] loss=0.5859
Predicted String:  ohlll , Epoch [28/15] loss=0.5757
Predicted String:  ohlol , Epoch [29/15] loss=0.5660
Predicted String:  ohlol , Epoch [30/15] loss=0.5572
Predicted String:  ohlol , Epoch [31/15] loss=0.5492
Predicted String:  ohlol , Epoch [32/15] loss=0.5419
Predicted String:  ohlol , Epoch [33/15] loss=0.5350
Predicted String:  ohlol , Epoch [34/15] loss=0.5284
Predicted String:  ohlol , Epoch [35/15] loss=0.5219
Predicted String:  ohlol , Epoch [36/15] loss=0.5156
Predicted String:  ohlol , Epoch [37/15] loss=0.5094
Predicted String:  ohlol , Epoch [38/15] loss=0.5035
Predicted String:  ohlol , Epoch [39/15] loss=0.4977
Predicted String:  ohlol , Epoch [40/15] loss=0.4921

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/89607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

fpga实操训练(锁相环pll)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 锁相环pll是fpga区别于stm32、soc很重要的一个特征。通常来说&#xff0c;输入的晶振一般是25m、50m这样的&#xff0c;不一定能满足功能的开发。这…

QT—QList与QLinkedList类的常用方法

QList<T>维护了一个指针数组&#xff0c;数组元素指向每一个链表项&#xff0c;因此QList<T> 提供了基于下标的快速访问。QLinkedList<T>是一个链式列表&#xff0c;不能使用下标访问&#xff0c;与QList相比&#xff0c;当对一个很大的列表进行插入操作时&a…

最近爆火chatGTP是人工智能还是人工智障?

关于chatGTP和一些话题? OpenAI 发布了 ChatGPT&#xff0c;是一个可以对话的方式进行交互的模型&#xff0c;因为它的智能化&#xff0c;得到了很多用户的欢迎。 ChatGPT是InstructGPT的兄弟模型&#xff0c;可以以对话的形式与用户交互&#xff0c;这使得ChatGPT能够回答问…

linux第五章---git的基本操作

git作为代码管理仓库&#xff08;版本管理工具&#xff09;&#xff0c;主要有GitHub和Gitee等等。&#xff0c;大家可以登录官网注册&#xff0c;Github经常访问不到&#xff08;看运气&#xff09;&#xff0c;Gitee作为国内比较火的一个平台(较商业化)。 1.git基本概念 工…

Java连接Access数据库改成MySQL连接数据库

升级诉求&#xff1a;Java连接Access已经算是过时的产物了&#xff0c;一般作为存储服务的应用在Java界比较常用的还是MySQL&#xff0c; 当然还有Oracle数据库。这里要讲的就是连接MySQL数据库了。 就是因为有了SQL标准&#xff0c;各大厂商实现SQL语句基本上大同小异&#xf…

基于Python完成CA系统的设计和实现(附源码)

CA 系统开发 一、CA系统的设计和实现 ​ 注&#xff1a;CA&#xff0c;Certificate Authority&#xff0c;电子认证服务或机构&#xff0c;为电子签名相关各方提供真实性和可靠性验证&#xff0c;是负责发放和管理数字证书的权威机构&#xff0c;并作为电子商务交易中受信任的…

基于Feign远程调用

RestTemplate方式调用存在的问题 先看看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; 1、代码可读性差&#xff0c;编程体验不统一&#xff1b; 2、参数复杂URL难以维护&#xff1b; 为了解决这些问题&#xff0c;所以引入了Feign&am…

QT QStackedWidget 控件 使用详解

本文详细的介绍了QStackedWidget控件的各种操作&#xff0c;例如&#xff1a;新建界面、页面切换、添加页面、addWidget、count、currentIndex 、currentWidget、indexOf、insertWidget、removeWidget、widget、setCurrentIndex 槽函数、setCurrentWidget 槽函数、currentChang…

RSS Can:将网站信息流转换为 RSS 订阅源(三)

第三篇内容里&#xff0c;我们来聊聊把结构化数据转换为可以订阅的 RSS 订阅数据源。 写在前面 通过前两篇文章《RSS Can&#xff1a;使用 Golang 实现更好的 RSS Hub 服务&#xff08;一&#xff09;》和《RSS Can&#xff1a;借助 V8 让 Golang 应用具备动态化能力&#xf…

【云计算与大数据技术】集群资源统一管理系统YARN、Mesos、Omega讲解(图文解释 超详细)

相比于一种计算框架一个集群的模式&#xff0c;共享集群的模式具有以下三个优点 1&#xff1a;硬件共享 资源利用率高 2&#xff1a;人员共享 运维成本低 3&#xff1a;数据共享 数据复制开销低 一、集群资源统一管理系统 集群资源统一管理系统需要支持多种计算框架,并需…

如何能让Linux系统能够更好的支持高并发环境?

Linux系统在默认的参数下对高并发支持不好&#xff0c;主要瓶颈在于单进程最大打开文件数限制、内核TCP参数方面和IO事件分配机制等。所以下面我们从这几方面进行调优&#xff0c;使Linux系统能够更好的支持高并发环境。 iptables相关 如果不是必须使用&#xff0c;建议关掉或…

对接云眸控件兼容性记录

之前采用的UIKit的形式进行视频播放&#xff0c;因为业务要求转换成了Web视频控件的形式。但是Web控件存在不少的兼容性问题 开发的直播系统(www.a.com)是通过Iframe嵌入到门户网站(www.b.com)中&#xff0c;并且部署的地址不同于门户地址: 由于系统页面和门户网站不同域&…

证明客户端发起HTTP请求后会进入TIME_WAIT状态并占用端口

证明客户端发起HTTP请求后会进入TIME_WAIT状态并占用端口 起因 线上出现服务器发起Http请求会报 connect: cannot assign requested address 错误的现象原因是HTTP请求四次挥手的发起方会进入TIME_WAIT状态并占用端口&#xff0c;大量的短链接导致端口耗尽 – 在这篇文章里很详…

代码的编译原理,以Linux系统为例

程序编译分为预编译、编译、汇编和链接四个阶段。在Windows操作系统中&#xff0c;编译工具用的是集成的开发环境&#xff0c;在Linux系统中没有很好的继承开发环境&#xff0c;用的是gcc编译器或者g&#xff0c;gcc用于C语言代码的编译&#xff0c;g用在C的编译过程中。在Linu…

使用mybatisplus 和vben实现低代码开发

前言 如今软件的开发&#xff0c;低代码开发可以3天就做一个CRM&#xff0c;感觉程序员都要失业了的节奏。我们这边用了mybatisplus&#xff0c;其官方也推荐了几个低代码平台&#xff0c;有兴趣的同学可以去看看。我们就直接用mp提供的FastAutoGenerator来进行代码生成。 接下…

凭借这份秘籍,华为老总“寒气”传播下,仍然拿下大厂offer大满贯

首先感谢下华为老总“把寒气传递每一个人”【手动狗头】 当前互联网大环境确实不太乐观&#xff0c;所以我相信不仅仅是华为的 20 万员工感受到了所谓的“寒气”&#xff0c;众多的网友和互联网it工作者&#xff0c;也感受到了“寒气”。最近有很多同学来找我说最近工作难找&a…

【C++】 封装/重载/友元

文章目录一、内存分区、引用、函数1 内存分区模型2 引用&#xff08;reference&#xff09;&#xff08;指针常量&#xff09;3 函数默认参数4 函数占位参数5 函数重载二、封装1 struct和class区别三、对象的构造和析构1 构造函数的分类及调用2 拷贝构造函数调用时机3 构造函数…

产品经理 - 产品设计方法论业务落地部分_包括流程产品文档方法论需求设计方法论

整体 - 产品设计方法论思维导图 个人整理&#xff0c;存在异议大家可以讨论下 业务落地方法论 在进行了需求收集以及需求分析后&#xff0c;针对收集到的需求以及对应的分析结论后&#xff0c;需针对当前的需求点进行开发落地&#xff0c;核心即为两点&#xff0c;需求设计…

大学生HTML期末作业网页:使用DIV+CSS技术制作一个简单的小说网站 (3个页面 登录+注册+首页 )

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

C# DotNet基本类库

统一的编程API&#xff1a;NET Framework 一 任何事物都是对象(类型转换) 1 任何事物都是object类的子类 ① 一个函数如果需要object参数&#xff0c;则可以代入任何参数&#xff1b; ② 任何对象都有以下方法&#xff1a; ToString() Equals() GetType() MemberwiseClone…