pytorch模型训练实用教程学习笔记:二模型的构建(代码片段)

zstar-_ zstar-_     2022-11-30     218

关键词:

前言

最近在重温Pytorch基础,然而Pytorch官方文档的各种API是根据字母排列的,并不适合学习阅读。
于是在gayhub上找到了这样一份教程《Pytorch模型训练实用教程》,写得不错,特此根据它来再学习一下Pytorch。
仓库地址:https://github.com/TingsongYu/PyTorch_Tutorial

复杂模型构建解析

模型搭建比较容易,但是复杂模型通常是使用多个重复结构,下面以ResNet34为例:

from torch import nn
from torch.nn import functional as F


class ResidualBlock(nn.Module):
    '''
    实现子module: Residual Block
    '''

    def __init__(self, inchannel, outchannel, stride=1, shortcut=None):
        super(ResidualBlock, self).__init__()
        self.left = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),
            nn.BatchNorm2d(outchannel),
            nn.ReLU(inplace=True),
            nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),
            nn.BatchNorm2d(outchannel))
        self.right = shortcut

    def forward(self, x):
        out = self.left(x)
        residual = x if self.right is None else self.right(x)
        out += residual
        return F.relu(out)


class ResNet34(BasicModule):
    '''
    实现主module:ResNet34
    ResNet34包含多个layer,每个layer又包含多个Residual block
    用子module来实现Residual block,用_make_layer函数来实现layer
    '''

    def __init__(self, num_classes=2):
        super(ResNet34, self).__init__()
        self.model_name = 'resnet34'

        # 前几层: 图像转换
        self.pre = nn.Sequential(
            nn.Conv2d(3, 64, 7, 2, 3, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(3, 2, 1))

        # 重复的layer,分别有3,4,6,3个residual block
        self.layer1 = self._make_layer(64, 128, 3)
        self.layer2 = self._make_layer(128, 256, 4, stride=2)
        self.layer3 = self._make_layer(256, 512, 6, stride=2)
        self.layer4 = self._make_layer(512, 512, 3, stride=2)

        # 分类用的全连接
        self.fc = nn.Linear(512, num_classes)

    def _make_layer(self, inchannel, outchannel, block_num, stride=1):
        '''
        构建layer,包含多个residual block
        '''
        shortcut = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
            nn.BatchNorm2d(outchannel))

        layers = []
        layers.append(ResidualBlock(inchannel, outchannel, stride, shortcut))

        for i in range(1, block_num):
            layers.append(ResidualBlock(outchannel, outchannel))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.pre(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = F.avg_pool2d(x, 7)
        x = x.view(x.size(0), -1)
        return self.fc(x)

残差网络有很多重复的网络结构层,在这些重复的层中,又会有多个相同结构的残差块ResidualBlock。
上面这段代码用_make_layer来调用重复层,同时用ResidualBlock来封装重复结构的残差块。

权值初始化

在以往复现网络时,权重初始化其实一直没注意过,下面这段代码展现如何进行权值初始化。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    # 定义权值初始化
    def initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.xavier_normal_(m.weight.data)
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                torch.nn.init.normal_(m.weight.data, 0, 0.01)
                m.bias.data.zero_()


net = Net()     # 创建一个网络
net.initialize_weights()    # 初始化权值

这段代码对网路的卷积层,BN层和全连接层分别初始化了不同的权值和偏置。
默认不初始化权值的情况下,默认采用的随机权值满足均匀分布、

Pytorch中,各种初始化方法如下:

Xavier 均匀分布

torch.nn.init.xavier_uniform_(tensor, gain=1)

Xavier 正态分布

torch.nn.init.xavier_normal_(tensor, gain=1)

kaiming 均匀分布

torch.nn.init.kaiming_uniform_(tensor, a=0, mode=‘fan_in’, nonlinearity=‘leaky_relu’)

kaiming 正态分布

torch.nn.init.kaiming_normal_(tensor, a=0, mode=‘fan_in’, nonlinearity=‘leaky_relu’)

均匀分布初始化

torch.nn.init.uniform_(tensor, a=0, b=1)
使值服从均匀分布 U(a,b)

正态分布初始化

torch.nn.init.normal_(tensor, mean=0, std=1)
使值服从正态分布 N(mean, std),默认值为 0,1

常数初始化

torch.nn.init.constant_(tensor, val)
使值为常数 val nn.init.constant_(w, 0.3)

单位矩阵初始化

torch.nn.init.eye_(tensor)
将二维 tensor 初始化为单位矩阵(the identity matrix)

正交初始化

torch.nn.init.orthogonal_(tensor, gain=1)

稀疏初始化

torch.nn.init.sparse_(tensor, sparsity, std=0.01)

模型参数保存和加载

在我之前的博文深度学习基础:7.模型的保存与加载/学习率调度中提到过模型的保存和加载,摘过来放到这里。

模型保存:

torch.save(net.state_dict(), 'net_params.pt')

模型加载:

model.load_state_dict('net_params.pt')

在这个教程中,使用的是.pkl这个后缀

torch.save(net.state_dict(), 'net_params.pkl')

相关API均相同,唯一的区别在于文件后缀。
查阅相关资料,pt,pth,pkl均可作为模型参数后缀,不必细究。

我是土堆-pytorch教程知识点学习总结笔记(代码片段)

此文章为【我是土堆- Pytorch教程】知识点学习总结笔记(五)包括:完整的模型训练套路(一)、完整的模型训练套路(二)、完整的模型训练套路(三)、利用GPU训练(一)、利用GPU... 查看详情

pytorch模型训练实用教程学习笔记:三损失函数汇总(代码片段)

前言最近在重温Pytorch基础,然而Pytorch官方文档的各种API是根据字母排列的,并不适合学习阅读。于是在gayhub上找到了这样一份教程《Pytorch模型训练实用教程》,写得不错,特此根据它来再学习一下Pytorch。仓库地... 查看详情

pytorch学习笔记5.torchvision库(代码片段)

PyTorch学习笔记5.torchvision加载数据集一、简介二、安装三、torchvision的主要功能示例1.加载model(1)加载几个预训练模型(2)只加载模型,不加载预训练参数(4)加载部分预训练模型(5)调整模型(6)加载非预训练模型的方法3.1.6.1保存和... 查看详情

pytorch学习笔记5.torchvision库(代码片段)

PyTorch学习笔记5.torchvision加载数据集一、简介二、安装三、torchvision的主要功能示例1.加载model(1)加载几个预训练模型(2)只加载模型,不加载预训练参数(4)加载部分预训练模型(5)调整模型(6)加载非预训练模型的方法3.1.6.1保存和... 查看详情

pytorch学习笔记2.运行官网训练推理的入门示例(代码片段)

PyTorch学习笔记2.运行官网训练、推理的入门示例一、加载数据二、创建模型torch.nn.Sequential介绍:torch.nn.Linear3.torch.nn.ReLU三、调整模型参数四、保存模型五、加载模型一、加载数据首先引用必要的库:importtorchfromtorchimportnn... 查看详情

pytorch学习笔记:模型定义修改保存(代码片段)

往期学习资料推荐:1.Pytorch实战笔记_GoAI的博客-CSDN博客2.Pytorch入门教程_GoAI的博客-CSDN博客本系列目录:PyTorch学习笔记(一):PyTorch环境安装PyTorch学习笔记(二):简介与基础知识PyTorch学习笔记&#... 查看详情

pytorch学习笔记8.实现线性回归模型

PyTorch学习笔记8.实现线性回归模型一、回归的概念1.概念2.目标3.应用4.训练线性回归的步骤二、数据集1.构造数据集2.把数据集转为pytorch使用的张量三、模型1.模型定义2.损失函数3.优化器四、使用模型1.训练2.测试3.预测4.可视化五... 查看详情

小白学习pytorch教程九基于pytorch训练第一个rnn模型(代码片段)

@Author:Runsen当阅读一篇课文时,我们可以根据前面的单词来理解每个单词的,而不是从零开始理解每个单词。这可以称为记忆。卷积神经网络模型(CNN)不能实现这种记忆,因此引入了递归神经网络模型(RNN)来解决这一问题... 查看详情

学习笔记《pytorch入门》完整的模型训练套路(cifar10model)(代码片段)

文章目录准备数据集(训练和测试)搭建神经网络创建损失函数,分类问题使用交叉熵创建优化器设置训练网络的一些参数进入训练循环准备进入测试步骤完整代码:准备数据集(训练和测试)训练数据集... 查看详情

pytorch学习笔记8.实现线性回归模型(代码片段)

PyTorch学习笔记8.实现线性回归模型一、回归的概念1.概念2.目标3.应用4.训练线性回归的步骤二、数据集1.构造数据集2.把数据集转为pytorch使用的张量三、模型1.模型定义2.损失函数3.优化器四、使用模型1.训练2.测试3.预测4.可视化五... 查看详情

小白学习pytorch教程十基于大型电影评论数据集训练第一个lstm模型(代码片段)

@Author:Runsen文章目录编码建立字典并对评论进行编码对标签进行编码删除异常值填充序列数据加载器RNN模型的实现训练本博客对原始IMDB数据集进行预处理,建立一个简单的深层神经网络模型,对给定数据进行情感分析... 查看详情

《南溪的目标检测学习笔记》——训练pytorch模型遇到显存不足的情况怎么办

1前言在目标检测中,可能会遇到显存不足的情况,我们在这里记录一下解决方案;2如何判断真正是出现显存(不是“软件误报”)当前需要分配的显存在200MiB以下,例如:RuntimeError:CUDAoutofmemory.Triedtoal... 查看详情

pytorch学习笔记7.textcnn文本分类(代码片段)

PyTorch学习笔记7.TextCNN文本分类一、模型结构二、文本分词与编码1.分词与编码器2.数据加载器二、模型定义1.卷积层2.池化层3.全连接层三、训练过程四、测试过程五、预测过程一、模型结构2014年,YoonKim针对CNN的输入层做了一... 查看详情

pytorch学习笔记7.textcnn文本分类(代码片段)

PyTorch学习笔记7.TextCNN文本分类一、模型结构二、文本分词与编码1.分词与编码器2.数据加载器二、模型定义1.卷积层2.池化层3.全连接层三、训练过程四、测试过程五、预测过程一、模型结构2014年,YoonKim针对CNN的输入层做了一... 查看详情

在 PyTorch 中加载迁移学习模型进行推理的正确方法是啥?

】在PyTorch中加载迁移学习模型进行推理的正确方法是啥?【英文标题】:WhatistheproperwaytoloadatransferlearningmodelforinferenceinPyTorch?在PyTorch中加载迁移学习模型进行推理的正确方法是什么?【发布时间】:2019-10-1122:23:17【问题描述】... 查看详情

pytorch学习笔记:pytorch进阶训练技巧(代码片段)

PyTorch实战:PyTorch进阶训练技巧往期学习资料推荐:1.Pytorch实战笔记_GoAI的博客-CSDN博客2.Pytorch入门教程_GoAI的博客-CSDN博客本系列目录:PyTorch学习笔记(一):PyTorch环境安装PyTorch学习笔记(二)... 查看详情

pytorch学习笔记第五篇——训练分类器(代码片段)

文章目录1.数据2.训练图像分类器2.1加载并标准化CIFAR102.2训练图像3.定义卷积神经网络、损失函数、优化器、训练网络和保存模型4.测试自己的模型5.在GPU上进行训练1.数据通常,当您必须处理图像,文本,音频或视频... 查看详情

小白学习pytorch教程十一基于mnist数据集训练第一个生成性对抗网络(代码片段)

@Author:RunsenGAN是使用两个神经网络模型训练的生成模型。一种模型称为生成网络模型,它学习生成新的似是而非的样本。另一个模型被称为判别网络,它学习区分生成的例子和真实的例子。生成性对抗网络2014࿰... 查看详情