首页 > 其他分享 >深度学习-pytorch模型构建

深度学习-pytorch模型构建

时间:2023-04-04 19:35:04浏览次数:33  
标签:__ nn self init channels pytorch 构建 深度 input


title: Python特殊语法--列表推导式 切片 迭代器 生成器 装饰器 lambda表达式 

构建自己的模型

让我们直接切入主题,使用 PyTorch,自己构建并训练一个线性回归模型,来拟合出训练集中的走势分布。我们先随机生成训练集 X 与对应的标签 Y,具体代码如下:

import numpy as np
import random
from matplotlib import pyplot as plt

w = 2
b = 3
xlim = [-10, 10]
x_train = np.random.randint(low=xlim[0], high=xlim[1], size=30)

y_train = [w * x + b + random.randint(0,2) for x in x_train]

plt.plot(x_train, y_train, 'bo')

熟悉回归的同学应该知道,我们的回归模型为:y=wx+b。这里的 x 与 y,其实就对应上述代码中的 x_train 与 y_train,而 w 与 b 正是我们要学习的参数。好,那么我们看看如何构建这个模型。我们还是先看代码,再具体讲解

import torch
from torch import nn

class LinearModel(nn.Module):
  def __init__(self):
    super().__init__()
    self.weight = nn.Parameter(torch.randn(1))
    self.bias = nn.Parameter(torch.randn(1))

  def forward(self, input):
    return (input * self.weight) + self.bias
  • 1.必须继承 nn.Module 类。

  • 2.重写 init() 方法。通常来说要把有需要学习的参数的层放到构造函数中,例如,例子中的 weight 与 bias,还有我们之前学习的卷积层。我们在上述的__init__()中使用了 nn.Parameter(),它主要的作用就是作为 nn.Module 中可训练的参数使用。必须调用父类的构造方法才可以,也就是这行代码:super().__init__()

    因为在 nn.Module 的 __init__() 中,会初始化一些有序的字典与集合。这些集合用来存储一些模型训练过程的中间变量,如果不初始化 nn.Module 中的这些参数的话,

  • 3.forward() 是必须重写的方法。看函数名也可以知道,它是用来定义这个模型是如何计算输出的,也就是前向传播。对应到我们的例子,就是获得最终输出 y=weight * x+bias 的计算结果。对于一些不需要学习参数的层,一般来说可以放在这里。例如,BN 层,激活函数还有 Dropout。

  • 4.Sequential() 按顺序执行里头的模块

  • 5 Embedding 随机初始化嵌入的s向量 embedding = nn.Embedding(5, 3) # 定义一个具有5个单词,维度为3的查询矩阵

  • 6 torch.nn.Lineartorch.nn.Linear类用于定义模型的线性层,即完成前面提到的不同的层之间的线性变换。 线性层接受的参数有3个:分别是输入特征数、输出特征数、是否使用偏置,默认为True,使用torch.nn.Linear类,会自动生成对应维度的权重参数和偏置,对于生成 的权重参数和偏置,我们的模型默认使用一种比之前的简单随机方式更好的参数初始化方式。

    embedding = nn.Embedding(5, 3)  # 定义一个具有5个单词,维度为3的查询矩阵
    print(embedding.weight)  # 展示该矩阵的具体内容
    test = torch.LongTensor([[0, 2, 0, 1],
                             [1, 3, 4, 4]])  # 该test矩阵用于被embed,其size为[2, 4]
    # 其中的第一行为[0, 2, 0, 1],表示获取查询矩阵中ID为0, 2, 0, 1的查询向量
    # 可以在之后的test输出中与embed的输出进行比较
    test = embedding(test)
    print(test.size())  # 输出embed后test的size,为[2, 4, 3],增加
    # 的3,是因为查询向量的维度为3
    print(test)  # 输出embed后的test的内容
    
    
    ——————————————————————————————————————
    输出:
    Parameter containing:
    tensor([[-1.8056,  0.1836, -1.4376],
            [ 0.8409,  0.1034, -1.3735],
            [-1.3317,  0.8350, -1.7235],
            [ 1.5251, -0.2363, -0.6729],
            [ 0.4148, -0.0923,  0.2459]], requires_grad=True)
    torch.Size([2, 4, 3])
    tensor([[[-1.8056,  0.1836, -1.4376],
             [-1.3317,  0.8350, -1.7235],
             [-1.8056,  0.1836, -1.4376],
             [ 0.8409,  0.1034, -1.3735]],
    
            [[ 0.8409,  0.1034, -1.3735],
             [ 1.5251, -0.2363, -0.6729],
             [ 0.4148, -0.0923,  0.2459],
             [ 0.4148, -0.0923,  0.2459]]], grad_fn=<EmbeddingBackward>)
    

    可以看出创建了一个具有5个ID(可以理解为拥有5个词的词典)的查询矩阵,每个查询向量的维度是3维,然后用一个自己需要Embedding的矩阵与之计算,其中的内容就是需要匹配的ID号,注意!如果需要Embedding的矩阵中的查询向量不为1,2这种整数,而是1.1这种浮点数,就不能与查询向量成功匹配,会报错,且如果矩阵中的值大于了查询矩阵的范围,比如这里是5,也会报错。

  • nn.Parameter

  • nn.Module 模块nn.Module 是所有神经网络模块的基类。当我们自己要设计一个网络结构的时候,就要继承该类。也就说,其实Torchvison中的那些模型,也都是通过继承 nn.Module 模块来构建网络模型的。需要注意的是,模块本身是 callable 的,当调用它的时候,就是执行 forward 函数,也就是前向传播。

    我们还是结合代码例子直观感受一下。请看下面的代码,先创建一个 LinearModel 的实例 model,然后 model(x) 就相当于调用 LinearModel 中的 forward 方法。

模型的训练

我们的模型定义好之后,还没有被训练。要想训练我们的模型,就需要用到损失函数与优化方法,这一部分前面课里(如果你感觉陌生的话,可以回顾 11~13 节课)已经学过了,所以现在我们直接看代码就可以了。

这里选择的是 MSE 损失与 SGD 优化方法。

# 定义优化器
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9)

y_train = torch.tensor(y_train, dtype=torch.float32)
for _ in range(1000):
    input = torch.from_numpy(x_train)
    output = model(input)
    loss = nn.MSELoss()(output, y_train)
    model.zero_grad()
    loss.backward()
    optimizer.step()

经过 1000 个 Epoch 的训练以后,我们可以打印出模型的 weight 与 bias,看看是多少。对于一个模型的可训练的参数,我们可以通过 named_parameters() 来查看,请看下面代码。

  print(parameter)
# 输出:
('weight', Parameter containing:
tensor([2.0071], requires_grad=True))
('bias', Parameter containing:
tensor([3.1690], requires_grad=True))

复杂的定义方法

class CustomModel(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1_1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, padding='same')
    self.conv1_2 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=2, padding='same')
    ...
    self.conv_m_1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, padding='same')
    self.conv_m_2 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=2, padding='same')
    ...
    self.conv_n_1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, padding='same')
    self.conv_n_2 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=2, padding='same')

  def forward(self, input):
    x = self.conv1_1(input)
    x = self.conv1_2(x)
    ...
    x = self.conv_m_1(x)
    x = self.conv_m_2(x)
    ...    
    x = self.conv_n_1(x)
    x = self.conv_n_2(x)
    ...
    return x

其实这部分重复的结构完全可以放在一个单独的 module 中,然后,在我们模型中直接调用这部分即可,具体实现你可以参考下面的代码:

class CustomLayer(nn.Module):
  def __init__(self, input_channels, output_channels):
    super().__init__()
    self.conv1_1 = nn.Conv2d(in_channels=input_channels, out_channels=3, kernel_size=3, padding='same')
    self.conv1_2 = nn.Conv2d(in_channels=3, out_channels=output_channels, kernel_size=2, padding='same')
    
  def forward(self, input):
    x = self.conv1_1(input)
    x = self.conv1_2(x)
    return x
    

然后呢,CustomModel 就变成下面这样了:

  def __init__(self):
    super().__init__()
    self.layer1 = CustomLayer(1,1)
    ...
    self.layerm = CustomLayer(1,1)
    ...
    self.layern = CustomLayer(1,1)
  
  def forward(self, input):
    x = self.layer1(input)
    ...
    x = self.layerm(x)
    ...    
    x = self.layern(x)
    ...
    return x

Epoch

标签:__,nn,self,init,channels,pytorch,构建,深度,input
From: https://www.cnblogs.com/ZZXJJ/p/17287678.html

相关文章

  • 111. 二叉树的最小深度
    给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明:叶子节点是指没有子节点的节点。classSolution{public:intminDepth(TreeNode*root){if(root==nullptr)return0;if(!root->left&&!root->right......
  • 深度学习基础-pytorch1
    DataSetDataLoaderTorchvision数据读取训练开始的第一步,首先就是数据读取。PyTorch为我们提供了一种十分方便的数据读取机制,即使用Dataset类与DataLoader类的组合,来得到数据迭代器。在训练或预测时,数据迭代器能够输出每一批次所需的数据,并且对数据进行相应的预处理与......
  • 基于虚拟化的混合云集群——kafka集群环境构建工作
    摘要本章将详细的介绍kafka集群环境的构建和kafka的相关问题介绍。下载kafka的安装包官网下载地址:ApacheKafka这个下载很重要,可能会遇到:1)错误:找不到或无法加载主类kafka.Kafka配置kafka的环境在kafa的解压包中建立kafka的日志的文件夹log的位置:/home/xjl/software/kafka2.0.0/......
  • pytorch中bin模型文件转onnx遇到的问题
    pytorch中bin模型文件转onnx遇到的问题1常规做法importosimportnumpyasnpfromtransformersimportGPT2LMHeadModelimporttorchlocalfile=r"C:\Users\min_ppl_model"model=GPT2LMHeadModel.from_pretrained(localfile)#输入shape为1,50其中1为bs50为固......
  • 104.二叉树的最大深度
    给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。示例:给定二叉树[3,9,20,null,null,15,7],classSolution{public:intgetdepth(TreeNode*node){if(node==NULL)return0;......
  • 行稳致远,开往春天,浪潮云海为昆明地铁构建“云上智慧指挥官”
    引言:交通运输部《数字交通“十四五”发展规划》指出,要以数字化、网络化、智能化为主线,以改革创新为根本动力,以先进信息技术赋能交通运输发展,强化交通数字治理,统筹布局交通新基建,推动运输服务智能化。地铁里的“云上智慧指挥官”——综合管理系统IntegratedSupervisoryControlSy......
  • 基于mnist手写数字数据库的深度学习网络训练和数字识别matlab仿真
    1.算法描述        MNIST数据集(MixedNationalInstituteofStandardsandTechnologydatabase)是美国国家标准与技术研究院收集整理的大型手写数字数据库,该数据集包含60000 个于训练的样本和10000 个于测试的样本,图像是固定⼤小(28x28像素),每个像素的值为......
  • 前端性能精进(七)——构建
    前端性能精进(七)——构建前端构建是指通过工具自动化地处理那些繁琐、重复而有意义的任务。这些任务包括语言编译、文件压缩、模块打包、图像优化、单元测试等一切需要对源码进行处理的工作。在将这类任务交给工具后,开发人员被解放了生产力,得以集中精力去编写代码......
  • maven项目构建命令
    使用cmd进入到项目目录,进行构建。  ......
  • 简述构建微服务架构的四大挑战
    微服务的开发模式和单体服务差异比较大,对设计、开发、测试、运维等研发流程的各个阶段都提出了新的挑战。1、拆分挑战服务拆分是微服务架构过程中最重要的一步,关系到微服务架构的成败,糟糕的服务拆分会影响后续的服务化过程,严重时可能会导致大量的返工,甚至是推倒重来;好的服务化拆分,......