Neural Network学习笔记3

目录

损失函数和反向传播网络

优化器

现有网络模型的使用及修改

网络模型的保存与读取


损失函数和反向传播网络

在进行损失函数计算后,再进行.backward()反向传播。

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("dataset_transform",train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=1)


class Zrf(nn.Module):
    def __init__(self):
        super(Zrf, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

# 分类问题适合用交叉熵
loss = nn.CrossEntropyLoss()
zrf = Zrf()
for data in dataloader:
    imgs, targets = data
    outputs = zrf(imgs)
    # print(outputs)
    # print(targets)
    result_loss = loss(outputs, targets)
    result_loss.backward()

优化器

  以Adadelta为例,torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)

params: 模型的参数,让优化器知道我们的模型长什么样子。

lr: Learning rate, 学习率

其他的参数可以采用默认,并且优化算法不同,参数也会有很大不同。

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("dataset_transform",train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=1)


class Zrf(nn.Module):
    def __init__(self):
        super(Zrf, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

# 分类问题适合用交叉熵
loss = nn.CrossEntropyLoss()
zrf = Zrf()
# 设置优化器
# SGD 随机梯度下降
# lr的设不可以太大也不可以太小,一般情况下我们采用训练开始时lr大,之后的训练中lr小的方式
optim = torch.optim.SGD(zrf.parameters(), lr=0.01)
for epoch in range(20) :
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        outputs = zrf(imgs)
        result_loss = loss(outputs, targets)
        # 在进行反向传播来计算梯度时,要先将梯度置为0,防止之前计算出来的梯度的影响
        optim.zero_grad()
        result_loss.backward()
        # 根据梯度对卷积核参数进行调优
        optim.step()
        running_loss = running_loss + result_loss
    print(running_loss)

现有网络模型的使用及修改

torchvision.modles中的VGG为例。VGG常用VGG16和VGG19。

weights: 可选,要使用的预训练权重。默认情况下,不使用预先训练的权重。

progress: true时,会展示一个进度条

此外,pytorch在下载模型时会把模型下载到C盘,下面语句可以修改下载位置:

os.environ['TORCH_HOME'] = '/path/to/torch_home'

import torchvision
from torch import nn
from torchvision.models import VGG16_Weights
import os


# train_data = torchvision.datasets.ImageNet(root="data_image_net", split="train", download=True,
#                                            transform=torchvision.transforms.ToTensor())

# 最新版本默认是没有预训练的,需要使用预训练设置weights='DEFAULT'

os.environ['TORCH_HOME'] = '/path/to/torch_home'

vgg16_noPre = torchvision.models.vgg16()
vgg16_pre = torchvision.models.vgg16(weights=VGG16_Weights.DEFAULT)
print(vgg16_pre)

# 微调网络模型
train_data = torchvision.datasets.CIFAR10("dataset_transform",train=False, transform=torchvision.transforms.ToTensor(), download=True)
# 添加一层
# 在vgg整体层面上加
vgg16_pre.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_pre)
# 只在某一部分加(classifier部分)
vgg16_pre.classifier.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_pre)

# 修改
vgg16_noPre.classifier[6] = nn.Linear(4096, 10)
print(vgg16_noPre)

网络模型的保存与读取

保存方法演示:model_save.py

import torch
import torchvision
from torch import nn

# 使用未经过训练的,初始化的参数
vgg16 = torchvision.models.vgg16()
# 保存方式1
# 这样不仅保存了网络模型的结构,也保存了网络模型的参数
torch.save(vgg16, "vgg16_method1.pth")

# 保存方式2
# 不保存网络的结构,只是把网络的参数保存成数据字典,也就是保存了网络的状态
# (官方推荐!!!)占用空间更小
torch.save(vgg16.state_dict(), "vgg16_method2.pth")

# 陷阱1
class Zrf(nn.Module):
    def __init__(self):
        super(Zrf, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

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

zrf = Zrf()
torch.save(zrf, "zrf_method1.pth")

读取方法演示:model_load.py

import torch
import torchvision
from torch import nn

# 方式1 ----> 对应保存方式1,来加载模型
model = torch.load("vgg16_method1.pth")
# print(model)

# 方式2 ---> 对应保存方式2
vgg16 = torchvision.models.vgg16() # 新建网络模型结构
model = torch.load("vgg16_method2.pth")
# print(model)
vgg16.load_state_dict(model) # 加载网络模型的状态
print(vgg16)

# 陷阱1
# 在使用自己创建的网络时,注意要有网络的这个类在本文件(程序可以访问到网络),只是不需要zrf = Zrf()再创建网络了
# 方法1
# class Zrf(nn.Module):
#     def __init__(self):
#         super(Zrf, self).__init__()
#         self.conv1 = nn.Conv2d(3, 64, kernel_size=3)
#
#     def forward(self, x):
#         x = self.conv1(x)
#         return x
# 方法2
from model_save import *

model = torch.load("zrf_method1.pth")
print(model)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值