【Pytorch神经网络理论篇】 10 优化器模块+退化学习率

同学你好!本文章于2021年末编写,获得广泛的好评!

故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现,

Pytorch深度学习·理论篇(2023版)目录地址为:

CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!https://v9999.blog.csdn.net/article/details/127587345欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~

 

1 优化器模块的作用

1.1 反向传播的核心思想

反向传播的意义在于告诉模型我们需要将权重修改到什么数值可以得到最优解,在开始探索合适权重的过程中,正向传播所生成的结果与实际标签的目标值存在误差,反向传播通过这个误差传递给权重,要求权重进行适当的调整来达到一个合适的输出,最终使得正向传播所预测的结果与标签的目标值的误差达到最小,以上即为反向传播的核心思想

1.2 优化器简介

正向结构与损失函数获取完毕之后,通过优化器模块中优化函数来实现对学习参数的优化,其内部原理主要是梯度下降的方法实现的

1.2.1 优化器与梯度下降

优化器是指通过算法帮助模型在训练过程中更快更好地将参数调整到位,梯度下降主要在损失函数求解出损失值时,它利用梯度下降的方向为前进方向,沿着梯度下降的方向求解最小值,帮助模型找到最小的那个损失值,从而可以反向推算出学习参数的权重,达到优化的目的。

1.3 优化器的类型

1.3.1 批量梯度下降

主要特点:遍历全部数据集计算一次损失函数,根据函数结果更新梯度。

缺点:每次都要遍历全部数据集,计算开销大,计算慢,不支持在线学习。

1.3.2 随机梯度下降

主要特点:每检查一个数据就进行损失函数计算,求梯度更新函数

缺点:计算速度快,收敛性不好,易在最优点附近摆动,两次参数也可能互相抵消,函数震荡剧烈。

1.3.3 小批量梯度下降(折中)

主要特点:将数据集分成若干批,按照批次来实现更新参数,一批中的一组数据共同决定梯度的反向,梯度下降方向不易跑偏,减少随机性,计算量小。

缺点:————————

2 优化器

2.1 常见的优化器

2.1.1 Adam

较为常用,学习率设为3e-4

2.1.2 Ranger

基于RAdam与Lookhead优化器基础上融合而来,兼顾两者的优点,综合性能占优,使得其在各种模型中都具有较高的精度、收敛速度快、使用方便、无需手动调参。

  • RAdam:带有整流器的Adam,能够利用潜在散度动态地打开或者管理自适应学习率。
  • Lookhead:通过迭代更新两组权重的方法,提前观察另一个优化器生成的序列进而选择探索方向。

2.1.3 AMSGrad

在Adam优化器基础上使用二阶冲量,在计算机视觉模型上表现更为出色

2.1.4 Adamax

在带有词向量的自然语言处理模型中表现得更好

2.2 如何选取优化器

2.2.1 手动精确调整模型方面

一般先使用Adam优化器训练模型,在模型无法进一步收敛后,再使用SGD优化器进行手动调节学习率,进一步提升模型性能。

2.2.2 自动精确调整模型方面

一般以Adam优化器为最常用,在收敛速度、模型训练精度都具有较好的效果,对于学习率设置较为宽松,更易于使用。

2.3 优化器的使用

2.3.1 优化器调用方法

优化器在工作时,先算出梯度(根据损失值对某个参数求偏导),再沿着该梯度的方向算出一段距离(由学习率决定),该差值作为变化值更新到原有参数上。

import torch
### Adam()是优化器方法 
#model.parameters():待优化的权重参数,调用模型的parameters(),将返回值传入
#lr:学习率,学习率越大收敛越快!
optimizer = torch.optim.Adam(model.parameters(),lr = lreaning_rate)

2.3.2 查看优化器的参数结构

Pytorch中的每个优化器类中均有param_groups属性,该属性包括每个待优化权重的配置参数,是一个列表对象

list(optimizer.param_group[0].keys())
#返回: ['params','lr','eps','weight_deacy','amsgrad']
#返回: ['优化器要作用的权重参数','学习率','','权重参数的衰减率','是否使用二阶冲量的方式']
### 权重参数的衰减率weight_deacy是指模型在训练过程中使用L2郑泽华的衰减参数,L2正则化是一种防止过拟合的方法

3 退化学习率

3.1 退化学习率简介

退化学习率/学习率衰减,即在刚训练开始时,使用大的学习率加速,训练到一定程度后使用小的学习率来提高精度。

3.1.1 退化学习率/学习率衰减 手动代码实现

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
for i in range(epochs):loss = model.getloss(xt,yt)losses.append(loss.item()) # 保存中间状态的损失值optimizer.zero_grad() # 清空之前的梯度loss.backward() # 反向传播损失值optimizer.step() # 更新参数if i % 50 == 0: # 每五十步将学习率 lr X 0.99for p in optimizer.param_groups:p['lr'] = p['lr'] * 0.99lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

3.2 使用lr_scheduler接口实现退化学习率

在Ptorch的optim模块中,将退化学习率的多种实现方法封装到lr_scheduler接口中

3.2.1 使用lr_scheduler接口实现退化学习率 代码实现

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.StepLR(optimizer,step_size=50,gamma=0.99) # 设置退化学习率,每50步乘以0.99
for i in range(epochs):loss = model.getloss(xt,yt)losses.append(loss.item()) # 保存中间状态的损失值optimizer.zero_grad() # 清空之前的梯度loss.backward() # 反向传播损失值optimizer.step() # 更新参数scheduler.step() # 调用退化学习率对象lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

 3.2.2 lr_scheduler接口中的退化学习率种类

  • 等间隔调整学习率StepLR():每训练指定步数,学习率调整为 lr = lr×gamma (gamma为手动设置的退化率参数)。
#optimizer (Optimizer) – 包装的优化器。
#step_size (int) – 学习率衰减间隔,例如若为 30,则会在 30、 60、 90…个 epoch 时,将学习率调整为 lr * gamma。
#gamma (float) – 学习率衰减的乘积因子。
#last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。
class torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
#调整倍数为gamma 倍,调整间隔为step_size。当last_epoch = -1时,将初始lr设置为lr。
  • 多间隔调整学习率MultiStepLR():按照指定的步数来调整学习率。调整方式也是lr= lr x gamma。
  • 指数衰减调整学习率ExponentialLR():每训练一步,学习率呈指数型衰减,即学习率调整为lr=lr ∗ gamma^epoch (step为训练步数)。
class torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1)
#根据epoch数和gamma调整学习率,每个epoch都在改变,调整公式:lr∗gamma^epoch。# 参数:
## optimizer (Optimizer) – 包装的优化器。
## gamma (float) – 学习率衰减的乘积因子。
## last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。
  • 余弦退火函数调整学习率CosineAnnealingLR():余弦退火指的就是按照弦函数的曲线进行衰减,每训练一步,学习率呈余弦函数型衰减。
    torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1)
    # 参数:
    ## T_max(int) – 一次学习率周期的迭代次数,即 T_max 个 epoch 之后重新设置学习率。
    ## eta_min(float) – 最小学习率,即在一个周期中,学习率最小会下降到 eta_min,默认值为 0。
  • 根据指标调整学习率ReduceLROnPlateau:当某指标(loss或accuracy)在最近几次训练中均没有变化(下降或升高超过给定阈值)时,调整学习率。
  • 自定义调整学习率LambdaLR:将每个参数组的学习速率设置为初始的lr乘以一个给定的函数。
class torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1)
#参数:
##optimizer (Optimizer) – 包装的优化器。
##lr_lambda (function or list) – 一个函数来计算一个乘法因子给定一个整数参数的epoch,或列表等功能,为每个组optimizer.param_groups。
##last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。

3.2.3 多种学习率衰减总结

LambdaLR最为灵活,可以根据需求指定任何策略的学习率变化。它在fne-tune(微调模型的一种方法)中特别有用,不但可以为不同层设置不同的学习率,而且可以为不同层设置不同的学习率调整策略。

3.3 使用lr_scheduler接口实现多种退化学习率

MultiStepLR():在论文中使用较多,简单可控。

ReducelROnPlateau():自动化程度高,参数多。

3.3.1 使用lr_scheduler接口实现MultiStepLR

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[200,700,900],gamma=0.99) #在100 700 900 次时,调整学习率for i in range(epochs):loss = model.getloss(xt,yt)losses.append(loss.item()) # 保存中间状态的损失值optimizer.zero_grad() # 清空之前的梯度loss.backward() # 反向传播损失值optimizer.step() # 更新参数scheduler.step() # 调用退化学习率对象lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

3.3.2 使用lr_scheduler接口实现ReduceLROnPlateau

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,mode='min', # 要监控模型的最大值or最小值factor= 0.5, # 退化学习率参数 gammapatience=5, # 不再减少/增加的累计次数verbose=True, # 触发规则时是否打印信息threshold=0.001, # 监控值触发规则的阈值threshold_mode='abs', # 计算触发条件的规则cooldown=0, # 触发规则后的停止监控步数,避免lr下降过快min_lr=0, # 允许的最小退化学习率eps=1e-08 # 当退化学习率小于该值时,停止调整
)for i in range(epochs):loss = model.getloss(xt,yt)losses.append(loss.item()) # 保存中间状态的损失值scheduler.step(loss.item()) # 调用退化学习率对象,需要传入被监控的值,否则代码出错 【ReduceLROnPlateau()特别的地方】optimizer.zero_grad() # 清空之前的梯度loss.backward() # 反向传播损失值optimizer.step() # 更新参数lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

上述代码 参数Threshold_mode有两种取值:

'rel':在参数mode为max时,如果监控值超过best(1+threshold),则触发规则;在参数mode为min时,如果监控值低于best(1 - threshold),则触发规则。【best为训练过程中的历史最好值】

'abs':在参数mode为max时,如果监控值超过best + threshold,则触发规则;在参数mode为min时,如果监控值低于best - threshold,则触发规则。【best为训练过程中的历史最好值】

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

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

相关文章

Android fb0 截屏实现

问题:我们有几个项目,在项目1和项目2上实现截屏是没有问题的,但是在项目3上实现截屏是不行的 原因:分辨率差异引起的问题,分辨率长宽一定要是32的整数倍 Dear customer, Sorry for the late reply due to annual leave. I dont think this issue relates with thediff…

Python trino执行hive insert overwrite不生效的问题

使用python的trino包执行insert overwrite,但是overwrite却没有生效的问题 根据trino的官网介绍的insert overwrite的开启方式,开启hive的insert overwrite会话,使当前会话的insert into语句支持insert overwrite,也即支持插入数…

HAProxy负载均衡原理及企业级实例部署haproxy集群

HAProxy是一种高效、可靠、免费的高可用及负载均衡解决方案,非常适合于高负载站点的七层数据请求。客户端通过HAProxy代理服务器获得站点页面,而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。 同一客户端访问服务器&…

【Pytorch神经网络实战案例】07 预测泰坦尼克号上生存的乘客

1 样本处理 1.1 载入样本代码---Titanic forecast.py(第1部分) import numpy as np import torch import torch.nn as nn import torch.nn.functional as F from scipy import stats import pandas as pd import matplotlib.pyplot as plt import os o…

ubuntu下 安装 adb

1、把adb tool工具考到你要安装的目录夏目 <

基于sanic的服务使用celery完成动态修改定时任务

首先声明一下 考虑到celery目前和asyncio的不兼容性&#xff0c;协程任务需要转换为非异步的普通方法才能被当做task加入定时&#xff0c;并且celery和asyncio使用可能会带来预想不到的问题&#xff0c;在celery官方第二次承诺的6.0版本融合asyncio之前&#xff0c;需要慎重考虑…

shell 中的ifeq

libs_for_gcc -lgnunormal_libs foo: $(objects)ifeq ($(CC),gcc)$(CC) -o foo $(objects) $(libs_for_gcc)else$(CC) -o foo $(objects) $(normal_libs)endif 可见&#xff0c;在上面示例的这个规则中&#xff0c;目标“foo”可以根据变量“$(CC)”值来选取不同的函数库来编…

第一篇unity

在网上找的学习资料&#xff0c;做了点简单的效果。 半成品 http://files.cnblogs.com/files/buzhidaojiaoshenme/unity.rar 第二个游戏&#xff0c;方向键和“W”&#xff0c;”S“键移动方块&#xff0c;碰撞到最右边的方块过关。 http://files.cnblogs.com/files/buzhidaoji…

报错:OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib already initialized.

问题描述&#xff1a; OMP: Error #15: Initializing libiomp5.dylib, but found libiomp5.dylib already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade perf…

Pyscript,使用Python编写前端脚本

介绍 Anaconda的CEO Peter Wang在前两个月的时候发布了Pyscript&#xff0c;实现了在HTML支持Python的使用&#xff0c;整个引用过程甚至不需要安装任何环境&#xff0c;只需要使用link和script标签即可引用实现Python在HTML中运行的功能&#xff0c;在HTML中也可以运行和使用…

如何把应用程序app编译进android系统

转载&#xff1a;http://ywxiao66.blog.163.com/blog/static/175482055201152710441106/------------------------------------------------------------------把常用的应用程序编译到img文件中&#xff0c;就成了系统的一部分&#xff0c;用户不必自己安装&#xff0c;当然也卸…

【Pytorch神经网络实战案例】08 识别黑白图中的服装图案(Fashion-MNIST)

1 Fashion-MNIST简介 FashionMNIST 是一个替代 MNIST 手写数字集 的图像数据集。 它是由 Zalando&#xff08;一家德国的时尚科技公司&#xff09;旗下的研究部门提供。其涵盖了来自 10 种类别的共 7 万个不同商品的正面图片。 FashionMNIST 的大小、格式和训练集/测试集划分与…

PHP list的赋值

List右边的赋值对象是一个以数值为索引的数组&#xff0c;左边的变量的位置和赋值对象的键值一一对应&#xff0c;有些位置的变量可以省略不写。非末尾的被赋值变量省略时&#xff0c;分隔的逗号不能省略。左边变量被赋值的顺序是从右到左的。 1 list($a, ,$b,$c[],$c[]) [1,2…

Pyscript,创建一个能执行crud操作的网页应用

目录 实现一个添加邀请客人名单的功能 循序渐进&#xff0c;逐步实现&#xff1a; 输入客人名称&#xff0c;按下enter键添加客人名单点击客人名单在名单上添加或者取消添加删除线&#xff0c;表示已经检查客人到场或未到场 checkbox&#xff0c;点击客人名单或者点击checkb…

爬虫实战学习笔记_1 爬虫基础+HTTP原理

1 爬虫简介 网络爬虫&#xff08;又被称作网络蜘蛛、网络机器人&#xff0c;在某些社区中也经常被称为网页追逐者)可以按照指定的规则&#xff08;网络爬虫的算法&#xff09;自动浏览或抓取网络中的信息。 1.1 Web网页存在方式 表层网页指的是不需要提交表单&#xff0c;使…

LeetCode | HouseCode 算法题

题目&#xff1a; You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it…

爬虫实战学习笔记_2 网络请求urllib模块+设置请求头+Cookie+模拟登陆

1 urllib模块 1.1 urllib模块简介 Python3中将urib与urllib2模块的功能组合&#xff0c;并且命名为urllib。Python3中的urllib模块中包含多个功能的子模块&#xff0c;具体内容如下。 urllib.request&#xff1a;用于实现基本HTTP请求的模块。urlb.error&#xff1a;异常处理…

Python解决多个进程服务重复运行定时任务的问题

记录多实例服务定时任务出现运行多次的问题 问题&#xff1a;web项目运行多个实例时&#xff0c;定时任务会被执行多次的问题 举例来说 我使用库APScheduler排定了一个定时任务taskA在每天的晚上9点需要执行一次&#xff0c;我的web服务使用分布式运行了8个实例&#xff0c;于…

java----IO和NIO的区别

概念&#xff1a;NIO即New IO&#xff0c;这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的&#xff0c;但实现方式不同&#xff0c;NIO主要用到的是块&#xff0c;所以NIO的效率要比IO高很多。在Java API中提供了两套NIO&#xff0c;一套是针对标准输入输出NIO&#xf…

【Pytorch神经网络理论篇】 11 卷积网络模型+Sobel算子原理

同学你好&#xff01;本文章于2021年末编写&#xff0c;已与实际存在较大的偏差&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)…