当前位置: 首页 > news >正文

【PyTorch】动态调整学习率 torch.optim.lr_scheduler.StepLR 调度器

文章目录

  • 1. torch.optim.lr_scheduler.StepLR 官方文档详解
  • 2. 使用示例
    • 2.1 官方提供使用示例
    • 2.2 自己写代码测试方法
      • 2.2.1 get_last_lr() 方法
      • 2.2.2 state_dict() 方法
      • 2.2.3 load_state_dict() 保存和加载调度器
  • 3. 思考
    • 3.1 为什么需要state_dict()
    • 3.2 get_lr() 与 get_last_lr() 的输出不一致问题

在深度学习中,学习率调度器(Learning Rate Scheduler) 是用来动态调整学习率的工具。它的主要目的是在训练过程中自动调整学习率,以提高训练的效率和效果。之所以称其为“调度器”,是因为它控制着学习率的调整和更新,类似于调度一个过程或者任务,它按照某种策略和规则来“调度”学习率,本文将详细介绍pytorch中动态调整学习率方法之一 torch.optim.lr_scheduler.StepLR

官方文档链接:
https://pytorch.ac.cn/docs/stable/generated/torch.optim.lr_scheduler.StepLR.html#torch.optim.lr_scheduler.StepLR

1. torch.optim.lr_scheduler.StepLR 官方文档详解

官方文档定义:

class torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1, verbose='deprecated')

每隔 step_size 个 epochs 将每个参数组的学习率衰减 gamma 倍。
请注意,这种衰减可能与来自此调度程序外部的学习率的其他更改同时发生。当 last_epoch=-1 时,将初始 lr 设置为 lr。

参数:

  • o p t i m i z e r optimizer optimizer (优化器) : 包装的优化器
  • s t e p _ s i z e ( i n t ) step\_size(int) step_size(int) : 学习率衰减周期
  • g a m m a ( f l o a t ) gamma (float) gamma(float) : 学习率衰减的乘法因子, 默认值:0.1
  • l a s t _ e p o c h ( i n t ) last\_epoch (int) last_epoch(int) : 最后一个 epoch 的索引, 默认值:-1 表示从头开始
  • v e r b o s e ( b o o l ∣ s t r ) verbose (bool | str) verbose(boolstr): 如果为 True,则为每次更新打印一条消息到标准输出, 默认值:False。

注意:

  • 自版本 2.2 起不推荐使用: v e r b o s e verbose verbose 已弃用。请使用 g e t _ l a s t _ l r ( ) get\_last\_lr() get_last_lr()访问学习率

其它:

  • g e t _ l a s t _ l r ( ) get\_last\_lr() get_last_lr() : 返回当前调度程序计算的最后一个学习率, 返回类型 L i s t [ f l o a t ] List[float] List[float]
  • g e t _ l r ( ) get\_lr() get_lr() : 计算每个组的学习率
  • l o a d _ s t a t e _ d i c t ( s t a t e _ d i c t ) load\_state\_dict(state\_dict) load_state_dict(state_dict) : 加载调度程序的状态,参数: s t a t e _ d i c t ( d i c t ) state\_dict (dict) state_dict(dict) 调度程序状态,应为 s t a t e _ d i c t ( ) state\_dict() state_dict() 调用返回的对象。
  • p r i n t _ l r ( i s _ v e r b o s e , g r o u p , l r , e p o c h = N o n e ) print\_lr(is\_verbose, group, lr, epoch=None) print_lr(is_verbose,group,lr,epoch=None) : 显示当前学习率。
  • s t a t e _ d i c t ( ) state\_dict() state_dict() : 将调度程序的状态作为 d i c t dict dict 返回,它包含 s e l f . _ _ d i c t _ _ self.\_\_dict\_\_ self.__dict__ 中每个变量的条目,这些变量不是优化器。
  • s t e p ( e p o c h = N o n e ) step(epoch=None) step(epoch=None) : 执行一步操作,即更新一次学习率

注意:

  • 自版本 2.4 起不推荐使用: p r i n t _ l r ( ) print\_lr() print_lr() 已弃用。请使用 g e t _ l a s t _ l r ( ) get\_last\_lr() get_last_lr() 访问学习率。

2. 使用示例

2.1 官方提供使用示例

  • 假设初始 l r = 0.05 lr = 0.05 lr=0.05 s t e p _ s i z e = 30 step\_size=30 step_size=30 g a m m a = 0.1 gamma=0.1 gamma=0.1,即每 30 个 epoch后,将学习率乘以 0.1
  • e p o c h < 30 epoch< 30 epoch<30 时, l r = 0.05 lr = 0.05 lr=0.05 ,即 l r = l r lr=lr lr=lr
  • 30 < = e p o c h < 60 30 <= epoch < 60 30<=epoch<60 l r = 0.005 lr = 0.005 lr=0.005,即 l r n e w = l r o l d ∗ g a m m a = 0.05 ∗ 0.1 = 0.005 lr_{new}=lr_{old}*gamma=0.05*0.1=0.005 lrnew=lroldgamma=0.050.1=0.005
  • 60 < = e p o c h < 90 60 <= epoch < 90 60<=epoch<90 l r = 0.0005 lr = 0.0005 lr=0.0005,即 l r n e w = l r o l d ∗ g a m m a = 0.005 ∗ 0.1 = 0.0005 lr_{new}=lr_{old}*gamma=0.005*0.1=0.0005 lrnew=lroldgamma=0.0050.1=0.0005
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05     if epoch < 30
# lr = 0.005    if 30 <= epoch < 60
# lr = 0.0005   if 60 <= epoch < 90
# ...
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):train(...)validate(...)scheduler.step()

2.2 自己写代码测试方法

2.2.1 get_last_lr() 方法

  • 用于返回调度器计算的 最后一个学习率。这个学习率是在调度器(scheduler)调整之后的当前学习率
  • 如果优化器中有多个参数组, g e t _ l a s t _ l r ( ) get\_last\_lr() get_last_lr() 返回的是一个列表,每个元素对应一个参数组的学习率
  • 如果优化器中只有一个参数组, g e t _ l a s t _ l r ( ) get\_last\_lr() get_last_lr() 返回一个只有一个元素的列表
import torch
from torch import nn
from torch import optim
net = nn.Linear(3,4)
def train():optimizer = optim.Adam(net.parameters(), lr=0.1)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 1, gamma=0.1)for epoch in range(0, 10):print(epoch, scheduler.get_last_lr())optimizer.step()scheduler.step()
if __name__ == "__main__":train()

代码输出:

0 [0.1]
1 [0.010000000000000002]
2 [0.0010000000000000002]
3 [0.00010000000000000003]
4 [1.0000000000000004e-05]
5 [1.0000000000000004e-06]
6 [1.0000000000000005e-07]
7 [1.0000000000000005e-08]
8 [1.0000000000000005e-09]
9 [1.0000000000000006e-10]

2.2.2 state_dict() 方法

  • s t a t e _ d i c t ( ) state\_dict() state_dict() 是一个非常重要的函数,它能够返回一个包含模型或优化器状态的字典(dict)。对于学习率调度器来说, s t a t e _ d i c t ( ) state\_dict() state_dict() 返回调度器的状态,包括它的参数和变量,用于保存和恢复调度器的状态等

代码示例:

import torch
from torch import nn
from torch import optimnet = nn.Linear(3,4)def train():optimizer = optim.Adam(net.parameters(), lr=0.1)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 1, gamma=0.1)for epoch in range(10):print(epoch, scheduler.state_dict())optimizer.step()scheduler.step()if __name__ == "__main__":train()

代码输出:

0 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 0, 'verbose': False, '_step_count': 1, '_get_lr_called_within_step': False, '_last_lr': [0.1]}
1 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 1, 'verbose': False, '_step_count': 2, '_get_lr_called_within_step': False, '_last_lr': [0.010000000000000002]}   
2 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 2, 'verbose': False, '_step_count': 3, '_get_lr_called_within_step': False, '_last_lr': [0.0010000000000000002]}  
3 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 3, 'verbose': False, '_step_count': 4, '_get_lr_called_within_step': False, '_last_lr': [0.00010000000000000003]} 
4 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 4, 'verbose': False, '_step_count': 5, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000004e-05]} 
5 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 5, 'verbose': False, '_step_count': 6, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000004e-06]} 
6 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 6, 'verbose': False, '_step_count': 7, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000005e-07]} 
7 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 7, 'verbose': False, '_step_count': 8, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000005e-08]} 
8 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 8, 'verbose': False, '_step_count': 9, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000005e-09]} 
9 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 9, 'verbose': False, '_step_count': 10, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000006e-10]}

输出详解:

  • step_size: 该值表示每隔多少个 epoch 学习率就会发生变化。在例子中, s t e p _ s i z e = 1 step\_size = 1 step_size=1,意味着每经过 1 个 epoch,学习率都会更新一次
  • gamma: 这是学习率更新的衰减因子。每次调用 s c h e d u l e r . s t e p ( ) scheduler.step() scheduler.step() 时,当前的学习率将会乘以 g a m m a gamma gamma。例子中, g a m m a = 0.1 gamma = 0.1 gamma=0.1,意味着每次更新学习率时,学习率将减少为原来的 10%
  • base_lrs: 这是每个参数组的初始学习率(在调度器调整之前的学习率)。这里的 [ 0.1 ] [0.1] [0.1]表示模型的初始学习率是 0.1。如果有多个参数组,这里会是一个列表,列出每个参数组的初始学习率
  • last_epoch: 这是上一个 epoch 的编号,用来确定学习率更新时的参考点。 l a s t _ e p o c h = 0 last\_epoch = 0 last_epoch=0 表示调度器刚刚初始化,学习率还没有更新过。通常,last_epoch 用来恢复训练时从哪个 epoch 开始更新学习率
  • verbose: 该参数控制调度器是否在学习率更新时打印详细信息。 v e r b o s e = F a l s e verbose = False verbose=False 表示调度器在更新学习率时不会打印信息。如果设置为 T r u e True True,则每次更新学习率时都会打印一条日志。
  • _step_count: 这个内部变量跟踪调度器已经调用了多少次 step()。在例子中, _ s t e p _ c o u n t = 1 \_step\_count = 1 _step_count=1,表示调度器已经调用过一次 s t e p ( ) step() step(),即更新过一次学习率
  • _get_lr_called_within_step: 是一个内部标志,表示是否在 step() 方法内部调用了 get_lr()。通常不需要关注这个值,它帮助调度器管理内部逻辑
  • _last_lr: 这是调度器最近一次计算的学习率。这个列表保存了每个参数组的学习率。在你的例子中, _ l a s t _ l r = [ 0.1 ] \_last\_lr = [0.1] _last_lr=[0.1],表示当前学习率是 0.1。这会在 scheduler.step() 后更新为新的学习率。

2.2.3 load_state_dict() 保存和加载调度器

可以将 state_dict() 保存到文件中,然后在以后恢复。如下是一个保存和加载学习率调度器状态的例子:

保存调度器状态:

# 保存调度器的 state_dict
torch.save(scheduler.state_dict(), 'scheduler_state.pth')

加载调度器状态:

# 加载调度器的 state_dict
scheduler.load_state_dict(torch.load('scheduler_state.pth'))

通过这种方式,可以在训练中断后恢复学习率调度器的状态,并继续进行训练。

保存调度器状态示例:

epoch = 5 时,保存调度器状态:

import torch
from torch import nn
from torch import optim
net = nn.Linear(3,4)
def train():optimizer = optim.Adam(net.parameters(), lr=0.1)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 1, gamma=0.1)for epoch in range(10):if epoch == 5:torch.save(scheduler.state_dict(), 'scheduler_state.pth')breakoptimizer.step()scheduler.step()if __name__ == "__main__":train()

加载调度器状态示例:

import torch
from torch import nn
from torch import optimnet = nn.Linear(3,4)def train():optimizer = optim.Adam(net.parameters(), lr=0.1)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 1, gamma=0.1)scheduler.load_state_dict(torch.load("scheduler_state.pth"))for epoch in range(3):print(epoch, scheduler.state_dict())optimizer.step()scheduler.step()if __name__ == "__main__":train()

代码输出:

0 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 5, 'verbose': False, '_step_count': 6, '_get_lr_called_within_step': False, '_last_lr': [1.0000000000000004e-06]}
1 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 6, 'verbose': False, '_step_count': 7, '_get_lr_called_within_step': False, '_last_lr': [0.010000000000000002]}
2 {'step_size': 1, 'gamma': 0.1, 'base_lrs': [0.1], 'last_epoch': 7, 'verbose': False, '_step_count': 8, '_get_lr_called_within_step': False, '_last_lr': [0.0010000000000000002]}

可以看到:

  • last_epoch 从 5 开始
  • _step_count 从6 开始
  • _last_lr 从 1e-6 开始

说明是从上次终断的状态继续运行

3. 思考

3.1 为什么需要state_dict()

  • 保存和恢复训练: 当你希望在训练中断后恢复训练时,你可以保存模型和调度器的 state_dict(),然后在恢复时加载它们,确保学习率调度器从上次停止的地方继续工作,而不是从头开始。
  • 调试和分析:通过 state_dict() 可以查看学习率的变化,帮助你调试和分析训练过程中调度器的行为。

3.2 get_lr() 与 get_last_lr() 的输出不一致问题

测试代码:

import torch
from torch import nn
from torch import optimnet = nn.Linear(3,4)def train():optimizer = optim.Adam(net.parameters(), lr=0.1)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 1, gamma=0.1)for epoch in range(3):print(epoch, scheduler.get_lr())print(epoch, scheduler.get_last_lr())print([group["lr"] for group in optimizer.param_groups])print("==========================================")optimizer.step()scheduler.step()if __name__ == "__main__":train()

代码输出:

0 [0.1]
0 [0.1]
[0.1]
==========================================
1 [0.0010000000000000002]
1 [0.010000000000000002]
[0.010000000000000002]
==========================================
2 [0.00010000000000000003]
2 [0.0010000000000000002]
[0.0010000000000000002]
==========================================

不知道为什么从 epoch > 0 之后,get_lr() 每次都比 get_last_lr() 提前一步更新,但是通过查看 optimizer.param_groups 的学习率与 get_last_lr() 一致。

get_lr()函数源码:

def get_lr(self):if not self._get_lr_called_within_step:warnings.warn("To get the last learning rate computed by the scheduler, ""please use `get_last_lr()`.", UserWarning)if (self.last_epoch == 0) or (self.last_epoch % self.step_size != 0):return [group['lr'] for group in self.optimizer.param_groups]return [group['lr'] * self.gammafor group in self.optimizer.param_groups]

我们可以看到在源码中当:if (self.last_epoch == 0) or (self.last_epoch % self.step_size != 0),返回值为[group['lr'] for group in self.optimizer.param_groups], 否则的话返回值为[group['lr'] * self.gamma for group in self.optimizer.param_groups],因此可以很好的解释上面的现象,但是Pytorch为什么要这样做呢??目前没有找到相关资料,可以评论区留言讨论!

get_last_lr() 函数源码:

def get_last_lr(self):""" Return last computed learning rate by current scheduler."""return self._last_lr

相关文章:

【PyTorch】动态调整学习率 torch.optim.lr_scheduler.StepLR 调度器

文章目录 1. torch.optim.lr_scheduler.StepLR 官方文档详解2. 使用示例2.1 官方提供使用示例2.2 自己写代码测试方法2.2.1 get_last_lr() 方法2.2.2 state_dict() 方法2.2.3 load_state_dict() 保存和加载调度器 3. 思考3.1 为什么需要state_dict()3.2 get_lr() 与 get_last_l…...

AIGC drug design 人工智能生成式药物设计:基于 GPT 的 SMILES 生成与应用

人工智能生成式药物设计&#xff1a;基于 GPT 的 SMILES 生成与应用 1. 人工智能生成模型&#xff1a;解密 GPT 的工作原理 目录 引言 1.1 背景介绍 1.2 人工智能生成模型的兴起 1.3 GPT 系列模型的地位与影响 GPT 模型概述 2.1 什么是 GPT 2.2 GPT 的发展历程 2.3 GPT 与其…...

Python面试常见问题及答案4

一、内存管理相关 问题&#xff1a;Python中的垃圾回收机制是如何工作的&#xff1f; 答案&#xff1a;Python主要使用引用计数来进行垃圾回收&#xff0c;当对象的引用计数为0时&#xff0c;该对象就会被垃圾回收器回收。此外&#xff0c;Python还有一个循环垃圾收集器来处理循…...

开启第二阶段---蓝桥杯

一、12.10--数据类型的范围及转化 今天是刚开始&#xff0c;一天一道题 对于这道题我想要记录的是Java中的整数默认是 int 类型&#xff0c;如果数值超出了 int 的范围&#xff0c;就会发生溢出错误。为了避免这个问题&#xff0c;可以将数字表示为 long 类型&#xff0c;方法…...

npm内存溢出

项目过大运行项目内存溢出 报错代码 运行内存溢出 increase-memory-limit ‘“node --max-old-space-size8192”’ 不是内部或外部命令&#xff0c;也不是可运行的程序 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of m…...

回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 CNN-BiGRU,即卷积神经网络(CNN)与双…...

Android系统卡启动问题排查

Android系统启动正常来说会涉及到如下几个过程&#xff1a; 引导加载程序&#xff08;Bootloader&#xff09;Linux内核&#xff08;Kernel&#xff09;&#xff0c;负责硬件抽象、内存管理、进程管理、网络堆栈等init进程 init进程读取init.rc配置文件&#xff0c;用于启动各…...

STP(生成树协议)

STP的基本概念 概述 STP是一个用于局域网中消除环路的协议。运行该协议的设备通过彼此交互信息而发现网络中的环路&#xff0c;并对某些接口进行阻塞以消除环路。STP在网络中运行后会持续监控网络的状态&#xff0c;当网络出现拓扑变更时&#xff0c;STP能够感知并且进行自动…...

【前端面试】随机、结构赋值、博弈题

解构赋值&#xff08;Destructuring Assignment&#xff09;是 JavaScript ES6 引入的一项非常有用的特性&#xff0c;它允许我们快速地从数组或对象中提取值&#xff0c;并将它们赋给变量。这种方式使得代码更加简洁、易读&#xff0c;并且能够减少重复的访问和赋值操作。 1.…...

Volta——开箱即用的Node.js 版本管理工具

Volta volta 是一个较新的 Node.js 版本管理器&#xff0c;旨在简化 Node.js 和其他工具的安装和管理&#xff0c;在 2019 年出世&#xff0c;仍在积极开发中。Volta 采用了与 nvm 不同的方法&#xff1a;它不是管理 Node.js 的多个版本&#xff0c;而是管理项目及其依赖项。当…...

ubuntu 磁盘空间满,找不到占用文件的目录

解决方法&#xff1a; 检查磁盘空间&#xff1a; 执行 df -h 查看各分区磁盘使用情况。 查找大文件或目录&#xff1a; 执行 du -sh /* 2>/dev/null 查找根目录下的大文件或目录&#xff0c;再逐一进入子目录使用相同命令查找。 清理缓存和临时文件&#xff1a; 清理 /t…...

1. 机器学习基本知识(5)——练习题(参考答案)

20.&#x1f517;本章代码笔记&#x1f4d3;链接&#xff08;需要&#x1fa9c;&#xff09;&#xff1a;&#xff08;01_the_machine_learning_landscape.ipynb - Colab (google.com)&#xff09; 如果你不想通过上面的官方网址下载本章的笔记&#xff0c;还可以在本篇博文的…...

spark-sql 备忘录

wordcount sc.textFile("../data/data.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(__).collect 读取json 文件 并通过sql 执行 join 查询 public static void main(String[] args) {SparkSession session SparkSession.builder().master(&qu…...

基于softmax回归的多分类

基于softmax回归的多分类任务是机器学习领域中的一种常见应用。softmax回归,又称多项逻辑回归或多类逻辑回归,是逻辑回归在多分类问题上的推广。以下是对基于softmax回归的多分类任务的详细解释: 一、softmax回归的原理 softmax回归的核心思想是通过softmax函数将输入数据…...

bs4基本运用

1. bs4基本使用 1.1. 简介 bs4的全称为 BeautifulSoup。和lxml一样&#xff0c;是一个html的解析器&#xff0c;主要功能也是解析数据和提取数据 。 本模块作为了解模块&#xff0c;实际开发中很少用这个模块去解析数据&#xff0c;大家可能会想为什么这个模块会逐渐被淘汰&…...

MySQL 时区参数 time_zone 详解

文章目录 前言1. 时区参数影响2. 如何设置3. 字段类型选择 前言 MySQL 时区参数 time_zone 有什么用&#xff1f;修改它有什么影响&#xff1f;如何设置该参数&#xff0c;本篇文章会详细介绍。 1. 时区参数影响 time_zone 参数影响着 MySQL 系统函数还有字段的 DEFAULT CUR…...

Redis - 消息队列 Stream

一、概述 消息队列 定义 消息队列模型&#xff1a;一种分布式系统中的消息传递方案&#xff0c;由消息队列、生产者和消费者组成消息队列&#xff1a;负责存储和管理消息的中间件&#xff0c;也称为消息代理&#xff08;Message Broker&#xff09;生产者&#xff1a;负责 产…...

Docker:国内加速源

阿里云docker加速云&#xff1a; sudo tee /etc/docker/daemon.json <<EOF { “registry-mirrors”: [“https://euf11uji.mirror.aliyuncs.com”] } EOFhttps://docker.mozhu.dev/ sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": [&qu…...

Android Studio更改项目使用的JDK

一、吐槽 过去&#xff0c;在安卓项目中配置JDK和Gradle的过程非常直观&#xff0c;只需要进入Android Studio的File菜单中的Project Structure即可进行设置&#xff0c;十分方便。 原本可以在这修改JDK: 但大家都知道&#xff0c;Android Studio的狗屎性能&#xff0c;再加…...

ubuntu+ros新手笔记(四):gazebo无法加载

以下为ChatGPT 的解决方案&#xff0c;对我来说是可行的&#xff01;&#xff01; 我按照第2步操作就解决辣&#xff01;&#xff01; 我的提问&#xff1a; 在ubuntu 22.04 和ros2 humble环境下&#xff0c;gazebo加载不了 ChatGPT 回答&#xff1a; 在 Ubuntu 22.04 和 …...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...