pytorch基础学习4

视频(我是土堆)+笔记【我是土堆 - PyTorch教程】学习随手记
1.损失函数与反向传播
Loss Functions
作用:

  1. 计算实际输出和目标之间的差距;
  2. 为我们更新输出提供一定的依据(反向传播);给每一个卷积核中的参数提供了梯度 grad,采用反向传播时,每一个要更新的参数都会计算出对应的梯度,优化过程中根据梯度对参数进行优化,最终达到整个 loss 进行降低的目的
import torch
from torch.nn import L1Loss
from torch import nn

inputs=torch.tensor([1,2,3],dtype=torch.float32)
targets=torch.tensor([1,2,5],dtype=torch.float32)
inputs=torch.reshape(inputs,[1,1,1,3])
targets=torch.reshape(targets,[1,1,1,3])

#L1Loss
loss=L1Loss(reduction='sum')
# reduction属性:sum 表示差值绝对值相加;若是默认值,即mean,则为差值绝对值的均值
result=loss(inputs,targets)
print(result)

#MSELoss 均方误差
loss_mse=nn.MSELoss()
result_mse=loss_mse(inputs,targets)
print(result_mse)

#CROSSENTROPYLOSS 交叉熵
x=torch.tensor([0.1,0.2,0.3]) #属于某一类的概率,0.1属于0类的概率
y=torch.tensor([1]) #图片真实的label的下标
x=torch.reshape(x,(1,3))
loss_cross=nn.CrossEntropyLoss()
result_cross=loss_cross(x,y)
print(result_cross)
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

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

class Tudui(nn.Module): #搭建模型
    def __init__(self):
        super(Tudui,self).__init__()
        self.module1=Sequential(  #把上述的步骤进行简单化
            Conv2d(3, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),  # 展平,
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self,input):
        output=self.module1(input)
        return output


#如何在模型中运行loss function(实际输出和目标之间的差距)
loss=nn.CrossEntropyLoss() #使用交叉熵函数
tudui=Tudui()
for data in dataloader:
    imgs,targets=data
    output=tudui(imgs)
    result_loss=loss(output,targets)
    print(result_loss) #tensor(2.3803, grad_fn=<NllLossBackward0>)
    result_loss.backward() #反向传播是在loss中的,有一个参数grad(记录梯度),优化器会根据它的值对参数进行更新,以降低loss
    #通过不断更新梯度来减少梯度就可以使loss最小
    print("ok")

2.优化器
当使用损失函数时,可以调用损失函数的 backward,得到反向传播,反向传播可以求出每个需要调节的参数对应的梯度,有了梯度就可以利用优化器,优化器根据梯度对参数进行调整,以达到整体误差降低的目的
(lr:learning rate 学习率)
TORCH.OPTIM

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

#加载数据集并转为tensor数据类型
datasets=torchvision.datasets.CIFAR10("./datasets",train=False,transform=torchvision.transforms.ToTensor(),
                                      download=True)
#dataloader 进行加载
dataloader=DataLoader(datasets,batch_size=1)

class Tudui(nn.Module): #搭建网络
    def __init__(self):
        super(Tudui,self).__init__()
        self.module1=Sequential(  #把上述的步骤进行简单化
            Conv2d(3, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),  # 展平,
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self,input):
        output=self.module1(input)
        return output

loss=nn.CrossEntropyLoss() #使用交叉熵函数,计算loss
tudui=Tudui() #实例化,搭建网络
# SGD 随机梯度下降
optim=torch.optim.SGD(tudui.parameters(),lr=0.01)  #定义优化器
for epoch in range(20): #多次训练数据
    running_loss=0.0
    for data in dataloader: #只对数据训练一次
        imgs,targets=data
        output=tudui(imgs)
        result_loss=loss(output,targets)
        optim.zero_grad() #每个参数对应调节的梯度设置为0,优化器清0
        result_loss.backward() #反向传播是在result_loss中的,有一个参数grad(记录梯度),优化器会根据它的值对参数进行更新,以降低loss
        #通过不断更新梯度来减少梯度就可以使loss最小
        optim.step() #执行单个优化步骤(参数更新)
        running_loss=running_loss+result_loss #整体误差总和
    print(running_loss)

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

import torchvision
from torch import nn

vgg16_false=torchvision.models.vgg16(weights=None)
vgg16_true=torchvision.models.vgg16(weights='DEFAULT')
print(vgg16_true)

#如何利用现有的网络来改动它的结构
train_data=torchvision.datasets.CIFAR10("./datasets",train=True,transform=torchvision.transforms.ToTensor(),
                                        download=True)
# vgg16_true.add_module('add_liner',nn.Linear(1000,10)) #加入一个线性层
vgg16_true.classifier.add_module('add_liner',nn.Linear(1000,10)) #在(classifier)中加入线性层
print(vgg16_true)

print(vgg16_false)
vgg16_false.classifier[6]=nn.Linear(4096,10) #直接对(classifier)结构进行修改
print(vgg16_false)

4.网络模型的保存和读取

import torch
import torchvision
from torch import nn

vgg16=torchvision.models.vgg16(weights=None)
#保存方式1
torch.save(vgg16,"vgg16_method1.pth")#保存网络模型的结构+模型参数

#保存方式2(官方推荐的保存方式)
torch.save(vgg16.state_dict(),"vgg16_method2.pth") #保存网络模型的参数,以字典的形式展现出来

#陷阱 针对于保存方式1的
class Module(nn.Module):
    def __init__(self):
        super(Module,self).__init__()
        self.conv1=nn.Conv2d(3,64,kernel_size=3)

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

module=Module()
torch.save(module,"module_method1.pth")
import torch
import torchvision
from torch import nn

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

#方式2 加载模型
#module2=torch.load("vgg16_method2.pth") #对应保存方式2,打印出的是参数的字典形式
# 或者
# 如何恢复网络模型结构?
vgg16=torchvision.models.vgg16(weights=None)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))  #load_state_dict:下载数据,以字典的方式读取
print(vgg16)

#陷阱--针对于方式1
class Module(nn.Module):
    def __init__(self):
        super(Module,self).__init__()
        self.conv1=nn.Conv2d(3,64,kernel_size=3)

    def forward(self,x):
        x=self.conv1(x)
        return x
module2=torch.load("module_method1.pth")
print(module2)
#这样会出错
# AttributeError: Can't get attribute 'Module' on <module '__main__' from 'E:\\study\\pytorch_learn\\pythonProject\\module_load.py'>
#加上Module这个类(网络)
# 实际写项目过程中,直接定义在一个单独的文件中(如model_save.py),再在 model_load.py 中:或者from model_save import *


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值