PyTorch中的autocast:混合精度训练的实现原理

PyTorch中的autocast:混合精度训练的实现原理

在深度学习中,尤其是在训练大型模型时,计算资源和显存消耗往往是非常关键的因素。为了优化这些问题,混合精度训练(Mixed Precision Training)应运而生。autocast 是 PyTorch 提供的一个工具,用于自动处理混合精度训练中的数值类型选择,使得计算能在尽量减少精度损失的同时,提升性能。

1. 什么是autocast

autocast 是 PyTorch 中用于启用自动混合精度的上下文管理器。它可以使代码中的指定部分自动选择合适的浮点数精度(例如 float16bfloat16),以提高计算效率并节省显存,同时尽量保持模型的训练精度。

  • 目的:优化性能,减少显存占用。
  • 实现方式:在指定的代码区域内,自动选择使用较低精度(如 float16bfloat16)进行计算。计算结束后,返回高精度(如 float32)以进行梯度更新。

2. autocast如何工作?

工作流程

autocast 基本上是一个上下文管理器(Context Manager),其工作原理如下:

  1. 进入autocast上下文

    • 当代码进入 autocast 上下文时,PyTorch 会自动将相关操作(如矩阵乘法、卷积等)切换到 低精度浮点数(通常为 float16bfloat16),以提高计算速度和节省显存。
  2. 操作类型选择

    • autocast 会根据硬件和设备类型(例如 CUDACPU)自动选择合适的精度。对于 CUDA 设备,通常使用 float16;而对于 CPU 设备,使用 bfloat16
  3. 返回到默认精度

    • 计算完成后,autocast 会退出上下文并将所有变量恢复到 默认精度(通常是 float32)。这对于梯度计算和权重更新至关重要,因为在低精度下进行梯度计算可能会导致数值不稳定或精度损失。
  4. 避免梯度和权重更新中的精度丢失

    • autocast 内部进行的前向传播计算使用低精度(float16bfloat16),但 梯度计算和权重更新 操作仍然在 float32 精度下进行,以保证数值稳定性。
具体代码解析

以下是 PyTorch 中 autocast 的基本使用示例:

import torch
from torch import nn, optim
from torch.cuda.amp import autocast, GradScaler# 创建一个模型和优化器
model = nn.Linear(10, 1).cuda()
optimizer = optim.Adam(model.parameters(), lr=1e-3)# GradScaler 用于 Loss Scaling
scaler = GradScaler()# 假设有一个训练循环
for epoch in range(10):optimizer.zero_grad()# 进入 autocast 上下文with autocast(device_type="cuda"):inputs = torch.randn(32, 10).cuda()  # 输入数据targets = torch.randn(32, 1).cuda()  # 目标数据outputs = model(inputs)loss = nn.MSELoss()(outputs, targets)# 使用 GradScaler 进行 Loss Scaling 和反向传播scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()

3. autocast 代码解析

安装完torch之后,在类似于下面的路径下可以找到源码:[~/anaconda3/envs/xxx/lib/python3.10/site-packages/torch/amp/autocast_mode.py, 源码放到了文末。

我们深入分析autocast的实现代码,理解它是如何工作的:

__enter__方法:

当进入 autocast 上下文时,__enter__ 方法会被调用。此方法完成以下操作:

  • 保存当前的设置

    • 保存设备的 autocast 状态、数据类型(dtype)以及缓存设置。
  • 启用 autocast

    • 通过 torch.set_autocast_enabled() 启用指定设备的 autocast,并设置数据类型(如 float16bfloat16)。
  • 开启缓存

    • 启用或禁用 autocast 的缓存功能,优化计算性能。
def __enter__(self):self.prev_cache_enabled = torch.is_autocast_cache_enabled()self.prev = torch.is_autocast_enabled(self.device)self.prev_fastdtype = torch.get_autocast_dtype(self.device)torch.set_autocast_enabled(self.device, self._enabled)torch.set_autocast_dtype(self.device, self.fast_dtype)  # type: ignore[arg-type]torch.autocast_increment_nesting()torch.set_autocast_cache_enabled(self._cache_enabled)

如果读者对def __enter__(self)函数中的set_autocast_dtype这样的函数实现感兴趣,可以参考笔者的另一篇博客:PyTorch中的__init__.pyi文件:作用与C++实现关系解析

__exit__方法:

当退出 autocast 上下文时,__exit__ 方法会被调用:

  • 恢复原来的设置

    • 恢复原先的 autocast 状态、数据类型以及缓存设置。
  • 清理缓存

    • 在嵌套层级降至 0 时,调用 torch.clear_autocast_cache() 清理缓存,以释放内存。
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any):if torch.autocast_decrement_nesting() == 0:torch.clear_autocast_cache()torch.set_autocast_enabled(self.device, self.prev)torch.set_autocast_dtype(self.device, self.prev_fastdtype)torch.set_autocast_cache_enabled(self.prev_cache_enabled)return False
__call__方法:

此外,autocast 还可以作为装饰器使用:

def __call__(self, func):return autocast_decorator(self, func)

这个方法允许你将 autocast 直接应用到函数上,简化代码结构。

4. 使用 autocast 进行混合精度训练

在训练过程中,autocast 会自动选择适当的精度,以确保高效训练:

  • 前向传播(Forward Pass):大部分操作使用低精度(float16bfloat16)进行加速计算。
  • 反向传播(Backward Pass):梯度计算仍使用 float32 精度,避免由于精度不足引起的数值不稳定。
  • 梯度更新:权重更新在 float32 精度下进行,确保模型稳定收敛。

5. autocastGradScaler的结合

为了进一步提高混合精度训练的稳定性,PyTorch 还提供了 GradScaler,用来进行 Loss Scaling。其目的是防止低精度计算中的梯度溢出或下溢:

  • GradScaler 将损失放大,然后进行反向传播,确保梯度数值保持在合理范围内。
  • 通过 scaler.scale(loss).backward()scaler.step(optimizer) 来执行带有缩放的反向传播和优化器步骤。

总结

  • autocast 是 PyTorch 提供的一种自动混合精度工具,可以在训练过程中自动选择适当的数据类型,从而加速计算和减少显存使用。
  • autocast 在前向传播时使用低精度(如 float16bfloat16),但梯度计算和权重更新始终保持 float32 精度,以保证数值稳定性。
  • 通过与 GradScaler 配合使用,能够确保混合精度训练在节省资源的同时,避免精度丢失或梯度下溢问题。

使用 autocast 使得大规模深度学习模型的训练更高效,同时保持较高的精度和稳定性,特别适用于高性能计算环境中的训练任务。

附录:pytorch源码

class autocast:r"""Instances of :class:`autocast` serve as context managers or decorators thatallow regions of your script to run in mixed precision.In these regions, ops run in an op-specific dtype chosen by autocastto improve performance while maintaining accuracy.See the :ref:`Autocast Op Reference<autocast-op-reference>` for details.When entering an autocast-enabled region, Tensors may be any type.You should not call ``half()`` or ``bfloat16()`` on your model(s) or inputs when using autocasting.:class:`autocast` should wrap only the forward pass(es) of your network, including the losscomputation(s).  Backward passes under autocast are not recommended.Backward ops run in the same type that autocast used for corresponding forward ops.Example for CUDA Devices::# Creates model and optimizer in default precisionmodel = Net().cuda()optimizer = optim.SGD(model.parameters(), ...)for input, target in data:optimizer.zero_grad()# Enables autocasting for the forward pass (model + loss)with torch.autocast(device_type="cuda"):output = model(input)loss = loss_fn(output, target)# Exits the context manager before backward()loss.backward()optimizer.step()See the :ref:`Automatic Mixed Precision examples<amp-examples>` for usage (along with gradient scaling)in more complex scenarios (e.g., gradient penalty, multiple models/losses, custom autograd functions).:class:`autocast` can also be used as a decorator, e.g., on the ``forward`` method of your model::class AutocastModel(nn.Module):...@torch.autocast(device_type="cuda")def forward(self, input):...Floating-point Tensors produced in an autocast-enabled region may be ``float16``.After returning to an autocast-disabled region, using them with floating-pointTensors of different dtypes may cause type mismatch errors.  If so, cast the Tensor(s)produced in the autocast region back to ``float32`` (or other dtype if desired).If a Tensor from the autocast region is already ``float32``, the cast is a no-op,and incurs no additional overhead.CUDA Example::# Creates some tensors in default dtype (here assumed to be float32)a_float32 = torch.rand((8, 8), device="cuda")b_float32 = torch.rand((8, 8), device="cuda")c_float32 = torch.rand((8, 8), device="cuda")d_float32 = torch.rand((8, 8), device="cuda")with torch.autocast(device_type="cuda"):# torch.mm is on autocast's list of ops that should run in float16.# Inputs are float32, but the op runs in float16 and produces float16 output.# No manual casts are required.e_float16 = torch.mm(a_float32, b_float32)# Also handles mixed input typesf_float16 = torch.mm(d_float32, e_float16)# After exiting autocast, calls f_float16.float() to use with d_float32g_float32 = torch.mm(d_float32, f_float16.float())CPU Training Example::# Creates model and optimizer in default precisionmodel = Net()optimizer = optim.SGD(model.parameters(), ...)for epoch in epochs:for input, target in data:optimizer.zero_grad()# Runs the forward pass with autocasting.with torch.autocast(device_type="cpu", dtype=torch.bfloat16):output = model(input)loss = loss_fn(output, target)loss.backward()optimizer.step()CPU Inference Example::# Creates model in default precisionmodel = Net().eval()with torch.autocast(device_type="cpu", dtype=torch.bfloat16):for input in data:# Runs the forward pass with autocasting.output = model(input)CPU Inference Example with Jit Trace::class TestModel(nn.Module):def __init__(self, input_size, num_classes):super().__init__()self.fc1 = nn.Linear(input_size, num_classes)def forward(self, x):return self.fc1(x)input_size = 2num_classes = 2model = TestModel(input_size, num_classes).eval()# For now, we suggest to disable the Jit Autocast Pass,# As the issue: https://github.com/pytorch/pytorch/issues/75956torch._C._jit_set_autocast_mode(False)with torch.cpu.amp.autocast(cache_enabled=False):model = torch.jit.trace(model, torch.randn(1, input_size))model = torch.jit.freeze(model)# Models Runfor _ in range(3):model(torch.randn(1, input_size))Type mismatch errors *in* an autocast-enabled region are a bug; if this is what you observe,please file an issue.``autocast(enabled=False)`` subregions can be nested in autocast-enabled regions.Locally disabling autocast can be useful, for example, if you want to force a subregionto run in a particular ``dtype``.  Disabling autocast gives you explicit control overthe execution type.  In the subregion, inputs from the surrounding regionshould be cast to ``dtype`` before use::# Creates some tensors in default dtype (here assumed to be float32)a_float32 = torch.rand((8, 8), device="cuda")b_float32 = torch.rand((8, 8), device="cuda")c_float32 = torch.rand((8, 8), device="cuda")d_float32 = torch.rand((8, 8), device="cuda")with torch.autocast(device_type="cuda"):e_float16 = torch.mm(a_float32, b_float32)with torch.autocast(device_type="cuda", enabled=False):# Calls e_float16.float() to ensure float32 execution# (necessary because e_float16 was created in an autocasted region)f_float32 = torch.mm(c_float32, e_float16.float())# No manual casts are required when re-entering the autocast-enabled region.# torch.mm again runs in float16 and produces float16 output, regardless of input types.g_float16 = torch.mm(d_float32, f_float32)The autocast state is thread-local.  If you want it enabled in a new thread, the context manager or decoratormust be invoked in that thread.  This affects :class:`torch.nn.DataParallel` and:class:`torch.nn.parallel.DistributedDataParallel` when used with more than one GPU per process(see :ref:`Working with Multiple GPUs<amp-multigpu>`).Args:device_type(str, required):  Device type to use. Possible values are: 'cuda', 'cpu', 'xpu' and 'hpu'.The type is the same as the `type` attribute of a :class:`torch.device`.Thus, you may obtain the device type of a tensor using `Tensor.device.type`.enabled(bool, optional):  Whether autocasting should be enabled in the region.Default: ``True``dtype(torch_dtype, optional):  Data type for ops run in autocast. It uses the default value(``torch.float16`` for CUDA and ``torch.bfloat16`` for CPU), given by:func:`~torch.get_autocast_dtype`, if :attr:`dtype` is ``None``.Default: ``None``cache_enabled(bool, optional):  Whether the weight cache inside autocast should be enabled.Default: ``True``"""def __init__(self,device_type: str,dtype: Optional[_dtype] = None,enabled: bool = True,cache_enabled: Optional[bool] = None,):if not isinstance(device_type, str):raise ValueError(f"Expected `device_type` of type `str`, got: `{type(device_type)}`")if dtype is None:dtype = torch.get_autocast_dtype(device_type)if torch._jit_internal.is_scripting():self._enabled = enabledself.device = device_typeself.fast_dtype = dtypeassert dtype is not Nonereturnself.device = device_typeif not is_autocast_available(self.device):raise RuntimeError(f"User specified an unsupported autocast device_type '{self.device}'")self.custom_backend_name = torch._C._get_privateuse1_backend_name()self.fast_dtype = torch.get_autocast_dtype(self.device)if self.device == self.custom_backend_name:necessary_funcs = ["get_amp_supported_dtype",]message = f"Tried to use AMP with the `{self.custom_backend_name}` backend, but the backend has not "message += "registered a module or  the module miss some necessary funcs. The backend should register "message += "a module by `torch._register_device_module`, and the module must have these funcs: \n"message += "`get_amp_supported_dtype() -> List[torch.dtype]`. \n"assert hasattr(torch, self.custom_backend_name), messageself.custom_device_mod = getattr(torch, self.custom_backend_name)for func in necessary_funcs:assert hasattr(self.custom_device_mod, func), (message + f"But the func `{func}` is missing. \n")self._cache_enabled = torch.is_autocast_cache_enabled()if (enabledand torch.cuda.amp.common.amp_definitely_not_available()and self.device == "cuda"):warnings.warn("User provided device_type of 'cuda', but CUDA is not available. Disabling")enabled = Falseif dtype is not None:self.fast_dtype = dtypeif cache_enabled is not None:self._cache_enabled = cache_enabledif self.device == "cpu":supported_dtype = [torch.bfloat16, torch.float16]if self.fast_dtype not in supported_dtype and enabled:error_message = "In CPU autocast, but the target dtype is not supported. Disabling autocast.\n"error_message += "CPU Autocast only supports dtype of "error_message += (", ".join(str(dtype) for dtype in supported_dtype) + " currently.")warnings.warn(error_message)enabled = Falseelif self.device == "xpu":supported_dtype = [torch.bfloat16, torch.float16]if self.fast_dtype not in supported_dtype:error_message = "In XPU autocast, but the target dtype is not supported. Disabling autocast.\n"error_message += "XPU Autocast only supports dtypes of torch.bfloat16 and torch.float16 currently."warnings.warn(error_message)enabled = Falseelif self.device == "ipu":supported_dtypes = [torch.bfloat16, torch.float16]if self.fast_dtype not in supported_dtypes:error_message = "In IPU autocast, but the target dtype is not supported. Disabling autocast.\n"error_message += "IPU Autocast only supports dtypes of torch.bfloat16 and torch.float16 currently."warnings.warn(error_message)enabled = Falseelif self.device == "hpu":supported_dtype = [torch.bfloat16, torch.float16]if self.fast_dtype not in supported_dtype:error_message = "In HPU autocast, but the target dtype is not supported. Disabling autocast.\n"error_message += "HPU Autocast only supports dtypes of torch.bfloat16 and torch.float16 currently."warnings.warn(error_message)enabled = Falseelif self.device == self.custom_backend_name:supported_dtype = self.custom_device_mod.get_amp_supported_dtype()if self.fast_dtype not in supported_dtype:error_message = f"In {self.custom_backend_name} autocast, but the target dtype is not supported. "error_message += f"Disabling autocast.\n {self.custom_backend_name} Autocast only supports dtypes of "error_message += (", ".join(str(dtype) for dtype in supported_dtype) + " currently.")warnings.warn(error_message)enabled = Falseelif self.device == "cuda":if (enabledand self.fast_dtype == torch.bfloat16and not torch.cuda.is_bf16_supported()):raise RuntimeError("Current CUDA Device does not support bfloat16. Please switch dtype to float16.")elif self.device == "xla":supported_dtype = [torch.float16, torch.bfloat16]if self.fast_dtype not in supported_dtype:error_message = "In XLA autocast, but the target dtype is not supported. Disabling autocast.\n"error_message += ("XLA Autocast only supports dtype of torch.bfloat16 currently.")warnings.warn(error_message)enabled = Falseself._enabled = enableddef __enter__(self):if torch._jit_internal.is_scripting():assert self.fast_dtype is not Nonereturn selfself.prev_cache_enabled = torch.is_autocast_cache_enabled()self.prev = torch.is_autocast_enabled(self.device)self.prev_fastdtype = torch.get_autocast_dtype(self.device)torch.set_autocast_enabled(self.device, self._enabled)torch.set_autocast_dtype(self.device, self.fast_dtype)  # type: ignore[arg-type]torch.autocast_increment_nesting()torch.set_autocast_cache_enabled(self._cache_enabled)def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any):  # type: ignore[override]if torch._jit_internal.is_scripting():return# Drop the cache when we exit to a nesting level that's outside any instance of autocast.if torch.autocast_decrement_nesting() == 0:torch.clear_autocast_cache()torch.set_autocast_enabled(self.device, self.prev)torch.set_autocast_dtype(self.device, self.prev_fastdtype)torch.set_autocast_cache_enabled(self.prev_cache_enabled)return Falsedef __call__(self, func):if torch._jit_internal.is_scripting():return funcreturn autocast_decorator(self, func)

后记

2024年12月31日21点10分于上海, 在GPT4o大模型辅助下完成。

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

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

相关文章

再见2024,你好2025

再见2024&#xff0c;你好2025 1月2月3月4月5~10月11~12月一些收获读书跑步工作 为了让这篇博客不那么平淡&#xff0c;一句话可以总结为&#xff1a;平平无奇的琐碎&#xff0c;没有亮点成果。 也可以数字化概述&#xff1a;涨了1万粉&#xff0c;赚了10万&#xff0c;跑步300…

阴阳师の新手如何速刷5个SP/SSR?!(急速育成)

目标&#xff1a;攒5个SP/SSR式神&#xff0c;参与急速育成&#xff0c;省四个黑蛋&#xff08;想要快速升级技能而且经常上场的式神在攒够5个式神前先不升级&#xff09;【理论上组成&#xff1a;10蓝40蓝预约召唤福利20修行or抽卡】 关键点&#xff1a;蓝票&#xff0c;新手…

Kerberos用户认证-数据安全-简单了解-230403

hadoop安全模式官方文档&#xff1a;https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/SecureMode.html kerberos是什么 kerberos是计算机网络认证协议&#xff0c;用来在非安全网络中&#xff0c;对个人通信以安全的手段进行身份认证。 概念&#…

第 29 章 - ES 源码篇 - 网络 IO 模型及其实现概述

前言 本文介绍了 ES 使用的网络模型&#xff0c;并介绍 transport&#xff0c;http 接收、响应请求的代码入口。 网络 IO 模型 Node 在初始化的时候&#xff0c;会创建网络模块。网络模块会加载 Netty4Plugin plugin。 而后由 Netty4Plugin 创建对应的 transports&#xff0…

SQL 基础教程 - SQL SELECT 语句

SQL SELECT DISTINCT 语句 SELECT DISTINCT 语句用于返回唯一不同的值。 在表中&#xff0c;一个列可能会包含多个重复值&#xff0c;有时您也许希望仅仅列出不同&#xff08;distinct&#xff09;的值。 DISTINCT 关键词用于返回唯一不同的值。 SQL SELECT DISTINCT 语法 …

计算机网络基础知识(7)中科大郑铨老师笔记

协议层次及服务模型 计算机网络的分层设计方法&#xff0c;将复杂的网络功能分解为多个层次&#xff0c;每一层实现特定的功能。 互联网中的TCP/IP协议族&#xff0c;包括物理层、链 路层、网络层、传输层和应用层的功能。然后&#xff0c;数据传输的 过程&#xff0c;从应用层…

Microsoft word@【标题样式】应用不生效(主要表现为在导航窗格不显示)

背景 随笔。Microsoft word 2013基础使用&#xff0c;仅做参考和积累。 问题 Microsoft word 2013&#xff0c;对段落标题文字应用【标题样式】不生效&#xff08;主要表现为在导航窗格不显示&#xff09;。 图1 图2 观察图1和图2&#xff0c;发现图1的文字在应用【标题一】样…

TP 钱包插件版本的使用

目前 TokenPocket 的几个平台中&#xff0c;以 ios 和 安卓版本最为常见&#xff0c;其实很少有人知道&#xff0c;浏览器上有一个插件版本的 Tp, 用电脑多的话&#xff0c;这也是一个挺好的选择。 最新版本现在支持Chrome、Brave 浏览器、Edge&#xff08;Firefox及Opera正在…

微信流量主挑战:三天25用户!功能未完善?(新纪元4)

&#x1f389;【小程序上线第三天&#xff01;突破25用户大关&#xff01;】&#x1f389; 嘿&#xff0c;大家好&#xff01;今天是我们小程序上线的第三天&#xff0c;我们的用户量已经突破了25个&#xff01;昨天还是16个&#xff0c;今天一觉醒来竟然有25个&#xff01;这涨…

【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错

一、问题原因 1.安卓安全性变更 Android 12 的安全性变更&#xff0c;Google 引入了更严格的 PendingIntent 安全管理&#xff0c;强制要求开发者明确指定 PendingIntent 的可变性&#xff08;Mutable&#xff09;或不可变性&#xff08;Immutable&#xff09;。 但是&#xf…

打印进度条

文章目录 1.Python语言实现(1)黑白色(2)彩色&#xff1a;蓝色 2.C语言实现(1)黑白颜色(2)彩色版&#xff1a;红绿色 1.Python语言实现 (1)黑白色 import sys import timedef progress_bar(percentage, width50):"""打印进度条:param percentage: 当前进度百分比…

ubuntu 使用samba与windows共享文件[注意权限配置]

在Ubuntu上使用Samba服务与Windows系统共享文件&#xff0c;需要正确配置Samba服务以及相应的权限。以下是详细的步骤&#xff1a; 安装Samba 首先&#xff0c;确保你的Ubuntu系统上安装了Samba服务。 sudo apt update sudo apt install samba配置Samba 安装完成后&#xff0c…

数据结构(哈希表)

背景 在对数据的日常处理中&#xff0c;查找是一项基本操作。通常&#xff0c;查找算法都是基于对比的&#xff0c;比如在一条链表中有n个节点&#xff0c;要找到其中的某个节点&#xff0c;最基本的思路就是从头到尾依次遍历每个节点&#xff0c;依次对比每个节点是否是想要的…

【每日学点鸿蒙知识】模拟器开启网络、长时任务、兼容性测试支持、丢帧定位、SO中访问rawfile等

1、模拟器如何开启网络&#xff1f; 模拟器使用的是电脑本身的网络&#xff0c;不通过代理即可访问网络。 2、创建子window后&#xff0c;锁屏很短时间内&#xff0c;应用会被杀死&#xff1f; 没开长时任务&#xff0c;锁屏和退后台保活要开长时任务。 应用退至后台后&…

如何解决Eigen和CUDA版本不匹配引起的错误math_functions.hpp: No such file or directory

Apollo9针对RTX40的docker环境里的Eigen库版本是3.3.4&#xff0c;CUDA是11.8: 编译我们自己封装模型的某些component代码时没问题&#xff0c;编译一个封装occ模型的component代码时始终报错: In file included from /usr/include/eigen3/Eigen/Geometry:11:0, …

Mac连接云服务器工具推荐

文章目录 前言步骤1. 下载2. 安装3. 常用插件安装4. 连接ssh测试5. 连接sftp测试注意&#xff1a;ssh和sftp的区别注意&#xff1a;不同文件传输的区别解决SSL自动退出 前言 Royal TSX是什么&#xff1a; Royal TSX 是一款跨平台的远程桌面和连接管理工具&#xff0c;专为 mac…

python修改ppt中的文字部分及插入图片

批量修改ppt中的某个模块&#xff0c;或者批量制作奖状等场景会用到&#xff1b; import os import pandas as pd from pptx import Presentation from pptx.util import Inchesfilepath/Users/kangyongqing/Documents/kangyq/202303/分析模版/批量制作/file1时段预警_副本.pp…

从0到机器视觉工程师(一):机器视觉工业相机总结

目录 相机的作用 工业相机 工业相机的优点 工业相机的种类 工业相机知名品牌 光源与打光 打光方式 亮暗场照明 亮暗场照明的应用 亮暗场照明的区别 前向光漫射照明 背光照明 背光照明的原理 背光照明的应用 同轴光照明 同轴光照明的应用 总结 相机的作用 相机…

gesp(C++一级)(7)洛谷:B3863:[GESP202309 一级] 小明的幸运数

gesp(C一级)&#xff08;7&#xff09;洛谷&#xff1a;B3863&#xff1a;[GESP202309 一级] 小明的幸运数 题目描述 所有个位数为 k k k 的正整数&#xff0c;以及所有 k k k 的倍数&#xff0c;都被小明称为“ k k k 幸运数”。小明想知道正整数 L L L 和 R R R 之间&a…

风力涡轮机缺陷检测数据集,86.6%准确识别率,11921张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注

风力涡轮机缺陷检测数据集&#xff0c;86.6&#xff05;准确识别率&#xff0c;11921张图片&#xff0c;支持yolo&#xff0c;PASICAL VOC XML&#xff0c;COCO JSON格式的标注 数据集下载 yolov11&#xff1a; https://download.csdn.net/download/pbymw8iwm/90206849 yolov…