• [博文鉴赏] 低资源环境中的扩散模型优化:减少计算资源的生成方法
    低资源环境中的扩散模型优化:减少计算资源的生成方法在人工智能生成内容(AIGC)领域,扩散模型(Diffusion Models)凭借其卓越的生成能力,成为了近年来备受关注的生成模型之一。尽管其在图像生成、文本生成等领域表现出了极大的潜力,但扩散模型的计算开销较大,这使得其在低资源环境中应用时遇到了巨大的挑战。本文将探讨在低资源环境下,如何优化扩散模型的计算资源使用,减少其对硬件的依赖,并给出优化方法和代码实现。1. 扩散模型概述扩散模型是一种通过反向扩散过程生成数据的模型。其基本思想是将数据映射到高斯噪声空间,再通过一系列步骤逐渐去噪恢复生成样本。这一过程需要经过多个反向步骤,通常需要大量计算资源。1.1 扩散模型的优点和局限性优点:扩散模型能够生成高质量的数据,尤其是在生成图像、视频等任务中,具有竞争力的性能。通过噪声逐步去除的方式,生成的样本质量通常较高,避免了像生成对抗网络(GAN)中可能出现的训练不稳定性问题。局限性:扩散模型的生成过程需要经过大量的时间步(通常为几十到上百步),每一步都需要进行计算,计算资源需求高。需要的大量样本和高精度的计算使得扩散模型难以在低资源设备上运行。2. 低资源环境下的优化目标在低资源环境下,优化扩散模型的目标主要是减少其计算开销,并提高效率。具体来说,可以从以下几个方面进行优化:减少扩散步骤的数量:减少反向去噪的步骤数,从而减少计算量。模型压缩:通过模型剪枝、量化等技术,减小模型的大小,降低内存和计算需求。改进噪声调度:通过优化噪声调度,使得生成过程更加高效,减少每一步的计算量。硬件加速:在低资源环境中,通过量化、低精度计算等手段加速计算过程。3. 优化方法与技术3.1 减少扩散步骤的数量扩散模型通常需要进行多达几十个时间步的反向去噪,每一个时间步的计算量都很大。减少扩散步骤的数量是降低计算开销的直接方法。为了保证生成效果,我们可以通过以下几种方法优化:使用少量的反向步骤:通过实验调优,只保留最有效的几个步骤,从而大大减少计算时间。学习优化噪声调度:噪声调度控制了扩散过程中每一步的噪声强度,通过训练一个噪声调度函数来选择性地跳过一些计算量大的步骤。以下是减少扩散步骤的简单代码实现:import torch import torch.nn.functional as F class DiffusionModel(torch.nn.Module): def __init__(self, denoise_fn, num_steps=1000): super().__init__() self.denoise_fn = denoise_fn self.num_steps = num_steps def forward(self, x, timesteps): for t in range(self.num_steps): x = self.denoise_fn(x, timesteps) return x def optimize_diffusion(self, x, timesteps, optimized_steps=10): # 在此示例中,我们只用少量的步骤 for t in range(optimized_steps): x = self.denoise_fn(x, timesteps) return x # 示例使用 denoise_fn = lambda x, t: x # 简单的去噪函数示例 model = DiffusionModel(denoise_fn) input_data = torch.randn(1, 3, 64, 64) output_data = model.optimize_diffusion(input_data, timesteps=1000, optimized_steps=10) 3.2 模型压缩与优化扩散模型的计算资源消耗还受到模型大小的影响。通过对模型进行压缩,可以有效地减小内存和计算开销。常见的模型压缩技术包括:剪枝:剪枝可以减少神经网络中的冗余参数,从而减小模型大小并提高计算效率。量化:通过将模型参数从高精度浮点数(例如32位浮点)压缩为较低精度(如8位整数),可以显著降低内存使用和计算需求。知识蒸馏:通过将一个大型模型的知识转移到一个较小的模型中,使得小模型能保持较高的性能。以下是一个简单的量化代码示例:import torch import torch.quantization # 假设你有一个预训练的扩散模型 class SimpleDiffusionModel(torch.nn.Module): def __init__(self): super().__init__() self.conv1 = torch.nn.Conv2d(3, 64, kernel_size=3, padding=1) self.fc1 = torch.nn.Linear(64 * 32 * 32, 1000) self.fc2 = torch.nn.Linear(1000, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = x.view(x.size(0), -1) # 展平 x = F.relu(self.fc1(x)) x = self.fc2(x) return x # 模型量化 model = SimpleDiffusionModel() # 转换为量化模型 model.qconfig = torch.quantization.get_default_qconfig('fbgemm') torch.quantization.prepare(model, inplace=True) torch.quantization.convert(model, inplace=True) # 测试量化模型 input_data = torch.randn(1, 3, 32, 32) output = model(input_data) 3.3 硬件加速除了减少扩散步骤和压缩模型,硬件加速也是优化计算的一个有效方向。低精度计算和硬件加速(如使用GPU的TensorRT、FP16或INT8量化)可以显著提高生成效率。以下是使用TensorRT和PyTorch进行量化加速的示例:import torch import torch.onnx import tensorrt as trt # 将PyTorch模型导出为ONNX torch.onnx.export(model, input_data, "diffusion_model.onnx") # 使用TensorRT优化模型 TRT_LOGGER = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(TRT_LOGGER) network = builder.create_network() parser = trt.OnnxParser(network, TRT_LOGGER) # 解析ONNX模型并构建TensorRT引擎 with open("diffusion_model.onnx", 'rb') as f: parser.parse(f.read()) engine = builder.build_cuda_engine(network) 4. 进一步的优化方向与探索在低资源环境下优化扩散模型的工作并非一蹴而就。尽管通过减少扩散步骤、模型压缩和硬件加速等方法可以在一定程度上减轻计算负担,但仍有多个方向值得深入探索。以下是一些可能的优化路径:4.1 多尺度扩散策略一种潜在的优化方式是通过引入多尺度策略来减少扩散过程的复杂度。在多尺度扩散模型中,生成过程不再依赖于单一尺度的噪声处理,而是通过在不同尺度下进行去噪,逐步从粗略的表示到细致的图像生成。这种方法能够在保持生成质量的同时,减少计算量,因为我们可以在低分辨率的阶段进行快速的去噪,再逐步过渡到高分辨率的细节生成。这种方法的核心思想是利用多尺度图像特征来引导去噪过程。在低分辨率阶段,噪声较大,去噪过程可以较为简化;在高分辨率阶段,图像细节更丰富,去噪任务变得更为复杂。4.2 深度可分离卷积(Depthwise Separable Convolutions)深度可分离卷积是一种计算高效的卷积运算,它将标准卷积分解为两个阶段:深度卷积和逐点卷积。通过这种方式,卷积层的参数量和计算量大大减少。应用到扩散模型中,深度可分离卷积可以替代传统的卷积操作,从而加速生成过程,降低资源消耗。深度可分离卷积在计算资源受限的情况下尤为有用,尤其适用于嵌入式设备和低功耗硬件。其计算复杂度为常规卷积的 O(1/k2)O(1/k^2),其中 kk 是卷积核的大小。以下是将深度可分离卷积应用于扩散模型的代码示例:import torch import torch.nn as nn class DepthwiseSeparableConv(nn.Module): def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1): super(DepthwiseSeparableConv, self).__init__() self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=in_channels) self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1) def forward(self, x): x = self.depthwise(x) x = self.pointwise(x) return x # 示例:在扩散模型中使用深度可分离卷积 class SimpleDiffusionModelWithDWConv(nn.Module): def __init__(self): super(SimpleDiffusionModelWithDWConv, self).__init__() self.conv1 = DepthwiseSeparableConv(3, 64) self.fc1 = nn.Linear(64 * 32 * 32, 1000) self.fc2 = nn.Linear(1000, 10) def forward(self, x): x = torch.relu(self.conv1(x)) x = x.view(x.size(0), -1) # 展平 x = torch.relu(self.fc1(x)) x = self.fc2(x) return x # 测试模型 input_data = torch.randn(1, 3, 32, 32) model = SimpleDiffusionModelWithDWConv() output = model(input_data) 4.3 联合训练与迁移学习在低资源环境中,训练一个新的扩散模型可能会受到计算资源的严重制约。联合训练(Co-training)和迁移学习是两个有效的优化手段,通过利用已有的预训练模型或知识,可以大大减少训练时间和计算资源的消耗。4.3.1 联合训练联合训练方法允许模型在多个任务上进行训练,以共享资源和经验。在扩散模型的应用中,联合训练可以通过同时训练多个相关任务(例如图像生成和图像修复),使得模型能在一个多任务框架下学习,从而减少所需的计算资源。4.3.2 迁移学习迁移学习通过将一个已经训练好的模型(通常是大规模数据集上训练的)迁移到目标任务上,可以显著减少训练时间和计算资源。例如,通过迁移学习,我们可以使用一个大规模数据集上训练的扩散模型的权重,来初始化一个新的扩散模型,并只在特定的低资源数据集上微调网络。以下是一个简单的迁移学习的代码示例,假设我们已经有一个预训练的扩散模型,并在低资源数据集上进行微调:import torch import torch.nn as nn from torchvision import models # 假设我们有一个预训练的模型 pretrained_model = models.resnet18(pretrained=True) # 微调模型 class FineTunedDiffusionModel(nn.Module): def __init__(self): super(FineTunedDiffusionModel, self).__init__() self.features = pretrained_model.conv1 self.fc = nn.Linear(512, 10) # 假设是10类分类任务 def forward(self, x): x = self.features(x) x = torch.flatten(x, 1) x = self.fc(x) return x # 加载低资源数据集,进行微调 model = FineTunedDiffusionModel() optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # 假设已经加载了训练数据 # train_loader = ... # 在低资源环境下微调 # for data, targets in train_loader: # optimizer.zero_grad() # output = model(data) # loss = nn.CrossEntropyLoss()(output, targets) # loss.backward() # optimizer.step() 4.4 自适应计算和混合精度训练自适应计算(Adaptive Computation)和混合精度训练(Mixed Precision Training)是两种近年来越来越流行的优化方法。在低资源环境下,智能选择计算精度和计算量,可以减少计算开销并提高效率。4.4.1 自适应计算自适应计算根据当前任务的难度动态选择计算量。例如,对于容易生成的样本,可以减少计算步骤;而对于难度较高的样本,则可以增加计算步骤。这种方式可以减少不必要的计算资源浪费。4.4.2 混合精度训练混合精度训练利用低精度计算(如FP16)加速计算过程,同时尽量减少精度损失。通过使用低精度计算进行前向传播和反向传播,再使用高精度计算更新模型参数,可以在保证模型性能的同时大大提高计算效率。以下是一个简单的混合精度训练的实现示例:import torch from torch.cuda.amp import autocast, GradScaler # 假设我们有一个简单的扩散模型 model = SimpleDiffusionModelWithDWConv().cuda() optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) scaler = GradScaler() # 假设加载了数据 # train_loader = ... # 混合精度训练 for data, targets in train_loader: data, targets = data.cuda(), targets.cuda() optimizer.zero_grad() # 前向传播时使用混合精度 with autocast(): output = model(data) loss = nn.CrossEntropyLoss()(output, targets) # 反向传播并更新参数 scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() 5. 未来展望低资源环境下的扩散模型优化仍然面临许多挑战,但随着计算硬件的发展、算法创新和技术进步,未来在嵌入式设备、移动设备和边缘计算等资源受限场景中的应用前景广阔。通过采用上述优化策略,结合新的算法思路和硬件加速技术,扩散模型将在低资源环境中发挥更大的潜力,并为更多应用场景提供支持。总结在低资源环境中,扩散模型的优化是一个重要的研究方向。扩散模型在生成任务中具有强大的能力,但其计算资源需求通常较高,这使得它们在资源受限的设备上面临挑战。本文探讨了多种优化扩散模型的方法,旨在减少计算负担,并提高效率,使得这些模型能够在低资源环境下运行。主要优化方法包括:减少扩散步骤的数量:通过优化扩散步骤数目,减少每一步的计算量,从而提升生成速度和降低计算需求。模型压缩与优化:通过深度可分离卷积、剪枝、量化等技术减少模型的参数量,从而减小内存占用和计算复杂度。硬件加速:利用低精度计算(如FP16、INT8量化)和硬件加速(如GPU、TensorRT等)来提高计算效率。多尺度扩散策略:通过多尺度的生成策略,在不同分辨率下逐步去噪,减少计算量并加速生成过程。联合训练与迁移学习:通过迁移学习或联合训练方法利用已有的模型和知识,减少低资源环境下训练的时间和计算资源需求。自适应计算和混合精度训练:通过根据任务难度动态调整计算量,和使用混合精度训练,进一步提升计算效率。未来展望:尽管当前的优化方法已经显著提高了扩散模型在低资源环境中的适用性,但仍有很多值得探索的方向。例如,结合更多的硬件加速技术(如TPU、FPGA等),进一步优化模型的计算图和内存管理;以及通过更多先进的自适应计算和高效的模型架构设计,使得扩散模型能在更广泛的场景中得到应用。随着技术的不断进步,未来扩散模型有望在边缘设备、嵌入式系统和移动设备等资源受限的环境中得到广泛应用,并且能够为实时生成和推理任务提供强大的支持。
  • [行业动态] 华为×Deepseek 行业新闻合集 2月【合集】
    以下是2025年2月华为与DeepSeek合作的行业新闻合集,按技术动态、生态合作、市场影响等维度整理:一、技术动态与产品发布DeepSeek-R1推理服务上线(2月1日)华为推出基于昇腾云服务的DeepSeek-R1推理服务,其自研推理加速引擎显著提升模型性能,支持实时数据分析、智能监控、人机交互等场景,尤其在低延迟场景中表现突出,运行成本较传统GPU降低,助力中小企业智能化转型。DeepSeek系列新模型发布(2月4日-5日)华为昇腾社区上线DeepSeek系列模型(包括R1、V3、V2、Janus-Pro),支持一键部署与昇腾硬件适配。其中:DeepSeek-V3:推理速度较前代提升30%,优化大规模数据处理;DeepSeek-R1:强化低延迟响应,适配智能家居、实时视频分析等场景。模型在自然语言处理(NLP)和计算机视觉(CV)领域表现优异,并计划未来推出更多迭代版本。昇腾云服务适配DeepSeek模型(2月12日)华为云宣布昇腾云服务全面适配DeepSeek系列模型,进一步提升模型在云端的部署效率与稳定性,为企业提供更灵活的AI解决方案。二、生态合作与行业应用国产AI芯片深度合作DeepSeek与华为昇腾等16家国产AI芯片企业达成合作,通过模型压缩与优化技术,将训练成本降至行业标杆的1/10至1/20。昇腾910C芯片的推出进一步强化推理性能,助力国产芯片生态建设。全球企业接入浪潮国内外超30家企业(包括中国三大运营商、华为云、阿里云、英伟达、亚马逊云等)宣布支持DeepSeek模型。开源策略降低AI门槛,推动本地化/私有化IDC部署需求增长。智能手机集成DeepSeek-R1华为、OPPO、荣耀等国产手机厂商接入DeepSeek-R1大模型(6710亿参数),应用于语音助手(如华为“小艺”)、智能交互等功能,提升用户体验与设备竞争力。三、市场影响与行业趋势政策驱动与商业化加速信创国产化政策推动下,华为鸿蒙与DeepSeek成为2025年科技投资主线。DeepSeek通过低成本、高效率的AI平权策略,加速B端(金融、医疗)和C端(教育、政务)应用落地,预计2028年国内AIAgent市场规模达8520亿元。国际竞争与用户增长DeepSeek日活跃用户突破2000万,月活达3370万,但面临美国及部分国家的技术限制。其崛起被视为中国AI产业突破外部封锁的标志性事件,与华为Mate60的国产芯片突破形成呼应。行业生态重构DeepSeek的开源模式与华为昇腾生态的结合,推动IDC服务商、通信设备商(如中兴、紫光股份)及边缘计算领域需求增长,同时降低数据中心能耗压力。四、未来展望技术迭代:华为计划持续优化DeepSeek模型的端侧部署能力,推动多模态交互与强化学习应用。生态扩展:昇腾芯片与DeepSeek的协同将加速国产AI芯片替代进程,构建自主可控的技术生态。全球化挑战:需应对国际政策风险,同时探索海外市场合作机会。
  • [热门活动] 华为云昇腾专区重磅上线,带你入门昇腾AI技术学习与DeepSeek实践
     一、DeepSeek-R1(昇腾算力)立即体验:cid:link_0 二、昇腾专区快速体验:cid:link_1 
  • [其他] 人工智能论坛好文干货合集(2025年02月)
    华为昇腾再放大招!携手开源社区突破AI训练瓶颈,国产算力生态迎来高光时刻_人工智能_华为云论坛AI开发者必看!全国算力平台上线DeepSeek服务,22家云商一键调用,中国大模型弯道超车!_人工智能_华为云论坛大模型文生图的原理【知识普及】_人工智能_华为云论坛多模态融合的概念【知识普及】_人工智能_华为云论坛什么是模型蒸馏【知识普及】_人工智能_华为云论坛【分享交流】DeepSeek 为什么这么火?它与传统的chatGLM、豆包、文心一言、OpenGPT、Kimi 等AI有什么不同?_人工智能_华为云论坛梯度弥散、梯度爆炸和模型退化_人工智能_华为云论坛2个AI gallery_AI开发平台ModelArts_华为云论坛为什么线性模型无法学习异或函数_AI开发平台ModelArts_华为云论坛在人工智能领域,华为昇腾再次展现出强大的技术实力,携手开源社区共同突破AI训练的瓶颈。这一举措不仅推动了国产算力生态的发展,更为AI开发者提供了更为广阔的平台和机遇。全国算力平台推出的DeepSeek服务,为AI开发者提供了便捷的一键调用功能,涵盖了22家云商的资源。这一服务的推出,无疑将加速中国大模型在全球范围内的弯道超车,进一步提升中国在人工智能领域的国际竞争力。同时,华为云论坛也为AI开发者提供了丰富的知识普及内容。从大模型文生图的原理,到多模态融合的概念,再到模型蒸馏的详细介绍,这些内容不仅帮助开发者深入理解人工智能技术的核心原理,还为他们提供了更多创新的灵感和思路。在分享交流环节,DeepSeek的火爆引发了广泛讨论。与传统的chatGLM、豆包、文心一言、OpenGPT、Kimi等AI相比,DeepSeek在算法优化、训练效率、应用效果等方面展现出了独特的优势。这些讨论不仅增进了开发者对DeepSeek的了解,也促进了不同AI技术之间的交流与融合。此外,华为云论坛还关注了人工智能领域的一些技术难题,如梯度弥散、梯度爆炸和模型退化等。这些问题的解决对于提升AI模型的性能和稳定性具有重要意义。在AI开发平台ModelArts方面,华为云论坛也提供了丰富的资源和工具。其中,AI gallery作为ModelArts的重要组成部分,为开发者提供了大量的模型、算法和应用案例。这些资源不仅降低了开发者的学习成本,还为他们提供了更多实践和创新的机会。最后,关于线性模型无法学习异或函数的问题,华为云论坛也进行了深入的探讨。这一问题不仅揭示了线性模型的局限性,也引导开发者思考如何通过改进算法和模型来解决实际问题。综上所述,华为云论坛在人工智能领域提供了丰富的知识和资源,为开发者提供了广阔的学习和交流平台。未来,随着技术的不断进步和应用场景的不断拓展,相信华为云论坛将继续为AI开发者带来更多惊喜和机遇。
  • [其他] 差分卷积在计算机视觉中的应用(2)
    中心差分卷积CDC在人脸活体检测中的应用 [2,3]CDC代码链接: github.com/ZitongYu/CDCVanilla卷积通常直接聚合局部intensity-level的信息,故 1)容易受到外界光照等因素的影响;2)比较难表征细粒度的特征。在人脸活体检测任务中,前者容易导致模型的泛化能力较弱,如在未知的光照环境下测试性能较低;后者会导致难以学到防伪本质的细节信息,如spoof的材质。考虑到空间差分特征具有较强光照不变性,同时也包含更细粒度的spoof线索(如栅格效应,屏幕反射等),借鉴传统LBP的差分思想,我们提出了中心差分卷积(Central difference convolution, CDC)。假定邻域 为3x3区域,公式表达如下:   为了更好同时利用 intensity-level 和 gradient-level 的信息,我们通过超参    及共享卷积可学习的权重,统一了VanillaConv和CDC,而无需额外的可学习参数(和可忽略的计算量)。故更generalized的CDC公式为:  θ控制着差分卷积及Vanilla卷积的贡献,值越大意味着gradient clue占比越重;当θ=0时,就成了Vanilla卷积。文章 [3]中也具体对比了CDC与前人工作Local Binary Convolution [4], Gabor Convolution [5] 和 Self-Attention layer [6],有兴趣的请查阅原文。  本文摘自 小白学视觉 公众号
  • [其他] 差分卷积在计算机视觉中的应用(1)
    1.鼻祖LBP的简单回顾在传统的手工特征中,比较经典的有Oulu提出的 LBP(Local Binary Patterns),即局部二值模式 [1],至今引用已有16000+。最初的LBP是定义在3×3邻域内的,以邻域中心像素为阈值,将相邻的8个像素的灰度值与其进行差分比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,邻域内的8个点经比较可产生8位二进制数(通常转换为十进制数即LBP码,共256种),即得到该邻域中心像素点的LBP值,并用这个值来反映该区域的纹理信息。用公式表示为: LBP算子运算速度快,同时聚合了邻域内的差分信息,对光照变化较为鲁棒;同时也能较好地描述细粒度的纹理信息,故在早期纹理识别,人脸识别等都被广泛应用。下图为人脸图像在做LBP变换后的LBP码图像,可以看出脸部局部纹理特征较好地被表征:本文摘自 小白学视觉 公众号
  • [其他] 基于Pytorch的卷积算子的推导和实现(1)
    积运算与梯度推导本文所涉及的卷积运算是最平凡的卷积运算,不包含stride, padding, dilation, bias等。定义卷积运算Output Input Kernel,其中 为输入, Kernel 为卷积 核, Output Tensor 为输出, 且有 。如何实现卷积?可以先用nn.Unfold将输入的tensor展开,注意Unfold()也是可以指定stride, dilation等参数的,但我们这里不考虑这些,因此只用传入kernel_size,就可以将Input展开为Tensor 的形式。input_unf = nn.Unfold(kernel_size=K)(input)然后通过view将Input转变为Tensor 的形式。input_unf = input_unf.view((B, Cin, -1, M, M))同样通过view将Kernel转变为Tensor 的形式。kernel_view = kernel.view((Cout, Cin, K * K))而输出Output是Tensor 的形式。在这里就可以直接用Einstein求和标记将卷积运算写出来了: 代码为output = torch.einsum("ijklm,njk->inlm", input_unf, kernel_view)如何计算梯度?这部分求导的推导是我自己在草稿纸上完成的,后面经过一些验证应该或许可以保证是正确的。为了能够用Pytorch自带的 gradcheck 来验证backward梯度计算的正确性, 我们有必要对每个输入参数都进行求导, 假设最终的Loss函数结果为 (是一个标量), 我们需要计算对输入Input的导数 以及对卷积核Kernel的导数 。为了方便推导,先不考虑batch和channel,也就是Input, Kernel, Output都是二维的。Kernel的梯度根据链式求导法则我们可以将此导数(偏导)写作式中 已知 (backward过程中会作为参数一直传下去),也就是计算图中当前卷积算子后面的链路所有梯度的累乘,其size与Output一致。那么问题就是求Output对Kernel的偏导, 本文摘自 小白学视觉 公众号  
  • [其他] 基于Pytorch的卷积算子的推导和实现(2)
    前言本文主要有两个目的:推导卷积运算各个变量的梯度公式;学习如何扩展Pytorch算子,自己实现了一个能够forward和backward的卷积算子;首先介绍了计算图的自动求导方法,然后对卷积运算中Kernel和Input的梯度进行了推导,之后基于Pytorch实现了卷积算子并做了正确性检验。本文的代码在这个GitHub仓库:https://github.com/dragonylee/myDL/blob/master/%E6%89%A9%E5%B1%95%E6%B5%8B%E8%AF%95.ipynb。计算图计算图(Computational Graphs)是torch.autograd自动求导的理论基础,描述为一个有向无环图(DAG),箭头的方向是前向传播(forward)的方向,而逆向的反向传播(backward)的过程可以很方便地对任意变量求偏导。为了方便说明,这里举一个简单的例子: 其中 是输入, 是输出。根据链式求导法则我们可得:在Pytorch(Python)里定义上述三个函数:def square(x):    return x ** 2def mul3(x):    return x * 3def mul_(x, y):    return x * y然后用torchviz可视化其复合函数的计算图:x = torch.tensor(3., requires_grad=True, dtype=torch.float)y = torch.tensor(2., requires_grad=True, dtype=torch.float)a = square(x)   # a=x^2b = mul3(a)     # b=3ac = mul_(b, y)  # c=bytorchviz.make_dot(c, {"x": x, "y": y, "c": c}).view()得到如下结果: 忽略“Accumulate”这个操作,在该计算图上的反向求导过程表示如下:这很清晰地展示了计算图的功能,它记录了每一个变量(包括输出、中间变量)的计算函数(可以称之为一个算子,就是图中的方框,入边是输入,出边是输出),从而可以数值计算出相应的导数。实际上,任何变量qqq对ppp求导都可以对两者之间的反向链路进行累乘得到。对输出调用.backward()后,可以查看导数值:c.backward()print(y.grad)print(x.grad)输出结果和上图的计算结果一致。注意在backward过程中非叶子节点可以调用.retain_grad()来记录grad。以前我一直以为自动求导是一个很复杂的操作,没想到一个计算图就非常简洁地实现了,才发现“我以为”的复杂操作其实是形式化的求导…… 本文摘自 小白学视觉 公众号
  • [其他] 基于OpenCV的数字识别系统(5)
    优化一旦确定了数字隔离和预测的两个目标,就需要对算法进行优化,以预测泵的新图像上的数字。在优化的初始阶段,创建了一个简单的Playground应用程序,其中使用了OpenCV提供的一些简单的UI组件。使用这些组件,可以创建一些简单的轨迹栏,以左右滑动并更改不同的值并重新处理图像。围绕该cv2.imshow方法创建了一个小包装程序,该方法可以平铺显示的窗口我们可以加载不同的图像,并在图像处理中尝试变量的不同变化,并确定最佳的组合。自动化在每个图像上测试不同的变量是上手的好方法,但是我们想要一种更好的方法来验证是否更改了一个图像的变量是否会对其他任何图像产生影响。为此,我们想出了针对这些图像进行一些自动化测试的系统。我拍摄了每个测试图像,并将它们放在文件夹中。然后,我用图像中期望的数字来命名每个文件,并用小数点“ A”表示。应用程序可以加载该目录中的每个图像并预测数字,然后将其与文件名中的数字进行比较以确定是否匹配。这使我们可以针对所有不同的图像快速尝试更改。更进一步,我创建了此脚本的不同版本,该脚本将尝试对这组图像进行模糊,阈值等变量的几乎每种组合,并找出最优化的变量集将具有最佳的性能。准确性。该脚本在计算机上花费了相当长的时间才能运行,大约需要7个小时,但是最后提出了一组不同的变量,这些变量在我们手动测试时找不到。结论这是否是任何人实际上都会使用的功能尚待确定,但这在实现某些机器学习概念和使用OpenCV方面是一个有趣的练习。到目前为止,在我们的测试中,应用程序最大的问题是泵显示屏上的眩光。根据泵上的照明和手机的角度,可能会导致某些扫描失效。 本文摘自 小白学视觉 公众号
  • [其他] 基于OpenCV的数字识别系统(4)
    预测有两个等高线轮廓,一个带潜在位数,一个带潜在小数位,我们可以使用这些轮廓边界裁剪图像,并将其输入经过训练的系统中以预测其值。有关此过程的更多信息,请参见“数字培训”部分。查找小数在图像中查找小数点是要解决的另一个问题。由于它很小,有时会连接到它旁边的手指,因此使用我们在手指上使用的方法来确定它似乎有问题。当我们过滤轮廓时,我们收集了可能是十进制的正方形轮廓。从上一步获得经过验证的数字轮廓之后,我们将找到数字的最左x位置和最右x位置,以确定我们期望的小数位数。然后,我们将遍历那些潜在的小数,确定它是否在该空间以及该空间的下半部分,并将其分类为小数。找到小数点后,我们可以将其插入到我们上面预测的数字字符串中。数字培训在机器学习的世界中,解决OCR问题是一个分类问题。我们建立了一组训练有素的数据,例如图像处理中的数字,将它们分类为某种东西,然后使用该数据来匹配任何新图像。一旦基本的图像隔离功能开始工作,我就创建了一个脚本,该脚本可以遍历图像文件夹,运行数字隔离代码,然后将裁剪的数字保存到新文件夹中供我查看。运行完之后,我会有一个未经训练的数字文件夹,然后可以用来训练系统。由于OpenCV已经包含了k近邻(k-NN)实现,因此无需引入任何其他库。为了进行训练,我们浏览了数字作物的文件夹,然后将其放入标有0–9的新文件夹中,因此每个文件夹中都有一个数字的不同版本的集合。我们没有大量的这些图像,但是有足够的证据来证明这是可行的。由于这些数字是相当标准的,我认为我不需要大量训练有素的图像就可以相当准确。k-NN工作原理的基础是,我们将以黑白方式加载每个图像,将该图像存储在每个像素处于打开或关闭状态的数组中,然后将这些打开/关闭像素与特定的数字相关联。然后,当我们要预测一个新图像时,它将找出哪个训练图像与这些像素最匹配,然后向我们返回最接近的值。整理好数字后,将创建一个新的脚本,该脚本将遍历这些文件夹,获取每个图像并将该图像与数字关联。到目前为止,在大多数代码中,一般的图像处理概念在Python和C ++中都应用相同,但是在这里会有细微的差别。在大多数此类应用程序的Python示例中,分类被写入两个文件,一个包含分类,另一个包含该分类的图像内容。通常使用NumPy和标准文本文件完成此操作。但是,由于我想在iOS应用程序上重用该系统,因此我需要想出一种可以拥有跨平台分类文件的方式。当时,我什么都找不到,因此最终编写了一个快速实用程序,该实用程序将从Python中获取分类数据并将其序列化为JSON文件,我可以在OpenCV的FileStorage系统的C ++端使用它。这不漂亮,但是我写了一个简单的MatPython中的序列化方法,它将为OpenCV创建合适的结构以在iOS端读取。
  • [其他] 基于OpenCV的数字识别系统(3)
    轮廓过滤1.现在我们有了许多轮廓,我们需要找出我们关心的轮廓。浏览了一堆气泵的显示和场景后,使用一套适用于轮廓的快速规则。2.收集所有我们将分类为潜在小数的正方形轮廓。3.扔掉任何不是正方形或高矩形的东西。4.使轮廓与某些长宽比匹配。LCD显示屏中的十个数字中有九个数字的长宽比类似于下面的蓝色框高光之一。该规则的例外是数字“ 1”,其长宽比略有不同。通过使用一些样本轮廓,我将0–9!1方面确定为0.6,将1方面确定为0.3。它将使用这些比率和+/-缓冲区来确定轮廓是否是我们想要的东西,并收集这些轮廓。5.对潜在数字应用一组附加规则,在这里我们将确定轮廓边界是否偏离所有其他潜在数字的平均高度或垂直位置。由于数字的大小应相同,并且在相同的Y上对齐,因此我们可以丢弃它认为是数字的任何轮廓,但不能像其他轮廓那样将其对齐和调整大小。  本文摘自 小白学视觉 公众号
  • [其他] 基于OpenCV的数字识别系统(2)
    影像准备在开始图像处理流程之前,我们决定先调整一些图像属性,然后再继续。这有点试验和错误,但注意到,当我们调整图像的曝光度时,可以获得更好的结果。下面是使用Python调整后的图像,相当于曝光(阿尔法)的图像cv::Mat::convertTo这是刚刚在图像垫乘法操作cv2.multiply(some_img, np.array([some_alpha]),灰阶将图像转换为灰度。模糊模糊图像以减少噪点。我们尝试了许多不同的模糊选项,但仅用轻微的模糊就找到了最佳结果。阈值图像转换为黑白图像在下图中,使用cv2.adaptiveThreshold带有cv2.ADAPTIVE_THRES_GAUSSIAN_C选项的方法。此方法采用两个参数,块大小和要调整的常数。确定这两者需要一些试验和错误,更多有关优化部分的内容。填补空白由于大多数燃油泵都使用某种7段LCD显示屏,因此数字中存在一些细微的间隙,无法使用轮廓绘制方法,因此我们需要使这些段看起来相连。在这种情况下,我们将转到erode图像来弥补这些差距。由于大家可能希望使用,所以这似乎向后看,dilate但是这些方法通常适用于图像的白色部分。在我们的案例中,我们正在“侵蚀”白色背景以使数字看起来更大。反转图像在尝试在图像中查找轮廓之前,我们需要反转颜色,因为该findContours方法将找到白色的连接部分,而当前的数字是黑色。在图像上找到轮廓下图显示了我们的原始图像,该图像在上图的每个轮廓上都有包围框。大家可以看到它找到了数字,但也找到了一堆不是数字的东西,因此我们需要将它们过滤掉。 本文摘自 小白学视觉 公众号
  • [其他] 基于OpenCV的数字识别系统(1)
    对于这个项目的我们首先应该编写一个简单的Python应用程序以拍摄汽油泵的图像,然后尝试从中读取数字。OpenCV是用于计算机视觉应用程序的流行的跨平台库。它包括各种图像处理实用程序以及某些机器学习功能。除此之外我们希望可以先使用Python对其进行原型设计,然后将处理代码转换为C ++以在iOS应用程序上运行。目标我们首先要考虑以下两个问题:1.我们可以从图像中分离出数字吗?2.我们可以确定图像代表哪个数字吗?数字分割如何确定图像中的数字有多种方法,但是我提出了使用简单的图像阈值法来尝试查找数字的方法。图像阈值化的基本思想是将图像转换为灰度,然后说灰度值小于某个常数的任何像素,则该像素为一个值,否则为另一个。最后,您得到的二进制图像只有两种颜色,在大多数情况下只是黑白图像。这个概念在OCR应用中非常有效,但是主要问题是决定对该阈值使用什么。我们可以选择一些常量,也可以使用OpenCV选择其他一些选项。我们可以使用自适应阈值而不是使用常数,这将使用图像的较小部分并确定要使用的不同阈值。这在具有不同照明情况的应用中特别有用,特别是在扫描气泵中。将图像设置为阈值后,可以使用OpenCV的findContours方法查找图像中连接了白色像素部分的区域。绘制轮廓后,便可以裁剪出这些区域并确定它们是否可能是数字以及它是什么数字。基本图像处理流程这是我在测试图像处理中使用的原始图像。它有一些眩光点,但是图像相当干净。让我们逐步完成获取此源图像的过程,并尝试将其分解为单个数字。 本文摘自 小白学视觉 公众号
  • 如何在ImageNet-1K上训练视觉基础模型?(4)
    3. Empirical Validation我们在ImageNet-1K的训练集上进行预训练,该数据集包含约120万张图像,分布在1000个类别中。默认情况下,Proteus 是从具有相同patch大小的基础模型中蒸馏出来的。按照DINOv2和 SynCLR的设置,我们在分类任务(ImageNet-1K 和12个细粒度分类数据集)以及密集预测任务(语义分割和深度估计)上评估我们的方法。3.1 Accessing DINOv2DINOv2 在私有的大规模数据集 LVD-142M 上进行训练,我们利用预训练的 DINOv2 作为教师模型,在 ImageNet-1K 上训练一个随机初始化的网络。3.1.1 Target Model: ViT-SProteus-S 在不同任务上明显优于其他baseline方法,并且在训练数据远少于 Oracle 方法 DINOv2-S 的情况下,仅略微落后于后者。3.1.2 Target Model: ViT-B and ViT-L当我们扩大模型规模时,Proteus 与 Oracle 方法 DINOv2 之间的性能差距缩小。Proteus-L 在各项任务上的表现几乎与 DINOv2-L 相匹配。3.1.3 Comparison with Distillation in Supervised LearningProteus 在相似的成本下,在多个方面优于传统的监督训练,提供了一种被基础模型强化的新颖训练方案。3.2 Accessing SynCLR and CLIP我们通过使用其他基础模型 SynCLR 和 CLIP 作为教师网络来测试 Proteus 的泛化能力。SynCLR 通过在未公开的 6 亿张合成数据集进行对比学习而训练得到,而 CLIP 是通过在私有数据集 WIT-400M 上对图像和相应的文本描述进行对比学习获得的。3.3 Ablation on Proxy Dataset3.3.1 Dataset diversity如果我们增加Proxy Dataset的多样性,Proteus 的泛化能力可以得到提升。即使在只有单一图像作为Proxy Dataset的极端情况下,Proteus 仍然表现出很强的鲁棒性。3.3.2 Scaling behavior当我们从每个类别中子采样一部分数据或从总共1000个类别中子采样一部分类别时,Proteus 仍然表现出很强的鲁棒性。这表明即使在更小的数据规模下,也有可能训练基础模型。 本文摘自 小白学视觉 公众号
  • 如何在ImageNet-1K上训练视觉基础模型?(3)
    2. Method在本节我们将介绍Proteus,这是一种简单且通用的框架,用于在“有限”数据(即ImageNet-1K)上训练视觉基础模型。我们首先介绍了在减轻Dataset Bias方面所做的努力,以便Proteus能够通过模仿预训练基础模型的行为,有效地转移其通用的表征。然后,我们提出了包含多层次学习目标的Proxy Task,以确保模型在各种任务中的应用。2.1 Proxy Dataset在常规知识蒸馏的设置中,通常会引入KL divergence Loss来计算学生网络预测结果和教师网络预测结果的相似度,并辅以Cross-Entropy Loss来计算模型预测的概率分布与数据集One-hot Label的匹配程度,来指导模型的优化。从经验上看,这种设计在监督学习情况下效果良好,因为它在ImageNet-1K上表现出色。然而,我们认为这种设置会在以下两个方面阻碍知识传递:(1) Cross-Entropy Loss利用了One-hot Label的信息,可能导致Dataset Bias,因为模型倾向于记住训练图像和类别。这种记忆使得模型在下游评估中难以对未见过的类别进行泛化。(2) Class logits的生成隐性地引入了Dataset Bias,因为中间特征被投影到一个预定义的维度上,例如ImageNet-1K的1000维,这在下游评估中可能会被丢弃。基于这些考虑,我们在Projection head(全连接层)之前进行知识蒸馏,并利用中间特征进行知识传递[11]。2.2 Proxy Task基础模型如DINOv2 [2]旨在学习通用的视觉特征,不仅在高层次的分类任务中表现出色,而且在语义分割等密集预测任务中也表现优异。为了最大化知识传递能力并保证其在各种任务中的应用,我们在三个不同层次的训练目标(即token-level, patch-level, and feature-level)上进行蒸馏,通过模拟教师模型的行为来传递丰富的知识。Token-level Objective:为了学习用于高层次理解的discriminative的特征,我们最小化L2距离,以对齐教师模型和学生模型之间的classification token。Feature-level Objective:尽管token-level的学习目标作为Proxy Task可以获得discriminative的视觉特征,但它无法保证在语义分割或深度估计等密集预测任务上取得良好表现。为了解决这个问题,我们以类似的方式,即最小化教师模型和学生模型feature的L2距离,进行feature-level的知识传递。Patch-level Objective:为了进一步挖掘基础模型中的隐藏知识,我们借鉴Masked Image Modeling [12, 13, 14] 的思想,构建了一个patch-level的学习目标。给定一个图像,我们会生成一个额外的视图,其中部分patch被随机遮掩,然后将其送到学生网络以生成中间特征,并通过最小化教师模型和学生模型patch的L2距离来恢复被遮掩的区域。 本文摘自 小白学视觉 公众号
总条数:7841 到第
上滑加载中