(自用)学习进度(三)

一、损失函数和反向传播

(1)、概念

损失函数(Loss Function)是机器学习和深度学习中都非常核心的概念。它用于量化模型的预测结果与实际结果之间的差异,作为训练过程中优化算法的目标。简单来说,损失函数衡量的是模型的预测错误程度。

反向传播Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见方法。 该方法对网络中所有权重计算损失函数的梯度。 这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。、

(2)、示例

L1Loss和MSELoss

代码

import torch
from torch.nn import L1Loss

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))

loss = L1Loss()
loss_mse = MSELoss()

result1 = loss(inputs, targets)
result2 = loss_mse(inputs, targets)

print(result1)
print(result2)

 CrossEntropyLoss交叉熵

Pytorch中CrossEntropyLoss()函数的主要是将softmax-log-NLLLoss合并到一块得到的结果。

    1、Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。

    2、然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。

    3、NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来(下面例子中就是:将log_output\logsoftmax_output中与y_target对应的值拿出来),去掉负号,再求均值。

 

公式如下:

示例

import torch
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss

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))

loss = L1Loss()
loss_mse = MSELoss()

result1 = loss(inputs, targets)
result2 = loss_mse(inputs, targets)

#print(result1)
#print(result2)

x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)

反向传播

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

dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=1)


class TEST(nn.Module):
    def __init__(self):
        super(TEST, 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()
test1 = TEST()
for data in dataloader:
    imgs, targets = data
    outputs = test1(imgs)
    result_loss = loss(outputs, targets)
    result_loss.backward()
    print("ok")

通过使用backward()函数使其进行反向传播,计算出每个节点的参数的梯度,可以通过梯度选择合适的优化器,对参数进行优化,对loss达到降低的目的

二、优化器 

(1)、概念

优化器(optimizer)在深度学习中扮演着至关重要的角色,它们用于调整模型参数以最小化训练过程中定义的损失函数。PyTorch中的torch.optim模块提供了各种优化算法的实现,使得用户可以轻松地在训练过程中选择合适的优化器来优化模型。

这个模块包含了许多不同的优化器类,其中最常见的是随机梯度下降(SGD)、Adam、Adagrad等。每个优化器都有自己的超参数(如学习率、动量等),可以根据具体任务的需求进行调整。

parameters()函数是nn.Module类中的一个方法,用于返回模型中所有需要学习的参数。这些参数通常是神经网络中的权重和偏置。

当你调用模型的parameters()方法时,它会返回一个包含所有参数的迭代器,你可以通过遍历这个迭代器来访问每个参数。通常,你可以将这些参数传递给优化器,以便在训练过程中更新它们。

优化器中的参数可以根据具体的优化算法和任务需求而定。以下是一些常见的优化器参数及其含义:

  1. lr(learning rate): 学习率,控制每次参数更新的步长。较大的学习率可能导致参数更新过大,难以收敛;而较小的学习率可能导致收敛速度过慢。通常需要进行调试以找到合适的学习率。

  2. momentum: 动量,用于加速SGD在相关方向上的更新,并减少摆动。它是一个在0到1之间的值,0表示没有动量,1表示完全使用动量。动量的作用类似于物理学中的惯性,有助于克服局部极小值。

  3. weight_decay: 权重衰减(L2正则化),用于防止模型过拟合。它通过对模型参数的更新进行惩罚,使得参数的幅度较小,有助于提高模型的泛化能力。

  4. betas: Adam优化器中的参数,用于计算一阶矩和二阶矩的指数衰减率。通常为一个包含两个值的元组,分别表示一阶矩和二阶矩的衰减率。

  5. eps: Adam优化器中的参数,用于数值稳定性。防止分母为零的情况发生。

  6. amsgrad: Adam优化器中的参数,用于指定是否使用AMSGrad算法。当设为True时,AMSGrad算法会保证更新后的学习率不会比之前的学习率更小。

  7. alpha: RMSprop优化器中的参数,用于计算移动平均的系数。

  8. centered: RMSprop优化器中的参数,用于指定是否计算中心化的二阶矩。

  9. momentum_decay: LARS(Layer-wise Adaptive Rate Scaling)优化器中的参数,用于衰减动量。有助于防止模型训练时的震荡和过拟合。

  10. trust_coef: LAMB(Layer-wise Adaptive Moments based optimizer for Batch training)优化器中的参数,用于计算自适应学习率的信任系数。

(2)、示例

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

dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=1)


class TEST(nn.Module):
    def __init__(self):
        super(TEST, 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()
test1 = TEST()
optim = torch.optim.SGD(test1.parameters(), lr=0.01) 
for epoch in range(20): #epoch表示一轮训练
    for data in dataloader:
        imgs, targets = data
        outputs = test1(imgs)
        result_loss = loss(outputs, targets)
        optim.zero_grad() #将每个节点对应的梯度清零
        result_loss.backward() #使用反向传播,求出每个节点的梯度
        optim.step() #根据之前计算的梯度来更新模型参数
        running_loss = running_loss + result_loss # 每一轮误差的总和
    print(running_loss)

从结果可以看出优化器对模型参数进行优化,每轮误差减小

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

以VGG16为例

import torchvision

# train_data = torchvision.datasets.ImageNet("data_image_net", split='train', download=True,
#                                           transform=torchvision.transforms.ToTensor())
# 以上模型无法直接使用

vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)

print(vgg16_true)

 

对VGG16进行修改

vgg16_true.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)

vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)

修改没有使用预训练权重的VGG16模型的全连接层

vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)

四、网络模型的保存和读取

两种保存方式

import torch
import torchvision

vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1,模型结构+模型参数
torch.save(vgg16, "vgg16_method1.pth")

#保存方式2,模型参数(推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth") # 保存网络模型中的参数

两种读取方式 (与保存方式一一对应)

import torch
import torchvision

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

# 方式2->加载模型
vgg16 = torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
# model = torch.load("vgg16_method2.pth")
print(vgg16)

陷阱

class Trap(nn.Module):
    def __init__(self):
        super(Trap, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

    def forward(self, x):
        x = self.conv1(x)
        return x
trap = Trap()
torch.save(trap, "trap_method1.pth")
class Trap(nn.Module):
    def __init__(self):
        super(Trap, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

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


model = torch.load('trap_method1.pth')
print(model)

陷阱在读取时,需要再定义类,也可以使用form...import...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值