1.导包
#%matplotlib inline是jupyter notebook里的命令, 意思是将那些用matplotlib绘制的图显示在页面里而不是弹出一个窗口
%matplotlib inline
import math
import torch
from torch import nn
from torch.nn import functional as F
import dltools
2.加载time machine数据
#声明变量
batch_size= 32 #每批次取的数据数量
num_steps = 35 #子序列的长度(包含的字节长度)
## 默认需要从亚马逊aws云上面下载数据, 但是资源过期了, 导致数据下载加载不了.
#加载数据之前,需要将dltools.py源码文件中加载数据的方式改为本地加载
train_iter, vocab = dltools.load_data_time_machine(batch_size=batch_size, num_steps=num_steps)
#注意:修改源码时,只需要注释掉源码,添加新的代码即可,不要删掉要修改的源码!!!
#测试:遍历输出一条数据是否可行
for x, y in train_iter:
print(x, y)
break #表示输出一条数据就停止循环
tensor([[ 1, 17, 2, ..., 1, 5, 3], [ 3, 1, 16, ..., 2, 8, 1], [10, 1, 4, ..., 8, 1, 2], ..., [ 8, 1, 4, ..., 3, 1, 21], [ 4, 6, 8, ..., 6, 11, 1], [20, 12, 4, ..., 1, 14, 20]]) tensor([[17, 2, 12, ..., 5, 3, 1], [ 1, 16, 12, ..., 8, 1, 7], [ 1, 4, 8, ..., 1, 2, 4], ..., [ 1, 4, 21, ..., 1, 21, 14], [ 6, 8, 20, ..., 11, 1, 6], [12, 4, 15, ..., 14, 20, 1]])
3.pytorch中的one_hot编码模块的使用
#需要对加载的数据进行one_hot编码
#pytorch提供了快速进行one_hot编码的工具
#[0, 2]的shape=(1,2),one_hot输出结果就是(2,num_classes)
F.one_hot(torch.tensor([0, 2]), #表示词汇表索引为0的为1,;索引为2的为1
num_classes=len(vocab)) #类别数量
tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
F.one_hot(torch.tensor([0, 2]),num_classes=len(vocab)).shape
torch.Size([2, 28])
torch.arange(10)
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
X = torch.arange(10).reshape((2, 5))
X
tensor([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
X.shape
torch.Size([2, 5])
x = F.one_hot(X.T, 28)
x
tensor([[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], [[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], [[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]])
4.初始化模型
def get_params(vocab_size, num_hiddens, device):
"""
vocab_size:词汇表分类数量
num_hiddens:隐藏层数量
device:设置判断是否使用gpu的判断标志
"""
#初始化模型参数
num_inputs = num_outputs = vocab_size
#根据w的权重shape来创建一个标准正态分布的矩阵
def normal(shape):
#乘以0.01,使输出的数值变小,防止计算结果太大导致更新梯度爆炸
return torch.randn(size=shape, device=device)*0.01
#初始化隐藏层参数
W_xh = normal((num_inputs, num_hiddens))
W_hh = normal((num_hiddens, num_hiddens))
b_h = torch.zeros(num_hiddens, device=device)
#b_h 代表隐藏层的偏置,而 num_hiddens 指定了隐藏层的单元数量。
#torch.zeros() 函数用于创建一个指定形状的全零张量,这里创建的是一个形状为 [num_hiddens] 的全零张量,
#用于初始化隐藏层的偏置向量。这个偏置向量在神经网络训练过程中会被学习并更新,以优化模型的性能。
#此外,通过指定 device=device,确保了该张量被创建在正确的设备上(CPU或GPU),这取决于是否有可用的GPU资源。
#输出层
W_hq = normal((num_hiddens, num_outputs))
b_q = torch.zeros(num_outputs, device=device)
#以上参数都不能直接进行求导
#可以求导的方法:
#(1)nn.Parameter(W_xh)
#(2)将这些参数都设置requires_grad = True
params = [W_xh, W_hh, b_h, W_hq, b_q]
for param in params:
param.requires_grad_(True)
return params
#测试上面封装的代码:
get_params(28, 512, 'cuda:0')
[tensor([[-0.0063, -0.0225, 0.0025, ..., -0.0023, -0.0023, -0.0012], [-0.0062, 0.0012, 0.0059, ..., 0.0105, -0.0140, -0.0077], [-0.0160, 0.0007, 0.0052, ..., 0.0116, 0.0034, -0.0167], ..., [ 0.0063, 0.0063, -0.0015, ..., 0.0025, 0.0044, -0.0088], [ 0.0070, -0.0005, 0.0008, ..., -0.0080, 0.0020, 0.0033], [-0.0036, -0.0057, 0.0147, ..., 0.0003, -0.0048, -0.0108]], device='cuda:0', requires_grad=True), tensor([[-0.0138, -0.0069, 0.0037, ..., 0.0065, -0.0005, -0.0134], [ 0.0020, -0.0069, -0.0073, ..., 0.0098, 0.0081, 0.0184], [-0.0028, -0.0162, -0.0226, ..., -0.0146, 0.0024, -0.0228], ..., [ 0.0084, -0.0015, -0.0007, ..., -0.0091, 0.0095, -0.0138], [-0.0095, 0.0035, -0.0040, ..., 0.0075, 0.0085, -0.0005], [ 0.0022, -0.0038, 0.0003, ..., 0.0064, 0.0167, 0.0058]], device='cuda:0', requires_grad=True), tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], device='cuda:0', requires_grad=True), tensor([[-0.0027, 0.0008, 0.0039, ..., -0.0019, 0.0349, 0.0077], [ 0.0041, 0.0016, 0.0117, ..., -0.0060, 0.0040, -0.0189], [ 0.0200, 0.0059, -0.0046, ..., -0.0082, -0.0145, -0.0077], ..., [ 0.0131, -0.0004, -0.0085, ..., 0.0018, 0.0047, -0.0006], [-0.0130, -0.0060, 0.0023, ..., 0.0020, 0.0038, 0.0103], [ 0.0037, -0.0055, 0.0165, ..., -0.0099, -0.0047, -0.0054]], device='cuda:0', requires_grad=True), tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], device='cuda:0', requires_grad=True)]