pytorch 关于nn模块必须了解的知识

nn模块使用之前必须了解的知识

varaible

  1. 在module中流动的数据类型全部都是Varaible。
  2. Varaible的常见属性和变量有:data(包含保存的tensor)、grad(包含当前Varaible对应相应的Function的梯度)、requires_grad(bool值)、volatile(bool值,代表当前Varaible是否为推断模式)、creator(创建这个varaible的Fuction)

parameters

  1. Parameters是Variable的子类。
  2. Parameters 与 modules 一起使用时会有一些特殊的属性,其会被自动加到 Module 的parameters() 迭代器中,Variable 赋值给 modules 不会产生这样的效果。
  3. 用法很简单:torch.nn.Parameter(data, requires_grad)

module

  1. nn.Module是nn中十分重要的类,相当于一个容器,包含网络各层的定义及forward方法。
  2. 定义自已的网络,需要继承nn.Module类,并实现forward方法。
  3. 定义自已的网络,一般把网络中具有可学习参数的层放在构造函数__init__()中,不具有可学习参数的层(如ReLU)可放在构造函数中,也可不放在构造函数中(而在forward中使用nn.functional来代替)。
  4. 只要在nn.Module的子类中定义了forward函数,调用backward函数时,就会自动计算forward函数里面的varaible的梯度。
  5. 在forward函数中可以使用任何Variable支持的函数,毕竟在整个pytorch构建的图中,是Variable在流动。
  6. Modules也可以包括其他Modules,运行使用树结构来嵌入,可以将子模块作为根模型的属性,这样子模型的parameters就会自动加入根模型的parameters,方便整个网络的参数的更新。从下列看出,self.conv1 , self.conv2 是模型的子模型:
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module): def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)# submodule: Conv2d
        self.conv2 = nn.Conv2d(20, 20, 5)

    def forward(self, x):
       x = F.relu(self.conv1(x))
       return F.relu(self.conv2(x))

关于module的其他详细信息可以参考如下网站:

https://pytorch.org/docs/stable/nn.html#module
https://zhuanlan.zhihu.com/p/34616199
https://blog.csdn.net/u012609509/article/details/81203436

forward

  1. 该方法是用户自定义module里面可以选择重写的方法。
  2. 重写的内容往往是对于输入的参数进行一些运算,然后返回运算的结果。
  3. 如果该运算的结果是标量,那么可以调用backward函数来计算该运算里面所有varaible的梯度,以便后续optim的参数更新。
  4. 常见用法如下:
class NegativeSamplingLoss(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input_vectors, output_vectors, noise_vectors):
        # print("----------------input_vectors.shape-------------------")
        # print(input_vectors.shape)
        BATCH_SIZE, embed_size = input_vectors.shape
        # 将输入词向量与目标词向量作维度转化处理
        input_vectors = input_vectors.view(BATCH_SIZE, embed_size, 1)
        output_vectors = output_vectors.view(BATCH_SIZE, 1, embed_size)
        # 目标词损失
        out_loss = torch.bmm(output_vectors, input_vectors).sigmoid().log()  # (B,1,1)
        out_loss = out_loss.squeeze()  # 降维为 B
        # 负样本损失 noise_vectors.size = (BATCH_SIZE, N_SAMPLES, embed_size)
        noise_loss = torch.bmm(noise_vectors.neg(), input_vectors).sigmoid().log()  # (B,N_SAMPLES,1)
        # print("----------------noise_loss-------------------")
        # print(noise_loss)
        if BATCH_SIZE != 1:  # 因为当中心词到达左右两侧时,当windows_size为2时,会出现(B,N_SAMPLES,1)重的B = 1的情况,那么下面的语句会报错
            noise_loss = noise_loss.squeeze().sum(1)  # 多个负样本,所以要加和
        # 综合计算两类损失
        return -(out_loss + noise_loss).mean()

#初始化
criterion = NegativeSamplingLoss()

# 计算损失
loss = criterion(input_vectors, output_vectors, noise_vectors)
loss.backward()  # 回传
optimizer.step()  # 更新参数

backward

  1. 该函数往往对应forward函数的运算结果。
  2. 通过forward函数运算结果得到的标量来调用backward,可以更新该运算的相关叶子结点varaible。
    关于module的其他详细信息可以参考如下网站:

https://blog.csdn.net/douhaoexia/article/details/78821428

optim

  1. nn内含有许多optimizer,例如SGD、Adam,每个optimizer都有自己相应的应用常见,具体可以google。
  2. optimizer传入的参数主要有parameters、learningRate、momentum。
  3. optimizer更新的原理是,根据传入parameters的grad,结合learningRate和momentum来往梯度下降的方向更新所有的parameters。
  4. 简单使用如下:
for input, target in dataset:
    optimizer.zero_grad()
    output = model(input)
    loss = loss_fn(output, target)
    loss.backward()
    optimizer.step()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值