从零实现循环神经网络(一)

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

5.知识点个人理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值