pytorch07:损失函数与优化器

news2024/11/26 12:40:21

在这里插入图片描述

目录

  • 一、损失函数是什么
  • 二、常见的损失函数
    • 2.1 nn.CrossEntropyLoss交叉熵损失函数
      • 2.1.1 交叉熵的概念
      • 2.2.2 交叉熵代码实现
      • 2.2.3 加权重损失
    • 2.2 nn.NLLLoss
      • 2.2.1 代码实现
    • 2.3 nn.BCELoss
      • 2.3.1 代码实现
    • 2.4 nn.BCEWithLogitsLoss
      • 2.4.1 代码实现
  • 三、优化器Optimizer
    • 3.1 什么是优化器
      • 3.1.1梯度的概念
    • 3.2 optimizer的属性
    • 3.3 optimizer的方法
      • 3.3.1 zero_grad()
      • 3.3.2 step()
      • 3.3.3 add_param_group()
      • 3.3.4 state_dict()
      • 3.3.5 load_state_dict()
    • 3.3 梯度下降
    • 3.4 学习率
    • 3.5 多尺度学习率实验
    • 3.6 momentum动量
      • 3.6.1 指数加权平均
      • 3.6.2 加Momentum更新公式
      • 3.6.3 momentum实验
    • 4.SGD优化器
  • 四、常见的其他优化器

一、损失函数是什么

从下面的一元函数可以看出,直线拟合的点和真实值之间存在误差,这个误差就是损失函数。
损失函数:计算一个样本的差异。
代价函数:样本数据集所有损失的平均值。
目标函数:代价函数+Regularization(对模型的约束)
Regularization:为了防止模型过拟合,需要添加该项对模型进行约束
一般用代价函数来表示模型的损失函数

在这里插入图片描述
在这里插入图片描述

二、常见的损失函数

2.1 nn.CrossEntropyLoss交叉熵损失函数

功能: nn.LogSoftmax()nn.NLLLoss() 结合,进行交叉熵计算
LogSoftmax:将数据归一化到一个概率取值的范围 0~1
NLLLoss():使用概率值计算交叉熵
在这里插入图片描述
主要参数:
• weight:各类别的loss设置权值
• ignore_index:忽略某个类别
• reduction :计算模式,可为none/sum /mean
none- 逐个元素计算
sum- 所有元素求和,返回标量
mean- 加权平均,返回标量

交叉熵损失函数继承的父类损失:

class _Loss(Module):
    reduction: str

    def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:
        super().__init__()
        if size_average is not None or reduce is not None:
            self.reduction: str = _Reduction.legacy_get_string(size_average, reduce)
        else:
            self.reduction = reduction

2.1.1 交叉熵的概念

熵:表示自信息的期望
自信息:用于衡量单个事件的不确定性
右图表示信息熵:当概率为0.5左右的时候,信息熵最大。
P表示原始数据的概率分布,Q表示模型输出的概率分布。
从公式可以看出优化交叉熵也就是优化相对熵,因为H§是一个常数。
在这里插入图片描述

2.2.2 交叉熵代码实现

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

# fake data
inputs = torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)  # 设置输入数据,两个神经元
target = torch.tensor([0, 1, 1], dtype=torch.long)  # 三个类别,第一个样本类别为0,第2,3个样本类别为1

# ----------------------------------- CrossEntropy loss: reduction -----------------------------------

# flag = 0
flag = 1
if flag:
    # def loss function
    loss_f_none = nn.CrossEntropyLoss(weight=None, reduction='none')
    loss_f_sum = nn.CrossEntropyLoss(weight=None, reduction='sum')  # 将所有损失相加
    loss_f_mean = nn.CrossEntropyLoss(weight=None, reduction='mean')  # 求损失的平均值

    # forward
    loss_none = loss_f_none(inputs, target)
    loss_sum = loss_f_sum(inputs, target)
    loss_mean = loss_f_mean(inputs, target)

    # view
    print("Cross Entropy Loss:\n ", loss_none, loss_sum, loss_mean)

# --------------------------------- 手算公式验证 只计算第一个样本的损失----------------------------------------
# flag = 0
flag = 1
if flag:
    idx = 0  # 第一个样本

    input_1 = inputs.detach().numpy()[idx]  # 取第一个样本数据 [1, 2]
    target_1 = target.numpy()[idx]  # 取第一个样本的标签类别 [0]

    # 第一项
    x_class = input_1[target_1]

    # 第二项
    sigma_exp_x = np.sum(list(map(np.exp, input_1)))
    log_sigma_exp_x = np.log(sigma_exp_x)

    # 输出loss
    loss_1 = -x_class + log_sigma_exp_x

    print("第一个样本loss为: ", loss_1)

输出结果:
使用交叉熵损失计算和手动设计公式计算得到的结果相同。
在这里插入图片描述

2.2.3 加权重损失

代码实现:
设计第一个样本的权重为1,后两个样本的权重为2

# ----------------------------------- weight -----------------------------------
# flag = 0
flag = 1
if flag:
    # def loss function
    weights = torch.tensor([1, 2], dtype=torch.float)
    # weights = torch.tensor([0.7, 0.3], dtype=torch.float)

    loss_f_none_w = nn.CrossEntropyLoss(weight=weights, reduction='none')
    loss_f_sum = nn.CrossEntropyLoss(weight=weights, reduction='sum')
    loss_f_mean = nn.CrossEntropyLoss(weight=weights, reduction='mean')

    # forward
    loss_none_w = loss_f_none_w(inputs, target)
    loss_sum = loss_f_sum(inputs, target)
    loss_mean = loss_f_mean(inputs, target)

    # view
    print("\nweights: ", weights)
    print(loss_none_w, loss_sum, loss_mean)

输出结果:
注意:在计算平均损失的时候,不再是总损失/3个样本,而是做了一个加权的求平均,第一个样本的权值是1,那就算1个样本,第2,3个样本的权值为2,所以算4个样本,损失的平均值为1.821/5=0.3642。
在这里插入图片描述

2.2 nn.NLLLoss

功能:实现负对数似然函数中的负号功能
在这里插入图片描述
主要参数:
• weight:各类别的loss设置权值
• ignore_index:忽略某个类别
• reduction:计算模式,可为none/sum/mean
none-逐个元素计算
sum-所有元素求和,返回标量
mean-加权平均,返回标量

2.2.1 代码实现

flag = 1
if flag:
    weights = torch.tensor([1, 1], dtype=torch.float)

    loss_f_none_w = nn.NLLLoss(weight=weights, reduction='none')
    loss_f_sum = nn.NLLLoss(weight=weights, reduction='sum')
    loss_f_mean = nn.NLLLoss(weight=weights, reduction='mean')

    # forward
    loss_none_w = loss_f_none_w(inputs, target)
    loss_sum = loss_f_sum(inputs, target)
    loss_mean = loss_f_mean(inputs, target)

    # view
    print("\nweights: ", weights)
    print("NLL Loss", loss_none_w, loss_sum, loss_mean)

输出结果:
该函数只是对输出结果进行添加符号处理
在这里插入图片描述

2.3 nn.BCELoss

功能:二分类交叉熵,对每一个神经元一一计算loss
注意事项:输入值取值在[0,1]
在这里插入图片描述
主要参数:
• weight:各类别的loss设置权值
• ignore_index:忽略某个类别
• reduction :计算模式,可为none/sum/mean
none-逐个元素计算
sum-所有元素求和,返回标量
mean-加权平均,返回标量

2.3.1 代码实现

注意:使用该函数,如果输入的值不是0~1之间的数据,需要添加sigmoid函数。

flag = 1
if flag:
    inputs = torch.tensor([[1, 2], [2, 2], [3, 4], [4, 5]], dtype=torch.float)
    target = torch.tensor([[1, 0], [1, 0], [0, 1], [0, 1]], dtype=torch.float)
    target_bce = target
    # 使用该函数一定要注意,将输出值压缩到0~1之间,使用sigmoid将输入值压缩到0~1之间
    inputs = torch.sigmoid(inputs)
    weights = torch.tensor([1, 1], dtype=torch.float)
    loss_f_none_w = nn.BCELoss(weight=weights, reduction='none')
    loss_f_sum = nn.BCELoss(weight=weights, reduction='sum')
    loss_f_mean = nn.BCELoss(weight=weights, reduction='mean')
    # forward
    loss_none_w = loss_f_none_w(inputs, target_bce)
    loss_sum = loss_f_sum(inputs, target_bce)
    loss_mean = loss_f_mean(inputs, target_bce)

    # view
    print("\nweights: ", weights)
    print("BCE Loss", loss_none_w, loss_sum, loss_mean)

输出结果:
对每一个神经元计算loss
在这里插入图片描述

2.4 nn.BCEWithLogitsLoss

功能:结合Sigmoid与二分类交叉熵
注意事项:使用该函数,网络最后不加sigmoid函数
主要参数:
• pos _weight :正样本的权值
• weight:各类别的loss设置权值
• ignore_index:忽略某个类别
• reduction :计算模式,可为none/sum/mean
none-逐个元素计算
sum-所有元素求和,返回标量
mean-加权平均,返回标量
在这里插入图片描述

2.4.1 代码实现

# ----------------------------------- 4 BCE with Logis Loss -----------------------------------
# flag = 0
flag = 1
if flag:
    inputs = torch.tensor([[1, 2], [2, 2], [3, 4], [4, 5]], dtype=torch.float)
    target = torch.tensor([[1, 0], [1, 0], [0, 1], [0, 1]], dtype=torch.float)

    target_bce = target

    # inputs = torch.sigmoid(inputs)

    weights = torch.tensor([1, 1], dtype=torch.float)

    loss_f_none_w = nn.BCEWithLogitsLoss(weight=weights, reduction='none')
    loss_f_sum = nn.BCEWithLogitsLoss(weight=weights, reduction='sum')
    loss_f_mean = nn.BCEWithLogitsLoss(weight=weights, reduction='mean')

    # forward
    loss_none_w = loss_f_none_w(inputs, target_bce)
    loss_sum = loss_f_sum(inputs, target_bce)
    loss_mean = loss_f_mean(inputs, target_bce)

    # view
    print("\nweights: ", weights)
    print(loss_none_w, loss_sum, loss_mean)

输出结果:
在这里插入图片描述

如果再使用sigmoid函数会导致损失函数发生变化,如下:
在这里插入图片描述

三、优化器Optimizer

3.1 什么是优化器

机器学习模型训练有以下几个步骤,优化器是在哪一步开始使用呢?
将数据输入到模型当中会得到一个output值,将output值和target目标值放入到损失函数计算损失,损失使用反向传播的方法求出训练过程中每一个参数的梯度,优化器拿到梯度,使用优化策略,减少损失。
在这里插入图片描述

3.1.1梯度的概念

pytorch的优化器:管理更新模型中可学习参数的值,使得模型输出更接近真实标签
导数:函数在指定坐标轴上的变化率
方向导数:指定方向上的变化率
梯度:一个向量,方向为方向导数取得最大值的方向
梯度下降:朝着梯度的负方向取变化,也就是变化最快的
在这里插入图片描述
在这里插入图片描述

3.2 optimizer的属性

在这里插入图片描述基本属性
• defaults:优化器超参数。
• state:参数的缓存,如momentum的缓存(前几次更新的梯度)。
• params_groups:管理的参数组,list类型中存储的字典类型。
• _step_count:记录更新次数,学习率调整中使用。

3.3 optimizer的方法

3.3.1 zero_grad()

作用:清空所管理参数的梯度
为什么使用该方法,这是因为pytorch特性:张量梯度不自动清零
在这里插入图片描述
代码实现:

flag = 1
if flag:
    print("weight before step:{}".format(weight.data))
    optimizer.step()  # 修改lr=1 0.1观察结果
    print("weight after step:{}".format(weight.data))
    print(
        "weight in optimizer:{}\nweight in weight:{}\n".format(id(optimizer.param_groups[0]['params'][0]), id(weight)))
    # 优化器当中存储的是参数变量的地址
    print("weight.grad is {}\n".format(weight.grad))
    optimizer.zero_grad()
    print("after optimizer.zero_grad(), weight.grad is\n{}".format(weight.grad))

输出结果:
通过输出可以看出优化器当中存储的是参数变量的地址,不需要额外使用内存保存梯度;
在这里插入图片描述

3.3.2 step()

作用:执行一步更新
在这里插入图片描述
代码实现:

import os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
import torch
import torch.optim as optim
from common_tools import set_seed

set_seed(1)  # 设置随机种子

weight = torch.randn((2, 2), requires_grad=True)
weight.grad = torch.ones((2, 2))  # 手动设置梯度为1

optimizer = optim.SGD([weight], lr=1)
# optimizer = optim.SGD([weight], lr=0.1)

# ----------------------------------- step -----------------------------------
# flag = 0
flag = 1
if flag:
    print("weight before step:{}".format(weight.data))
    optimizer.step()  # 梯度下降方法 观察结果 输入-梯度=输出
    print("weight after step:{}".format(weight.data))

结果输出:
当我们设置梯度为1,学习率为1的时候,输出结果=输入数据-梯度;
在这里插入图片描述
当我们设置梯度为1,学习率为0.1的时候,输出结果=输入数据-梯度;
在这里插入图片描述

3.3.3 add_param_group()

作用:添加参数组
对于不同的组有不同的超参数设置,例如一个深度学习模型,我们对特征提取模块的学习率设置小一些,让它更新慢一点,在全连接层可以设置学习率大一些。
在这里插入图片描述
代码实现:

flag = 1
if flag:
    print("optimizer.param_groups is\n{}".format(optimizer.param_groups))
    w2 = torch.randn((3, 3), requires_grad=True)
    optimizer.add_param_group({"params": w2, 'lr': 0.0001})
    print("optimizer.param_groups is\n{}".format(optimizer.param_groups))

输出结果:
将一个新的参数组
在这里插入图片描述

3.3.4 state_dict()

作用:获取优化器当前状态信息字典
当我们训练需要中断的时候可以使用该方法,将当前训练的参数保存下来。
在这里插入图片描述
代码实现

flag = 1
if flag:

    optimizer = optim.SGD([weight], lr=0.1, momentum=0.9)
    opt_state_dict = optimizer.state_dict()

    print("state_dict before step:\n", opt_state_dict)

    for i in range(10):
        optimizer.step()  # 更新参数

    print("state_dict after step:\n", optimizer.state_dict())

    torch.save(optimizer.state_dict(), os.path.join(BASE_DIR, "optimizer_state_dict.pkl"))  # 将当前state_dict保存成为序列化信息

输出结果:
将10次step的结果保存在optimizer_state_dict.pkl当中,同时会在当前文件夹生成一个新的文件。
在这里插入图片描述
在这里插入图片描述

3.3.5 load_state_dict()

作用:加载状态信息字典
用于读取上一次训练所保存的参数;
在这里插入图片描述
代码实现:

flag = 1
if flag:
    optimizer = optim.SGD([weight], lr=0.1, momentum=0.9)
    state_dict = torch.load(os.path.join(BASE_DIR, "optimizer_state_dict.pkl"))#首先加载进来训练参数

    print("state_dict before load state:\n", optimizer.state_dict())
    optimizer.load_state_dict(state_dict) #将训练参数添加到优化器当中
    print("state_dict after load state:\n", optimizer.state_dict())

输出结果:
在这里插入图片描述

3.3 梯度下降

对y=4 x 2 x^2 x2使用梯度下降的方法更新参数,使其到达最低点,发现在计算到第三次的时候,y的值变的很大,并没有减少参数,反而变的更大。
在这里插入图片描述
代码实现:

import torch
import numpy as np
import matplotlib.pyplot as plt

torch.manual_seed(1)


def func(x_t):
    """
    y = (2x)^2 = 4*x^2      dy/dx = 8x
    """
    return torch.pow(2 * x_t, 2)  # 求平方


# init
x = torch.tensor([2.], requires_grad=True)

# ------------------------------ 绘制函数基本曲线图 ------------------------------
flag = 0
# flag = 1
if flag:
    x_t = torch.linspace(-3, 3, 100)
    y = func(x_t)
    plt.plot(x_t.numpy(), y.numpy(), label="y = 4*x^2")
    plt.grid()
    plt.xlabel("x")
    plt.ylabel("y")
    plt.legend()
    plt.show()

# 横轴设为参数x,纵轴设置为y


# ------------------------------ gradient descent ------------------------------
# flag = 0
flag = 1
if flag:
    iter_rec, loss_rec, x_rec = list(), list(), list()  # 记录迭代次数和损失

    lr = 1  # 学习率/1. /.5 /.2 /.1 /.125
    max_iteration = 4  # 设置最大迭代次数

    for i in range(max_iteration):
        y = func(x)
        y.backward()  # 求取x的梯度

        print("Iter:{}, X:{:8}, X.grad:{:8}, loss:{:10}".format(
            i, x.detach().numpy()[0], x.grad.detach().numpy()[0], y.item()))

        x_rec.append(x.item())

        x.data.sub_(lr * x.grad)  # x -= x.grad  数学表达式意义:  x = x - x.grad    # 0.5 0.2 0.1 0.125
        x.grad.zero_()

        iter_rec.append(i)
        loss_rec.append(y.item())

    # plt.subplot(121).plot(iter_rec.detach().numpy(), loss_rec.detach().numpy(), '-ro')
    plt.subplot(121).plot(iter_rec, loss_rec, '-ro')

    plt.xlabel("Iteration")
    plt.ylabel("Loss value")

    x_t = torch.linspace(-3, 3, 100)
    y = func(x_t)
    plt.subplot(122).plot(x_t.numpy(), y.numpy(), label="y = 4*x^2")
    plt.grid()
    y_rec = [func(torch.tensor(i)).item() for i in x_rec]
    plt.subplot(122).plot(x_rec, y_rec, '-ro')
    plt.legend()
    plt.show()

输出结果:
在这里插入图片描述

当学习率设置为1,通过输出结果可以发现,随着迭代次数的增加,数值更新的步伐越大,损失值越大。那么如何解决这个问题呢。

3.4 学习率

通过设置学习率可以控制每次梯度下降的更新步伐大小。
在这里插入图片描述
代码展示:
在这里插入图片描述
输出结果:
在这里插入图片描述
当学习率设置过小为0.01时,10次迭代结果如下,会发现需要迭代多长才能梯度下降到最优值:
在这里插入图片描述

3.5 多尺度学习率实验

经过上次两次会发现学习率过大或者过小都不合适,那么如何找到一个最优的学习率可以提高梯度下降的速率?
使用多尺度学习率做测试,选取学习率区间0.01~0.2,在该区间划分10个等间距的学习率进行实验。

代码实现:

flag = 1
if flag:
    iteration = 100
    num_lr = 10
    lr_min, lr_max = 0.01, 0.2  # .5 .3 .2

    lr_list = np.linspace(lr_min, lr_max, num=num_lr).tolist()  # 生成num_lr个等间距的数组
    loss_rec = [[] for l in range(len(lr_list))]
    # iter_rec = list()

    for i, lr in enumerate(lr_list):
        x = torch.tensor([2.], requires_grad=True)
        for iter in range(iteration):
            y = func(x)
            y.backward()
            x.data.sub_(lr * x.grad)  # x.data -= x.grad
            x.grad.zero_()

            loss_rec[i].append(y.item())

    for i, loss_r in enumerate(loss_rec):
        plt.plot(range(len(loss_r)), loss_r, label="LR: {}".format(lr_list[i]))
    plt.legend()
    plt.xlabel('Iterations')
    plt.ylabel('Loss value')
    plt.show()

实验结果:
在这里插入图片描述

通过实验结果发现,当学习率在0.136的时候,此时会更快降低损失,y的值更快到达最小值。

3.6 momentum动量

结合当前梯度与上一次更新信息,用于当前更新
优化器中的momentum是指动量(Momentum),它是一种在优化算法中常用的技术,用于加速参数的更新。动量是在每次更新参数时,将之前的一次更新作为一部分权重加入到当前的更新中,从而使得参数的更新更加平滑,减少了震荡。
在优化过程中,优化器会根据损失函数和模型参数计算梯度。但是,由于模型参数可能存在多个局部最小值,优化器可能会在损失函数曲面上跳跃式地移动,导致参数更新剧烈,甚至出现震荡。动量技术通过引入历史更新信息,使得优化器能够更好地平滑地移动到最优解,从而减少了震荡和过拟合的风险。
在PyTorch等深度学习框架中,优化器通常会内置动量参数,用户只需要在创建优化器时指定学习率和优化器类型,框架会自动计算动量值并应用于优化过程。

3.6.1 指数加权平均

首先了解一下指数加权平均,数学思想:要求取当前时刻的平均值,距离当前时刻越近的参数值,参考价值越大,所占的权重越大,这个权重随着时间间隔的增大呈指数下降。
在这里插入图片描述
代码实现:

import torch
import numpy as np
import torch.optim as optim
import matplotlib.pyplot as plt
torch.manual_seed(1)
def exp_w_func(beta, time_list):
    return [(1 - beta) * np.power(beta, exp) for exp in time_list]
beta = 0.9
num_point = 100
time_list = np.arange(num_point).tolist()
# ------------------------------ exponential weight ------------------------------
# flag = 0
flag = 1
if flag:
    weights = exp_w_func(beta, time_list)

    plt.plot(time_list, weights, '-ro', label="Beta: {}\ny = B^t * (1-B)".format(beta))
    plt.xlabel("time")
    plt.ylabel("weight")
    plt.legend()
    plt.title("exponentially weighted average")
    plt.show()

    print(np.sum(weights))

实现结果:
在这里插入图片描述
通过代码实现可以看出,距离当前时刻越远,它对当前时刻的平均值越小。


当设置多个beta值的实验结果如下:

flag = 1
if flag:
    beta_list = [0.98, 0.95, 0.9, 0.8] #设置4中不同的beta 
    w_list = [exp_w_func(beta, time_list) for beta in beta_list]
    for i, w in enumerate(w_list):
        plt.plot(time_list, w, label="Beta: {}".format(beta_list[i]))
        plt.xlabel("time")
        plt.ylabel("weight")
    plt.legend()
    plt.show()

在这里插入图片描述

通过实验可以看出,beta 可以理解为记忆周期,当beta值越小,记忆周期越短,beta=0.8时,当到达20天的时候就不再关注远期的一个记忆值;beta值越大,记忆周期也就越长。

3.6.2 加Momentum更新公式

添加momentum更新之后的公式不仅仅只考虑当前的梯度,还要考虑上一次更新梯度乘以m的值,以及上上次梯度* m 2 m^2 m2…,距离当前时刻越远的值,对当前的影响越小,因为m是个小于1的数。
在这里插入图片描述

3.6.3 momentum实验

实验一:设置momentum为0,学习率分别为0.01和0.03时函数收敛速率。
代码:

flag = 1
if flag:
    def func(x):
        return torch.pow(2 * x, 2)  # y = (2x)^2 = 4*x^2        dy/dx = 8x


    iteration = 100
    m = 0.0  # .9 .63

    lr_list = [0.01, 0.03]

    momentum_list = list()
    loss_rec = [[] for l in range(len(lr_list))]
    iter_rec = list()

    for i, lr in enumerate(lr_list):
        x = torch.tensor([2.], requires_grad=True)

        momentum = 0. if lr == 0.03 else m
        momentum_list.append(momentum)

        optimizer = optim.SGD([x], lr=lr, momentum=momentum)

        for iter in range(iteration):
            y = func(x)
            y.backward()

            optimizer.step()
            optimizer.zero_grad()

            loss_rec[i].append(y.item())

    for i, loss_r in enumerate(loss_rec):
        plt.plot(range(len(loss_r)), loss_r, label="LR: {} M:{}".format(lr_list[i], momentum_list[i]))
    plt.legend()
    plt.xlabel('Iterations')
    plt.ylabel('Loss value')
    plt.show()

实验结果:
在这里插入图片描述

实验结果分析:因为黄色部分学习率更高,所以收敛的速率比较快。


实验二:设置学习率0.01时,momentum为0.9
实验结果如下:
在这里插入图片描述

实验结果分析:虽然0.01的学习率比较低,但是添加momentum之后收敛速率增加;为什么会出现波浪?因为在收敛到最小值的时候仍然保留着之前的权重,所以没法快速收敛到一个平稳值。

4.SGD优化器

在这里插入图片描述
• params:管理的参数组
• lr:初始学习率
• momentum:动量系数,贝塔
• weight_decay:L2正则化系数
• nesterov:是否采用NAG

四、常见的其他优化器

  1. optim.SGD:随机梯度下降法
  2. optim.Adagrad:自适应学习率梯度下降法
  3. optim.RMSprop: Adagrad的改进
  4. optim.Adadelta: Adagrad的改进
  5. optim.Adam:RMSprop结合Momentum
  6. optim.Adamax:Adam增加学习率上限
  7. optim.SparseAdam:稀疏版的Adam
  8. optim.ASGD:随机平均梯度下降
  9. optim.Rprop:弹性反向传播
  10. optim.LBFGS:BFGS的改进

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1357561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPT/GPT4科研应用与AI绘图技术及论文高效写作(建议收藏)

详情点击链接:GPT/GPT4科研实践应用与AI绘图技术及论文高效写作 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析,AI画图,图像识别,文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Clau…

轻量检测模型NanoDet解析

官方解读:YOLO之外的另一选择,手机端97FPS的Anchor-Free目标检测模型NanoDet现已开源~ - 知乎 official implementation: GitHub - RangiLyu/nanodet: NanoDet-Plus⚡Super fast and lightweight anchor-free object detection model. &…

[LitCTF 2023]这是什么?SQL !注一下 !

[LitCTF 2023]这是什么?SQL !注一下 ! wp 题目描述:为了安全起见多带了几个套罢了o(▽)q 页面内容(往下滑): SQL 语句已给出,无非是更换了闭合方式。 先输个 1 试试: …

<HarmonyOS第一课>1~10课后习题汇总

HarmonyOS第一课 <HarmonyOS主题课>1~3课后习题汇总 1运行Hello World 判断题 main_pages.json存放页面page路径配置信息。(正确)DevEco Studio是开发HarmonyOS应用的一站式集成开发环境。(正确) 单选题…

MS4553S用于开漏模式和推拉模式的 2bit 双向电平转换器,可替代TXS0102/PCA9306等

产品简述 MS4553S 是一款双向电平转换器,可以用作混合电压的数字信 号系统中。其使用两个独立构架的电源供电, A 端供电电压范围是 1.65V 到 5.5V , B 端供电电压范围是 2.3V 到 5.5V 。可用在电压为 1.8V 、 2.5V 、 3.3V 和 5V 的信号转…

vue3 vuedraggable draggable element must have an item slot

vue3vite 看官网使用这种<template #item“{ element }”> <draggablev-model"myArray"start"onStart"end"onEnd":sort"false"item-key"id"draggable".item"handle".mover" ><template…

3-sql注入之Mysql手工注入

文章目录 sql注入之Mysql手工注入sqli-labs数字型注入注入流程注入语句 sql注入之Mysql手工注入 练习靶场为sqli-labs第二关数字型注入 sqli-labs数字型注入 在url中输入id值&#xff0c;执行查询sql语句。即可得到对应数据 less-2源码分析&#xff1a; 浏览器 进行数据提交…

python旅游大数据分析可视化大屏 游客分析+商家分析+舆情分析 计算机毕业设计(附源码)Flask框架✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

关于目标检测任务中,XML(voc格式)标注文件的可视化

1. 前言 最近在弄关于目标检测的任务&#xff0c;因为检测的图片和标签是分开的&#xff0c;可视化效果不明显&#xff0c;也不知道随便下载的数据集&#xff0c;标注信息对不对。网上看了好多代码&#xff0c;代码风格和本人平时不同&#xff0c;看起来麻烦&#xff0c;也不知…

接了一条路由器视频广告

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 2023年7月&#xff0c;松松团队荣幸的承接了“某口袋路由器”的短视频广告。 我们向客户索取了了几个卖点&#xff1a; 1.家用美观不用走线(无线小巧美观) 外出便携(出差、户外直播、露营等&#xff0c;只要充满电…

Spring中的工厂类

目录 1.ApplicationContext 4.2.BeanFactory 1.ApplicationContext ApplicationContext的实现类&#xff0c;如下图&#xff1a; ClassPathXmlApplicationContext&#xff1a;加载类路径下 Spring 的配置文件 FileSystemXmlApplicationContext&#xff1a;加载本地磁盘下 S…

GO语言笔记1-变量与基本数据类型

变量使用步骤 声明赋值使用 package main import "fmt" func main(){var age int //声明一个 int类型的变量叫ageage 18 //给变量用 赋值fmt.Println(age) //使用变量 输出变量的值 } 编译运行输出变量值 变量的四种使用方式 package main import "fmt&q…

Linux系统使用超详细(六)~进程管理

目录 一、认识进程 二、进程号 2.1.进程号概念 2.2.进程号作用 三、进程查看 3.1. ps命令&#xff1a; 3.2. top命令&#xff1a; 3.3. htop命令&#xff1a; 3.4. pstree命令&#xff1a; 3.5. pgrep命令&#xff1a; 四、进程状态 五、进程优先级 六、进程优先…

C# 反射的终点:Type,MethodInfo,PropertyInfo,ParameterInfo,Summry

文章目录 前言反射是什么&#xff1f;常用类型操作SummryPropertyInfoMethodInfo无参函数运行 有参函数运行,获取paramterInfo 总结 前言 我之前写了一篇Attribute特性的介绍&#xff0c;成功拿到了Attribute的属性&#xff0c;但是如果把Attribute玩的溜&#xff0c;那就要彻…

一篇文章带你了解基于 Jenkins 流水线方式部署的好处

在软件开发过程中&#xff0c;部署是将代码从开发环境转移到生产环境的关键步骤。传统的部署方式可能涉及多个手动步骤和容易出错的过程。然而&#xff0c;基于 Jenkins 流水线方式部署可以带来许多好处&#xff0c;包括提高效率、一致性和可靠性。本文将探讨基于 Jenkins 流水…

k_d树, KNN算法学习笔记_1 距离和范数

k_d树, KNN算法学习笔记_1 距离和范数 二维树中最近邻搜索的示例。这里&#xff0c;树已经构建好了&#xff0c;每个节点对应一个矩形&#xff0c;每个矩形被分割成两个相等的子矩形&#xff0c;叶子对应于包含单个点的矩形 From Wikipedia 1&#xff0e; k k k近邻法是基本且简…

使用通用MCU实现无人机飞行任务的快速二次开发

使用通用MCU实现无人机飞行任务的快速二次开发 ---TIDronePilot外部控制offboard模式介绍 无名小哥 2024年1月1日 传统飞控二次开发方法和主要存在的问题简介 通过对前面几讲中《零基础竞赛无人机积木式编程指南》系列开发教程的学习可知&#xff0c;在以往TI电赛真题的学习…

简单多状态dp问题(打家劫舍Ⅱ)

通过分类谈论&#xff0c;将环形的问题&#xff0c;转化成两个线性的 “ 打家劫舍Ⅰ ” 1.状态表示 2.状态转移方程 3.初始化 f[ 0 ] nums[ 0 ] g[ 0 ] 0 4.填表顺序 从左往右填表&#xff0c;两个表一块填 5.返回值 max( f[ n-1 ] , g [ n - 1 ] )

VM安装虚拟机及初始化操作

一、VM下载及暗转 虚拟机指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统&#xff0c;在实体计算机中能够完成的工作在虚拟机中都能够实现。VMware 是一款功能强大的桌面虚拟计算机软件&#xff0c;提供用户可在单一的桌面上同时运行不同的…

YOLOv8改进 | 2023Neck篇 | 利用Gold-YOLO改进YOLOv8对小目标检测

一、本文介绍 本文给大家带来的改进机制是Gold-YOLO利用其Neck改进v8的Neck,GoLd-YOLO引入了一种新的机制——信息聚集-分发(Gather-and-Distribute, GD)。这个机制通过全局融合不同层次的特征并将融合后的全局信息注入到各个层级中,从而实现更高效的信息交互和融合。这种…