51c视觉~合集40
我自己的原文哦~ https://blog.51cto.com/whaosoft/12951385
#SparX
港大提出SparX:强化Vision Mamba和Transformer的稀疏跳跃连接机制
本文分享香港大学计算和数据科学学院俞益洲教授及其研究团队发表于 AAAI 2025 的论文——SparX,一种强化 Vision Mamba 和 Transformer 的稀疏跳跃连接机制,性能强大,代码已开源。
论文标题:
SparX: A Sparse Cross-Layer Connection Mechanism for Hierarchical Vision Mamba and Transformer Networks
论文链接:https://arxiv.org/abs/2409.09649
代码链接:https://github.com/LMMMEng/SparX
01 摘要
香港大学计算和数据科学学院俞益洲教授 (https://i.cs.hku.hk/~yzyu/index.html) 及其研究团队开发了一种新型的层间稀疏跳跃连接机制 --- Sparse Cross-Layer Connection Mechanism (SparX),可以有效提升包含 Vision Mamba 和 Transformer 在内的 Vision Backbone 的性能。
不同于常规的 Vision Backbone 通过堆叠相同的基础模块来搭建网络架构,SparX 受到了人类视觉系统中神经节细胞 (Retinal Ganglion Cell) 的启发, 将网络的基础模块分为两种不同的类型:神经节层 (Ganglion Layer) 和常规层(Normal Layer)。
前者具有更高的复杂度和连接度,类似于视觉系统中的神经节细胞,而后者的连接度和复杂度都较低,类似于视觉系统中的常规细胞。通过交叉堆叠 Ganglion Layer 和 Normal Layer 构建了一种新的 Vision Backbone 网络,在图像分类、语义分割和目标检测中展现了强大的性能。
例如,基于 SparX 构建的 Vision Mamba 模型 SparX-Mamba 相较于强大的 VMamba 仍有明显提升:虽然参数量更少,SparX-Mamba-T 在 ImageNet-1K 上的 Top-1 准确率仍超越 VMamba-T 1%。此外,SparX-Mamba 在语义分割和目标检测任务上同样具备突出的性能,展现了 Mamba 模型在学习长距离关联方面的优越性。
02 动机
随着自注意力(Self-attention)和状态空间模型(State Space Models 或 SSMs)在 NLP 任务中的优异表现,许多工作将这些方法成功应用到了视觉领域,例如 Swin-Transformer 和 VMamba。
目前主流的 Vision Backbone 模型的设计策略为构建新的 token mixer,并据此来构建视觉网络。然而,不同层输出的特征具有一定的互补性和冗余度,因此,寻找这些特征之间的互补性,并且移除冗余的特征可以进一步提升网络的表征能力,进而提升性能。
虽然一些先前的工作(例如 DenseNet)已经利用了不同网络层的交互和复用来提升性能,但是 DenseNet 中的稠密连接具有较高的计算复杂度,使其难以直接用于比卷积更加复杂的和 SSM 算子。因此,设计一种高效的神经连接机制来挖掘和利用网络的层间互补性仍然需要进一步探索。
03 方法
以基于 Mamba 的模型为例,在 SparX 中 Ganglion Layer 包含用于提取局部信息的动态位置编码(Dynamic Position Encoding (DPE)),用于实现层间信息交互的 Dynamic Multi-layer Channel Aggregator (DMCA),和用于空间上下文信息建模的视觉状态空间模型(Visual State Space Model 或 VSS),而 Normal Layer 则没有 DMCA 模块。
此外,SparX 引入了两条新的跨层连接规则:
1.Sparse Ganglion Layers 将一组具有均匀间隔的层指定为更加复杂且连接度更高的 ganglion layers,而所有其余层则为复杂度和连接度都较低的 normal layers。为了控制 ganglion layers 的密度,进而控制网络的复杂度和连接度,研究团队引入了一个步长参数 S,即 S=两个最近的 ganglion layers 之间的 normal layers 的层数加一。
此外,该规则定义了两种不同的连接类型:ganglion layer 和 norma layer 之间的内连以及两个 ganglion layers 之间的互连。为了让网络具备强大的层间特征交互且具有高效性,ganglion layer 只与处于自身和最近的前一个 ganglion layer 之间的那些 normal layers 建立内连,但是同时与多个先前的 ganglion layers 建立互连。
这种设计是因为:ganglion layer 可以被视为网络的“信息中心”,从最近的 normal layer 收集信息并与其他 ganglion layers 交换信息。一个简单的例子为:如果一个网络有 8 层并设置 S=2,则 normal layer 的索引为 {1, 3, 5, 7},而 ganglion layers 的索引为 {2, 4, 6, 8}。
2.跨层滑动窗口(Cross-layer Sliding Window)旨在进一步提升网络高效性,其设计背后的动机是:尽管上述层间连接方式具有稀疏性,深层网络仍可能因需要存储和访问大量先前的特征图而产生较高的显存消耗。为此,受启发于经典的空间滑动窗口,引入另一个超参数 M 来限制每个 ganglion layer 仅与先前的 M 个最接近的 ganglion layers 建立互连。
基于这两条新规则,即使没有直接连接,语义信息仍然可以通过相对稀疏的内连和互连从较浅的网络层快速传递到较深的网络层。图 1 展示了一个 SparX (S=2, M=2) 的示例。
▲ 图1. Mamba-based SparX示例
为了选择性地从先前网络层的特征中挖掘有用的特征,从而动态的建模层间交互,研究团队提出了一个简单有效的 DMCA 模块。如下图所示,DMCA 用当前层特征作为 query,用先前层的特征作为 key/value 来构建 channel-wise cross attention。构建 channel attention 的目的是为了更好地进行通道之间的信息交互,从而获得更好的性能。
▲ 图2. DMCA架构图
04 实验结果
图像分类:SparX 在大规模数据集 ImageNet-1K 上表现出了卓越的性能,相较于现有方法,展现出更为出色的性能以及更好的 tradeoff。如表 1 所示,SparX-Mamba-S 仅以大约一半的参数量和 FLOPs 就超越了 VMamba-B 的性能。
如表 2 所示,对 SparX 在 ADE20K 上也进行了全面的评估,其性能在与一些强大的 Vision Backbones 的比较中脱颖而出,并且有着好的 tradeoff。
如表 3 所示,在 COCO 2017 数据集上,SparX 同样展示出了更优的性能。值得注意的是,当使用更加强大的训练条件(3× schedule)时,SparX 展现了更加显著的性能提升。
▲ 表3. COCO目标检测和实例分割性能对比
通用性实验
研究团队用经典的 Swin-Transformer 测试了 SparX 的通用性,为了保持公平对比,micro 设计严格保持了和 Swin 原始设计一致,例如完全相同的 patch embedding 和 token mixer。如表 4 所示,SparX 在不同任务上均取得了显著的性能提升。
▲表4. SparX用于Transformer架构时的性能
消融实验
为了验证 SparX 的有效性,研究团队构建了两种不同的稠密连接模型:1)Dense Ganglion Connections (DGC-Mamba-T):移除跨层滑动窗口(Cross-layer Sliding Window)来消除互连稀疏性;2)DenseNet-style Network (DSN-Mamba-T):完全按照 DenseNet 的策略来构建模型。
如表 5 所示,SparX 在保持最优性能的前提下还具备高效性。
▲ 表5. SparX和Dense Connection的对比
可视化实验
Centered Kernel Alignment (CKA) 分析:不难发现,在表 5 消融实验中,连接度更高的模型(DGC 和 DSN)并没有带来性能提升。为了寻找背后的原因,我们进行了模型的 CKA 分析。
如图 3 所示,VMamba-T 每一层学习到的特征与相邻层非常相似,说明了模型具有大量的特征冗余。此外,DGC 和 DSN 模型可以学习到更加多样化的特征,降低了特征冗余度。与这些方法相比,SparX 不同层的特征更加多样化,从而具有更加强大的特征表达,这也是其性能更好的原因。
▲ 图3. CKA可视化
有效感受野(Effective Receptive Field 或 ERF)分析:如图 4 所示,SparX-Mamba 和其它方法相比具有更大的感受野,进一步说明了 SparX 对模型表征能力的增强效果。
▲ 图4. Effective Receptive Fields可视化
#使用计算机视觉实现自动分拣
计算机视觉分拣系统组成
使用计算机视觉进行自动分拣是一个技术驱动的过程,其中计算机视觉系统用于根据特定特征(例如大小、形状、颜色、纹理、条形码或其他视觉特征)对物品或材料进行识别、分类和排序。这种方法通常用于制造、物流、农业和回收等行业,以提高效率、降低劳动力成本并最大限度地减少错误。
以下是基于计算机视觉的自动分拣系统的关键组件:
- 摄像头和传感器:高速摄像头捕捉物品沿传送带移动的图像或视频。可以使用深度相机、红外相机或激光等其他传感器来捕获详细的对象信息。
- 计算机视觉算法:这些算法分析视觉数据以识别和分类对象。卷积神经网络 (CNN) 或机器学习模型等技术通常是这些系统的基础。
- 分拣机构:执行器、机械臂、喷气机或分流器根据分析将物品物理分类为适当的类别。
计算机视觉分拣系统案例
基于计算机视觉的分拣应用于多个行业。以下是一些示例使用案例。
农业:水果分级和分拣
这种基于计算机视觉的系统可以根据苹果、橙子和香蕉等水果的大小、形状和颜色或其他物理特征对其进行分级。该系统使用摄像头捕捉传送带上水果的图像,分析其质量,并将其分类为优质、标准或不合格等等级。该系统提高了效率,确保了一致性,并减少了分级中的体力劳动。
农业:种子分拣
该种子分拣系统使用高速摄像头和 AI 模型批量识别有缺陷的种子或异物。该系统的分拣机制根据大小、质地和颜色将有活力的种子与有缺陷的种子分开。它有助于提高种植种子的质量并提高作物产量。
农业:蔬菜缺陷分拣
在这个蔬菜缺陷分拣系统中,计算机视觉模型可以检测土豆、西红柿、胡萝卜或其他蔬菜甚至水果中的缺陷,如裂缝、瘀伤或斑点,并自动将有缺陷的缺陷从生产线上剔除。这确保了只有健康的农产品才能到达消费者手中并减少浪费。
制造业:不良品分拣
该有缺陷的产品分拣系统使用计算机视觉模型来检查产品是否存在缺陷,例如装配线上的划痕、凹痕或缺失的组件。有缺陷的产品会被标记并自动删除。它有助于提高产品质量并减少客户投诉。
制造业:金属废料分拣
在回收设施中,这种基于计算机视觉的金属废料分拣系统根据金属的物理特性和反射特性来识别和分拣不同类型的金属。这有助于优化回收过程并减少回收材料中的污染。
制造业:电子元件分类和分拣
该电子元件分类和排序系统使用计算机视觉来识别电子元件,例如电阻器、电容器或芯片,并根据类型、尺寸和放置要求对其进行排序。该系统提高了 PCB 组装的效率,并减少了元件放置的错误。
物流:仓库中的包裹分拣
这种基于计算机视觉的系统通过自动检测和分类各种包裹(包括盒子、带衬垫的信封和塑料袋)来增强物流中的包裹分拣。通过使用计算机视觉处理数据,它可以改变包装类型,防止路线错误和设备堵塞。该系统跟踪传送带上的包裹,机械臂将它们移动到正确的箱子。它提高了分拣速度并减少了运输错误。
供应链:垃圾和回收分拣
该系统通过提高垃圾和回收分拣流程的效率和准确性,在废物管理中使用计算机视觉。通过使用摄像头和 AI 模型,该系统可以识别和分类传送带上的各种材料(如塑料、玻璃、金属和纸张),确保它们被引导到适当的回收类别中。这种自动化不仅提高了分拣精度,还显著减少了人工干预的需求,从而提高了可回收材料的回收率并减少了垃圾填埋场的废物。AI 引导机器人的开发是为了以高精度分拣回收材料,从而提高回收设施的整体效率。
制药:药丸分拣
制药行业使用计算机视觉辅助药丸分拣来提高效率和准确性。配备摄像头和计算机视觉算法的自动化系统对片剂进行检测和分拣,识别缺口、变色或尺寸不正确等缺陷,确保只有优质产品才能通过供应链。例如,药丸分拣机每分钟可以处理许多片剂(丸剂),有效去除破碎的片剂和颗粒。这种自动化减少了人工劳动,最大限度地减少了错误,并在整个配送过程中保持了产品的完整性。
在这里,我们讨论了基于计算机视觉的分拣系统的一些用例。在其他各个领域中,用例数不胜数。计算机视觉通过自动化和提高准确性,显著增强了各个行业的分拣流程。通过将计算机视觉集成到分拣操作中,各行各业可以提高效率、准确性和生产力。
如何构建自动分拣系统
本节以苹果水果分拣为例,探讨了 Roboflow 如何使用计算机视觉简化自动分拣系统的创建。如前面部分所述,任何分拣系统的核心组件都是计算机视觉模型,它驱动决策过程。在这里,我们将演示 Roboflow 如何帮助构建这样的模型。下面概述的步骤为开发自动分拣系统提供了明确的路径。
我们正在开发一个使用计算机视觉的 Apple Sorting 对象检测模型,以区分好苹果和受损苹果。此项目的类定义为 “apple” 和 “damaged_apples”。首先创建一个用于对象检测的 Roboflow 项目,以管理数据集并简化模型开发过程。
步骤 #1:收集和注释数据集
构建对象检测模型的第一步是收集各种苹果图像数据集。这些图像应包括各种场景,例如不同的照明条件、角度和苹果大小,以确保模型的稳健性。数据集应同时捕获好苹果和受损苹果,以有效地表示这两个类。
收集图像后,使用边界框工具执行标注。在苹果周围绘制矩形,将它们标记为“苹果”或“damaged_apples”。这些标记的边界框用作真值数据,使模型能够在训练期间学习准确识别和分类对象。
步骤 #2:训练模型
对数据集进行注释后,下一步是使用 Roboflow 2.0 快速对象检测管道训练对象检测模型。
上图显示了使用 Roboflow 2.0 Object Detection (Fast) 训练的对象检测模型用于苹果分拣的结果。该模型将苹果识别并分类为 “apple”(好)或 “damaged_apple”,并带有相应的置信度分数。性能指标(mAP:79.1%、精确率:71.1%、召回率:77.0%)表示模型在识别和分类苹果方面的有效性。
步骤 #3:构建推理脚本
在此步骤中,我们将学习如何使用 Roboflow Inference API 和 Supervision 库构建推理脚本。该脚本处理实时摄像头流以识别合格和受损的苹果,并将结果发送到控制器进行自动分拣。识别出的标签用于传输命令,以通过串行端口控制分拣机械到连接的控制器,例如 Arduino 开发套件。该代码支持与分拣机制无缝集成,以分拣合格和受损的苹果。
api_key = "YOUR_ROBOFLOW_API_KEY"from inference import InferencePipeline
from inference.core.interfaces.camera.entities import VideoFrameimport cv2
import supervision as svimport serial
import time
import sys# Initialize serial communication with Arduino
arduino = serial.Serial('COM4', 9600, timeout=1)
time.sleep(2) # Allow Arduino to resetdef send_command_to_arduino(command: str):"""Send a command to Arduino via serial."""try:arduino.write(command.encode()) # Send command as bytesprint(f"Sent to Arduino: {command}")except Exception as e:print(f"Error sending data to Arduino: {e}")# Initialize annotators
label_annotator = sv.LabelAnnotator()
box_annotator = sv.BoxAnnotator()
# Initialize a variable to store the last sent command
last_command = Nonedef my_custom_sink(predictions: dict, video_frame: VideoFrame):global last_command # Declare the variable as global to retain its value across calls# Extract labels from predictionslabels = [p["class"] for p in predictions.get("predictions", [])]# Convert predictions to Supervision Detectionsdetections = sv.Detections.from_inference(predictions)# Annotate the frameimage = label_annotator.annotate(scene=video_frame.image.copy(), detectinotallow=detections, labels=labels)image = box_annotator.annotate(image, detectinotallow=detections)# Display the annotated imagecv2.imshow("Predictions", image)# Determine the appropriate command based on the labelsif "apple" in labels:current_command = "G_APPLE" # Command for damaged appleselif "damaged_apple" in labels:current_command = "D_APPLE" # Command for good appleselse:current_command = None # No command for other cases# Send the command only if it has changedif current_command != last_command:if current_command is not None: # Only send if there's a valid commandsend_command_to_arduino(current_command)last_command = current_command # Update the last commandif cv2.waitKey(1) & 0xFF == ord('q'):returnpipeline = InferencePipeline.init(model_id="apple-sorting-2bfhk/2",video_reference=0, # Use the default webcamon_predictinotallow=my_custom_sink,api_key=api_key,
)pipeline.start()
pipeline.join()
步骤 #4:构建分拣机制
图中所示的系统是一种苹果自动分拣机制,其中伺服系统用于根据苹果的分类为 “好苹果 ”或 “受损苹果 ”将苹果引导到适当的箱子中。
该电路由一个 Arduino Uno 和两个伺服电机组成。伺服电机连接到 Arduino 的 PWM 引脚(引脚 5 用于 Good Apple Servo,引脚 6 用于损坏的 Apple Servo)。
Arduino 通过 USB 连接与计算机视觉系统通信,通过串行端口接收命令。这些命令指示伺服位置,允许它们打开或关闭分拣门。该电路确保伺服系统与分类结果协调运行,将苹果引导到各自的箱子中。
以下是 Arduino 的固件代码:
#include <Servo.h>
int servoPin_1=5;
int servoPin_2=6;Servo good_apple_servo, damaged_apple_servo;void setup() {// put your setup code here, to run once:Serial.begin(9600);good_apple_servo.attach(servoPin_1);damaged_apple_servo.attach(servoPin_2);good_apple_servo.write(0);damaged_apple_servo.write(0);}void loop() {// put your main code here, to run repeatedly:
if (Serial.available() > 0) {String command = Serial.readStringUntil('\n'); // Read the commandcommand.trim(); // Remove extra whitespace// Debug: Print the received commandSerial.print("Received command: ");Serial.println(command);if (command == "G_APPLE") {good_apple_servo.write(90); // Opens sort line for good appledamaged_apple_servo.write(0); // closes sort line for damaged apple} else if (command == "D_APPLE") {damaged_apple_servo.write(90); // Opens sort line for damaged applegood_apple_servo.write(0); // closes sort line good apple} }}
系统如何运作
组件设置
两个伺服器连接到 Arduino Uno,每个伺服器负责控制排序路径。Good Apple Servo 为被归类为“Good”的苹果操作路径,而 Damaged Apple Servo 管理受损苹果的路径。
分类流程
计算机视觉模型处理实时摄像头流,将苹果分类为“良好”或“损坏”。通过上述步骤 #3 中的推理脚本。根据分类,通过串行端口将特定命令(G_APPLE 表示好苹果或 D_APPLE 表示受损苹果)发送到 Arduino。
伺服控制
Arduino 接收到命令并相应地调整舵机的位置:
- 对于一个好的苹果,Good Apple Servo 移动到 90°(打开)以允许苹果通过,而损坏的 Apple Servo 保持在 0°(关闭)。
- 对于损坏的苹果,损坏的苹果伺服器移动到 90°(打开)以引导苹果,而 Good Apple 伺服器保持在 0°(闭合)。
操作中的分拣
当苹果通过相机流时,分类会触发伺服移动。伺服系统充当门,将苹果引导到单独的箱子或溜槽中,确保准确分拣。
自动化和反馈
该系统持续加工苹果,根据分类结果动态调整伺服位置。这种实时决策允许在无需人工干预的情况下进行高速高效的分拣。
#计算机视觉中的梯度下降
计算机视觉 (CV) 模型使用训练数据来了解输入和输出数据之间的关系。训练是一个优化过程。梯度下降是一种基于成本函数的优化方法。它定义数据的预测值和实际值之间的差异。
CV 模型尝试最小化此损失函数或减小预测数据与实际输出数据之间的差距。为了训练深度学习模型 – 我们提供带注释的图像。在每次迭代中 – GD 尝试降低误差并提高模型的准确性。然后它经过一个试验过程以实现预期的目标。
动态神经网络使用优化方法到达目标。他们需要一种有效的方法来获取有关成功的反馈。优化算法创建该反馈循环,以帮助模型准确击中目标。
例如,图像分类模型使用图像的 RGB 值来生成具有置信度分数的类。训练该网络是为了最小化损失函数。损失函数的值提供了一个度量值 – 对于给定数据集,网络与目标性能相差多远。
在本文中,我们详细阐述了 CV 梯度下降 (GD) 中最流行的优化方法之一。
什么是梯度下降?
函数最小化的最著名优化方法是梯度下降。与大多数优化方法一样,它采用渐进的迭代方法来解决问题。坡度表示最快上升的方向。负坡度值表示最快下降的方向。
- 梯度下降从随机选择的点开始。然后,它沿梯度方向执行一系列步骤才能获得最接近解。
- 研究人员利用梯度下降来更新计算机视觉中的参数,例如线性回归中的回归系数和 NN 中的权重。
- 该方法定义初始参数的值。然后,它沿目标函数的方向迭代更新变量。因此,每次更新或迭代都会导致模型最小化给定的代价函数。
- 最后 – 它将逐渐收敛到给定函数的最佳值。
我们可以用狗训练来说明这一点。训练是循序渐进的,当达到特定目标时会有积极的强化。我们首先要引起它的注意,并在它看着我们时给它一个奖励。
有了这种强化(它对零食做了正确的事情),狗将继续遵循您的指示。因此 – 我们可以在它实现预期目标时对其进行奖励。
Gradient Descent 是如何工作的?
如上所述 – 我们可以将梯度视为或计算函数的斜率。它是函数关于所有变量的偏导数的集合。它表示斜率的陡峭程度,并指向函数增加(减少)最快的方向。
我们可以通过可视化具有两座山峰和一座山谷的山来说明梯度。有一个高峰上有一个盲人,他需要导航到底部。这个人不知道该选择哪个方向,但在正确的路径下,他会得到一些强化。他向下移动并为每一步获得加固,因此他将继续向下移动,直到到达底部。
学习率是 CV 优化中的一个重要参数。模型的学习率决定了是跳过数据的某些部分还是从上一次迭代进行调整。
在山的例子中,这将是这个人下山每走一步的大小。一开始 – 他可能会迈出很大的步伐。他会很快下降,但可能会超调并上山的另一边。
梯度下降中的学习率
Gradient Descent 是一种迭代优化算法,用于查找函数的局部最小值。较低的学习率更适合实际应用程序。如果学习率随着每一步的下降而降低,那将是理想的。
因此,这个人可以在不回头的情况下达到目标。因此,学习率绝不能太高或太低。
Gradient Descent 通过使用当前位置的渐变来计算下一个位置。我们通过学习率来放大当前梯度。我们从当前位置减去获得的值 (做一个步骤)。学习率对性能有很大影响:
- 低学习率意味着 GD 会收敛得更慢,或者可能在达到最佳点之前到达最终迭代。
- 高学习率意味着机器学习算法可能无法收敛到最佳点。它将找到一个局部最小值,甚至完全发散。
梯度下降问题
神经网络等复杂结构涉及假设函数中的非线性变换。它们的损失函数可能看起来不像具有单个最小值的凸函数。在整个域中,梯度可以在局部最小值处为零,也可以在全局最小值处为零。
如果它到达局部最小值 – 将很难逃脱该点。还有鞍点,其中函数是一个方向的最小值和另一个方向的局部最大值。它给人一种收敛到最低限度的错觉。
克服这些梯度下降挑战非常重要:
通过在优化过程中绘制成本函数来确保梯度下降正常运行。迭代次数在 x 轴上,成本函数的值在 y 轴上。
通过在梯度下降的每次迭代后表示成本函数的值,您可以估计学习率的好坏。
如果梯度下降工作正常,则应在每次迭代后最小化成本函数。
当梯度下降没有减少成本函数(大致保持在同一水平上)时 – 它已经收敛。
收敛 – 梯度下降可能需要 50 次迭代,或 50,000 次,甚至高达 100 万次,因此收敛的迭代次数不容易估计。
监控绘图上的梯度下降将使您能够确定它是否在成本函数增加的情况下无法正常工作。在大多数情况下,使用梯度下降时成本函数增加的原因是学习率大。
梯度下降的类型
根据算法使用的数据量 – 有 3 种类型的梯度下降:
随机梯度下降
随机梯度下降 (SGD) 随后更新每个训练样本的参数。在某些情况下 – SGD 比其他方法更快。
一个优点是频繁的更新提供了相当详细的改进率。但是 – SGD 的计算成本相当高。此外,更新频率会导致嘈杂的梯度,从而导致错误率增加。
for i in range (nb_epochs):
np . random . shuffle (data)
for example in data :
params_grad = evaluate_gradient (loss_function, example, params )
params = params - learning_rate * params_grad
批量梯度下降
批量梯度下降使用递归训练 epoch 来计算训练数据集中每个样本的误差。它的计算效率很高——它具有稳定的误差梯度和稳定的收敛性。缺点是稳定的误差梯度可能会收敛到一个不是模型所能达到的最佳点。它还需要在内存中加载整个训练集。
for i in range (nb_epochs):
params_grad = evaluate_gradient (loss_function, data, params)
params = params - learning_rate * params_grad
小批量梯度下降
小批量梯度下降是 SGD 和 BGD 算法的组合。它将训练数据集划分为小批次,并更新每个批次。这结合了 BGD 的效率和 SGD 的稳健性。
典型的小批量大小约为 100,但可能会因不同的应用而异。它是训练神经网络的首选算法,也是深度学习中最常见的 GD 类型。
for i in range (nb_epochs):
np.random . shuffle (data)
for batch in get_batches (data , batch_size =50):
params_grad = evaluate_gradient (loss_function, batch, params )
params = params - learning_rate * params_grad
#SpatialVLM
视觉语言模型虽然强大,但缺乏空间推理能力,最近 Google 的新论文说它的 SpatialVLM 可以做,看看他们是怎么做的。让视觉语言模型搞空间推理,谷歌又整新活了
视觉语言模型 (VLM) 已经在广泛的任务上取得了显著进展,包括图像描述、视觉问答 (VQA)、具身规划、动作识别等等。然而大多数视觉语言模型在空间推理方面仍然存在一些困难,比如需要理解目标在三维空间中的位置或空间关系的任务。
关于这一问题,研究者们常常从「人类」身上获得启发:通过具身体验和进化发展,人类拥有固有的空间推理技能,可以毫不费力地确定空间关系,比如目标相对位置或估算距离和大小,而无需复杂的思维链或心理计算。
这种对直接空间推理任务的熟练,与当前视觉语言模型能力的局限形成鲜明对比,并引发了一个引人注目的研究问题:是否能够赋予视觉语言模型类似于人类的空间推理能力?
最近,谷歌提出了一种具备空间推理能力的视觉语言模型:SpatialVLM。
- 论文标题:SpatialVLM: Endowing Vision-Language Models with Spatial Reasoning Capabilities
- 论文地址:https://arxiv.org/pdf/2401.12168.pdf
- 项目主页:https://spatial-vlm.github.io/
值得注意的是,研究者假设当前视觉语言模型在空间推理能力方面的限制并非源于其架构的局限,而更可能是由于在大规模训练时所使用的常见数据集的限制。例如,许多视觉语言模型是在以图像 - 描述对为特征的互联网规模数据集上进行训练的,这些数据集中包含的空间信息有限。存在限制的原因是获取富含空间信息的具身数据或 3D 感知查询的高质量人工注释比较困难,自动数据生成和增强技术是解决该问题的一种方法,然而很多之前的数据生成研究侧重于生成具有真实语义标注的照片逼真图像,忽略了对象和 3D 关系的丰富性。
与之相反,本文研究者专注于直接从现实世界数据中提取空间信息,以捕捉真实 3D 世界的多样性和复杂性。这一创新源自近期视觉模型方面在自动从 2D 图像中生成 3D 空间注释方面的进展。
SpatialVLM 系统可以实现数据生成和对视觉语言模型进行训练,以增强它们的空间推理能力。具体而言,研究者结合面向开放词汇的目标检测(open-vocabulary detection)、度量深度估计、语义分割和以目标为中心的描述模型,实现了在大规模地密集注释真实世界数据。SpatialVLM 将由视觉模型生成的数据转换成一种可用于描述、VQA 和空间推理数据的混合体上训练视觉语言模型的格式。
实验证明,本文训练的视觉语言模型表现出许多令人满意的能力。首先,它在回答定性空间问题方面的能力得到显著提升。其次,即使在有噪声的训练数据下,它也能可靠地进行定量估计。这种能力不仅使其具备关于目标大小的常识知识,还使其在重新排列任务的开放词汇奖励标注方面非常有用。第三,本文的空间视觉语言模型在自然语言界面的基础上,结合强大的大型语言模型,能够进行空间推理链以解决复杂的空间推理任务。
方法概览
为了使视觉语言模型具备定性和定量的空间推理能力,研究者提出生成一个大规模的空间 VQA 数据集用于训练视觉语言模型。具体而言,就是设计一个全面的数据生成框架,首先利用现成的计算机视觉模型,包括开放词汇检测、度量深度估计、语义分割和以目标为中心的描述模型,提取以目标为中心的背景信息,然后采用基于模板的方法生成质量合理的大规模空间 VQA 数据。本文中,研究者使用了生成的数据集训练 SpatialVLM,以学习直接的空间推理能力,然后将其与 LLMs 嵌入的高层常识推理相结合,解锁链式思维的空间推理。
2D 图像的空间基准
研究者设计了一个生成包含空间推理问题的 VQA 数据的流程,具体流程如图 2 中所示。
1、语义过滤:在本文的数据合成流程中,第一步是采用基于 CLIP 的开放词汇分类模型对所有图像进行分类,排除不适合的图像。
2、2D 图像提取以目标为中心的背景:这一步获得由像素簇和开放词汇描述组成的以目标为中心的实体。
3、2D 背景信息到 3D 背景信息:经过深度估计,将单眼的 2D 像素提升到度量尺度的 3D 点云。本文是第一个将互联网规模的图像提升至以目标为中心的 3D 点云,并用其合成带有 3D 空间推理监督的 VQA 数据。
4、消除歧义:有时一张图像中可能有多个相似类别的目标,导致它们的描述标签存在歧义。因此,在询问关于这些目标的问题之前,需要确保参考表达不含有歧义。
大规模空间推理 VQA 数据集
研究者通过使用合成数据进行预训练,将「直观」的空间推理能力融入 VLM。因此,合成涉及图像中不超过两个目标(表示为 A 和 B)的空间推理问答对。这里主要考虑以下两类问题:
1、定性问题:询问某些空间关系的判断。例如「给定两个对象 A 和 B,哪个更靠左?」
2、定量问题:询问更精细的答案,包括数字和单位。例如「相对于对象 B,对象 A 向左多少?」、「对象 A 距离 B 有多远?」
此处,研究者指定了 38 种不同类型的定性和定量空间推理问题,每种问题包含大约 20 个问题模板和 10 个答案模板。
图 3 展示了本文获取的合成问答对的示例。研究者创建了一个包括 1000 万张图像和 20 亿个直接空间推理问答对 (50% 是定性问题,50% 是定量问题) 的庞大数据集。
学习空间推理
直接空间推理:视觉语言模型接收图像 I 和关于空间任务的查询 Q 作为输入,并输出一个答案 A,并且以文本的格式呈现,无需使用外部工具或与其他大型模型进行交互。本文采用与 PaLM-E 相同的架构和训练流程,只是将 PaLM 的骨干替换为 PaLM 2-S。然后,使用原始 PaLM-E 数据集和作者的数据集的混合进行模型训练,其中有 5% 的 token 用于空间推理任务。
链式思维空间推理:SpatialVLM 提供了自然语言接口,可用于查询具有基础概念的问题,当与强大的 LLM 结合使用时,可以执行复杂的空间推理。
与 Socratic Models 和 LLM 协调器中的方法类似,本文利用 LLM (text-davinci-003) 来协调与 SpatialVLM 进行通信,以链式思维提示的方式解决复杂问题,如图 4 所示。
实验及结果
研究者通过实验证明并回答了如下的问题:
问题 1:本文设计的空间 VQA 数据生成和训练流程,是否提高了 VLM 的一般空间推理能力?以及它的表现如何?
问题 2:充满噪音数据的合成空间 VQA 数据和不同的训练策略,对学习性能有何影响?
问题 3:装备了「直接」空间推理能力的 VLM,是否能够解锁诸如链式思维推理和具身规划等新能力?
研究者通过使用 PaLM-E 训练集和本文设计的空间 VQA 数据集的混合来训练模型。为了验证 VLM 在空间推理上的局限是否是数据问题,他们选择了当前最先进的视觉语言模型作为基线。这些模型的训练过程中语义描述任务占据了相当的比重,而不是使用本文的空间 VQA 数据集进行训练。
空间 VQA 表现
定性空间 VQA。对于这一问题,人工注释的答案和 VLM 输出均为自由形式的自然语言。因此,为了评估 VLM 的性能,研究者使用人工评定员确定答案是否正确,表 1 中展示了各个 VLM 的成功率。
定量空间 VQA。如表 2 所示,本文的模型在两个指标上都比基线表现更好且遥遥领先。
空间 VQA 数据对通用 VQA 的影响
第二个问题是,由于与大量的空间 VQA 数据共同训练,VLM 在其他任务上的表现是否会因此而降低。通过将本文模型与在通用 VQA 基准上没有使用空间 VQA 数据进行训练的基本 PaLM 2-E 进行了比较,如表 3 所总结的,本文的模型在 OKVQA 基准上达到了与 PaLM 2-E 相当的性能,其中包括了有限的空间推理问题,并且在 VQA-v2 test-dev 基准上表现略好,该基准包含了空间推理问题。
ViT 编码器在空间推理中的影响
Frozen ViT (在对比目标上进行训练) 是否编码了足够的信息来进行空间推理?为了探索这一点,研究者的实验从第 110,000 步的训练开始,分成两个训练运行,一个 Frozen ViT,另一个 Unfrozen ViT。通过对这两个模型进行了 70,000 步的训练,评估结果如表 4 所示。
含噪声的定量空间答案的影响
研究者者使用机器人操作数据集训练视觉语言模型,发现模型能够在操作领域进行精细的距离估计 (图 5),进一步证明了数据的准确性。
表 5 比较了不同的高斯噪声标准差对定量空间 VQA 中整体 VLM 性能的影响。
空间推理启发新应用
1、视觉语言模型作为密集奖励注释器
视觉语言模型在机器人学领域有一个重要的应用。最近的研究表明,视觉语言模型和大型语言模型可以作为机器人任务的通用开放词汇奖励注释器和成功检测器,可用于制定有效的控制策略。然而,VLM 的奖励标注能力通常受到空间意识不足的限制。由于 SpatialVLM 能够从图像中定量估计距离或尺寸,因此它独特地适用作为密集的奖励注释器。作者进行一项真实的机器人实验,用自然语言指定了一个任务,并要求 SpatialVLM 为轨迹中的每一帧注释奖励。
图 6 中每个点表示一个目标的位置,它们的颜色表示注释的奖励。随着机器人朝着指定目标的进展,可以看到奖励是单调增加的,表明 SpatialVLM 作为密集奖励注释器的能力。
2、链式思维空间推理
研究者还研究了 SpatialVLM 是否能够用于执行需要多步推理的任务,考虑到它对基本空间问题的增强回答能力。作者在图 1 和图 4 中展示了一些例子。当大语言模型 (GPT-4) 装备有 SpatialVLM 作为空间推理子模块时,可以执行复杂的空间推理任务,比如回答环境中的 3 个对象是否能够形成「等腰三角形」。
#DiTCtrl
无需训练!多提示视频生成最新SOTA!港中文&腾讯等发布DiTCtrl:基于MM-DiT架构
腾讯等机构提出的DiTCtrl模型,这是一个基于MM-DiT架构的多提示视频生成方法,首次实现了无需额外训练的动态条件选择。DiTCtrl通过引入KV共享机制和隐混合策略,确保了不同提示之间的平滑过渡和一致的对象运动,展现出在视频生成任务中的优越性能,同时提出了MPVBench作为新的评估框架。
文章链接:https://arxiv.org/pdf/2412.18597
项目链接:https://github.com/TencentARC/DiTCtrl
亮点直击
- DiTCtrl,这是一种基于MM-DiT架构的、首次无需调优的多提示视频生成方法。本文的方法结合了新颖的KV共享机制和隐混合策略,使得不同提示之间能够无缝过渡,且无需额外的训练。
- 首度分析了MM-DiT的注意力机制,发现其3D全注意力与UNet-like扩散模型中的交叉/自注意力块具有相似的行为,从而实现了基于mask的精确语义控制,使得不同提示之间的生成更加一致。
- 推出了MPVBench,这是一个专为多提示视频生成设计的新基准,具有多种过渡类型和专门的评估指标,用于多提示视频的评估。-大量实验表明,本文的方法在多提示视频生成任务上实现了业界领先的性能,同时保持了计算效率。
总结速览
解决的问题
当前的视频生成模型,尤其是基于单一提示(single-prompt)的模型,如Sora,主要聚焦于生成单一提示下的视频内容。它们在生成多个顺序提示(multi-prompt)的连贯场景时存在显著挑战,尤其是在动态场景中需要反映多个动作时,面临的问题包括:
- 训练数据要求严格;
- 提示跟随能力较弱;
- 转场不自然,缺乏平滑过渡。
提出的方案本文提出了DiTCtrl方法。这是基于MM-DiT架构的、训练无关的多提示视频生成方法,首次能够在没有额外训练的情况下生成多提示的视频,且能够保证多个提示之间的视频内容平滑过渡。
应用的技术
- MM-DiT架构:多模态扩散Transformer(Multi-Modal Diffusion Transformer)架构被用于视频生成任务,能够有效处理文本、图像和视频的联合表示。
- 3D全注意力机制:分析了MM-DiT的注意力机制,发现其3D全注意力与UNet-like扩散模型中的交叉/自注意力模块相似,能够在多个提示之间共享注意力,从而实现语义一致性。
- KV共享和隐混合策略:为实现视频之间的平滑过渡,提出了键值共享(KV-sharing)机制和隐空间混合(latent blending)策略,以连接不同提示生成的视频片段。
达到的效果
- 平滑过渡与一致性:通过DiTCtrl方法,生成的视频在多个提示之间能够实现平滑的过渡和一致的物体运动,而不需要额外的训练。
- 高效性能:在MPVBench基准测试上,DiTCtrl在保持计算效率的同时,取得了最先进的性能。
- 新基准MPVBench:为了促进多提示视频生成的研究,文章还提出了MPVBench基准,专门用于评估多提示视频生成的过渡效果和性能。
方法
本文解决了zero-shot、多提示长视频生成的挑战, 无需模型训练或优化。这使我们能够生成高质量的视频,具有平滑和精确的提示间过渡,涵盖各种过渡类型(例如,风格、镜头运动和位置变化)。形式上, 给定一个预训练的单提示文本到视频扩散模型 和一个包含 个提示的序列 , 所提出的DiTCtrl能够生成一个连贯的长视频 , 该视频能够随时间忠实地跟随这些提示, 可以表示为:
MM-DiT 注意力机制分析
MM-DiT 是当前文本到图像/视频模型的基础架构,与之前的 UNet 架构有根本的不同,因为它将文本和视频映射到一个统一的序列中进行注意力计算。尽管该架构已被广泛使用,但其内部注意力机制的特性尚未得到充分探索,这限制了其在我们多提示长视频生成任务中的应用。因此,本文首次对基于最先进的视频模型(即 CogVideoX)的 3D 全注意力图中的区域注意力模式进行了全面分析。
如下图 2 所示,由于视觉和文本提示的连接,每个注意力矩阵可以分解为四个不同的区域,分别对应不同的注意力操作:视频到视频的注意力、文本到文本的注意力、文本到视频的注意力和视频到文本的注意力。以下是每个区域的详细介绍,灵感来源于先前的 UNet-like 结构中的独立注意力。
文本到视频和视频到文本的注意力
之前的 UNet-like 架构通过交叉注意力实现视频与文本的对齐。在 MM-DiT 中,文本到视频和视频到文本的注意力发挥了类似的作用。计算了所有层和注意力头的平均注意力值,然后通过选择特定的列或行来提取文本到视频和视频到文本区域的注意力值,这些列或行对应文本到视频和视频到文本区域中的token索引。接着,这些注意力值被重塑为 格式,从而能够可视化每一帧的语义激活图。如上图 2 所示,这些可视化结果显示了token级语义定位的显著精度,能够有效捕捉文本描述和视觉元素之间的细粒度关系。这一发现为精确的语义控制和定位提供了强有力的基础,为借用已有的图像/视频编辑技术以增强多提示视频生成的一致性和质量提供了支持。
文本到文本和视频到视频的注意力
文本到文本和视频到视频的区域注意力在某种程度上是新的,与相应的 UNet 结构不同。如下图 3 所示,本文的分析揭示了这两个组件中相似的模式。在文本到文本的注意力组件(图 3(a)(b),其中 (a) 表示较短提示的注意力模式,(b) 表示较长提示的模式)中,观察到一个显著的对角线模式,表明每个文本token主要关注其邻近的token。
值得注意的是,随着文本序列长度的增加,存在明显的垂直线,这些垂直线向后移动,表明所有token对文本序列末尾的特殊token保持显著关注。对于视频到视频的注意力组件,由于 MM-DiT 扁平化了空间和时间token以进行 3D 注意力计算,在单帧级别的分析揭示了空间注意力中的明显对角线模式(上图 3(c))。更重要的是,当检查来自不同帧中相同空间位置的token构建的注意力图时,还观察到显著的对角线模式(图 3(d))。这一特征与最近的基于 UNet 的视频模型中的空间注意力和时间注意力(如 VideoCrafter 和 Lavie)中的发现相似,符合 [25] 中的报告结果。
由于之前的工作仅训练扩散模型的特定部分以进行更高级的控制和生成,本文的发现为从 MM-DiT 角度看待这些方法提供了有力的证据。这些在 MM-DiT 架构中出现的一致对角线模式表明了帧间强相关性,这对于维持空间-时间一致性和保留视频序列中的运动忠实度至关重要。
随时间一致的视频生成
MM-DiT 中的注意力机制与 UNet-like 视频扩散模型中的行为类似。因此,提出了基于mask引导的 KV 共享策略,用于多提示视频生成任务中的一致视频生成。
如下图 4 所示, 为了在提示 和提示 之间生成一致的视频, 利用 MM-DiT 中第 和第 个提示的中间注意力来分别生成特定一致对象的注意力mask。这是通过对 3D 全注意力中的所有文本到视频/视频到文本部分进行平均,并使用给定的特定主题token来实现的。通过这些mask,接着执行mask引导的注意力融合, 生成提示 的新注意力特征。受到 MasaCtrl 的启发, 直接利用提示 中的键和值来引导提示 的生成, 从而实现随时间变化的一致外观生成。
形式上, 在第 步, 分别使用固定的 MM-DiT 骨干网络与提示 和下一个提示 进行前向传递,生成中间区域的交叉注意力图。然后, 对所有头和层中的注意力图进行平均, 得到相同空间分辨率 和时间帧 的平均值。得到的交叉注意力图记作 , 其中 是文本token的数量。接下来, 获得与前景对象相关的token的平均交叉注意力图。分别将 和 作为从 和 中提取的前景对象masks。利用这些masks, 可以限制在 中的对象仅查询来自 中对象区域的信息:
其中, 是最终的注意力输出。然后, 将当前步骤的特征图替换为 , 以便进一步计算。
用于过渡的隐混合策略
尽管之前的方法保证了片段之间的语义一致性,但要实现不同语义片段之间的平滑过渡,仍需要精心设计。因此,提出了一种隐混合策略,旨在确保不同语义片段之间的时间一致性,灵感来源于最近在单提示长视频生成中的工作 [33, 46]。
如下图 5 所示,本文的方法在相邻语义视频片段(视频 和视频 )之间引入重叠区域。对于重叠区域中的每个帧位置,应用一个位置相关的权重函数,该函数遵循对称分布——越靠近各自片段的帧得到更高的权重,而边界处的帧则得到较低的权重。这个加权方案确保了不同语义上下文之间的平滑过渡。
形式上, 给定由提示 和 分别生成的两个相邻视频片段 和 , 提出如下隐混合策略。设 表示片段之间的重叠帧数。对于重叠区域中的帧位置 , 计算其混合隐特征 :
其中, 和 分别是来自 和 的隐特征, 是一个位置相关的三角形权重函数, 定义为:
本文的方法的关键优势在于,它不需要额外的训练,同时能够有效地处理不同语义上下文之间的过渡。在每个去噪步骤中,首先独立处理每个片段,然后逐步使用位置相关的权重在重叠区域中融合隐特征。这一策略在保持时间一致性的同时,平滑地过渡于不同的语义上下文之间,使其特别适用于多提示视频生成任务。
实验
基于 CogVideoX-2B 实现了 DiTCtrl,CogVideoX-2B 是一种基于 MM-DiT 的先进开源文本到视频扩散模型。在实验中,生成了多提示条件的视频,每个视频片段由 49 帧组成,分辨率为 480×720。此外,还使用了 ChatGPT 来生成不同类型的多个过渡。在实验中将隐采样帧数和重叠大小设置为 13 和 6。实验在单个 NVIDIA A100 GPU 上进行。
质量结果
与当前最先进的多提示视频生成方法[33, 38, 40] 和领先的商业解决方案 进行了全面的定性比较。为了确保公平比较,还在 CogVideoX 主干上实现了 FreeNoise,作为增强的基准。
如下图 6 所示,本文提出的方法在三个关键方面展示了优越的性能:文本到视频对齐、时间一致性和运动质量。尽管 Kling 在高质量视频生成方面展现了令人印象深刻的能力,但它仅限于同时的多语义混合,而不是顺序的语义过渡,这突出了在多提示视频生成任务中实现时间演变内容的重要性。
本文的比较分析揭示了现有方法的 distinct 特征和局限性。Gen-L-Video 存在严重的时间抖动和偶尔的物体消失,影响了整体视频质量。Video-Infinity 和 FreeNoise 都在场景级语义变化方面取得了成功,但缺乏物理上合理的运动——例如,在上图 6 中,车辆看似在运动,但空间位置固定,这是它们基于 UNet 的能力的限制。相比之下,FreeNoise+DiT 利用了 DiT 架构的能力实现了更真实的物体运动,但在语义过渡上存在困难,导致片段之间出现明显的中断。DiTCtrl 方法保留了预训练 DiT 模型的固有能力,同时解决了这些局限性,能够平滑地实现语义过渡,并在整个视频序列中保持运动一致性。
定量结果
首先详细介绍我们提出的用于评估多提示视频生成的新基准 MPVBench,然后讨论定量结果。
MPVBench
MPVBench 包含一个多样化的提示数据集和一个专门为多提示生成定制的新度量标准。具体来说,通过利用 GPT-4,生成了 130 个长格式的提示,涵盖 10 种不同的过渡模式。然后,对于多提示视频生成,观察到 CLIP 特征在单一提示和多提示场景之间的分布有所不同。如下图 7 所示,自然视频的特征点沿着一条连续曲线分布,而两个拼接的孤立视频的特征点则沿着两条连续曲线分布,并且在中间有一个断点。
由于常见的 CLIP 相似度计算的是邻近相似度的平均值,自然视频和孤立视频之间的差异仅在断点处发生,并且在按帧数划分后,差异会变得非常小。为了解决这一限制,提出了 CSCV(Clip Similarity Coefficient of Variation),这一度量标准专门用于评估多提示过渡的平滑度:
其中, 表示帧特征, 和 分别是标准差和平均值。变异系数 (CV) 描述了均匀度的程度,可以大大惩罚孤立情况。函数 将分数映射到 范围内, 分数越大越好。
自动评估
使用 MPVBench 进行自动评估。从下表 1 中可以看出,本文的方法获得了最高的 CSCV 分数,证明了在过渡处理和生成模式的整体稳定性方面具有优势。虽然 FreeNoise 排名第二,稳定性相对较强,但其他方法在这一方面显著落后,这与上图 7 中 CLIP 嵌入的 T-SNE 可视化结果一致。在运动平滑性方面,本文的方法在运动质量和一致性方面表现优越。在文本-图像相似度指标方面,尽管 FreeNoise 和 Video-Infinity 获得了更高的分数,但这可以归因于我们方法的 KV-sharing 机制,在该机制下,后续视频片段本质上从前面的语义内容中学习。
如前面图6所示,本文的设计选择允许路面逐渐过渡到雪地条件,同时保留之前场景的特征。尽管可能会导致较低的文本-图像对齐得分,但它确保了序列中的语义连续性。在实际应用中,这种权衡并不会对多提示场景中的视觉质量产生负面影响,如下面我们展示的用户研究结果所示。
人类评估
邀请了28名用户评估五个模型:Gen-L-Video、Video-Infinity、FreeNoise、FreeNoise+DiT 和本文的方法。使用5点Likert量表(1代表低质量,5代表高质量)。参与者根据16个不同场景生成的视频,考虑整体偏好、运动模式、时间一致性和文本对齐情况对每种方法进行评分。正如下表2所示,本文的方法在所有四个标准上显著超越了其他现有方法,展示了在生成具有自然语义过渡的视频方面的卓越能力,能够更好地与人类对视觉连贯性和连续性的偏好相符。
消融研究
进行消融研究,以验证DiTCtrl关键组件的有效性:隐融合策略、KV-sharing机制和掩模引导生成,如下图8所示。第一行显示了直接使用文本-视频模型的结果,导致场景变化突兀,运动模式断裂,无法保持从冲浪到滑雪过程中运动的一致性。第二行表明,未使用隐融合策略的DiTCtrl能够实现基本的视频编辑功能,但场景之间缺乏平滑过渡。没有KV-sharing(第三行)的DiTCtrl表现出不稳定的环境过渡和显著的运动伪影,角色缩放不一致,动作变形。此外,没有掩模引导(第四行)的DiTCtrl提高了运动一致性和过渡效果,但在不同提示和环境之间的对象属性混乱方面存在问题。另一方面,完整的DiTCtrl实现提供了对生成内容的最精确控制,展示了卓越的对象一致性和更平滑的提示过渡,同时保持所需的运动模式。这些结果验证了对MM-DiT注意力机制的分析及其在实现准确语义控制中的作用。
更多应用
单提示长视频生成
本文的方法能够自然地应用于单提示长视频生成。如下图9所示,使用提示“A white SUV drives on a steep dirt road”,本文的方法成功生成了长度超过原始视频12倍的视频,同时保持了一致的运动模式和环境连贯性。这表明,本文的技术不仅适用于多提示视频生成任务,还能有效地扩展到长时间视频的生成,确保了生成内容在时间维度上的连贯性和一致性。
视频编辑
本文展示了如何使用本文的方法实现视频编辑功能(例如,“重新加权”和“单词替换”)。通过这些操作,能够在不破坏视频原有结构和连贯性的情况下,灵活地编辑视频内容。这使得我们的技术不仅仅适用于新视频的生成,还能作为强大的视频编辑工具,在多个语义变化的场景下保持视频的整体一致性与流畅过渡。
结论
本文介绍了DiTCtrl,一种基于MM-DiT架构的多提示视频生成的创新方法,且无需额外的训练。对MM-DiT的注意力机制进行了开创性的分析,揭示了其与UNet-like扩散模型中的交叉/自注意力模块的相似性,这使得在提示之间能够实现mask引导的语义控制。通过引入KV共享机制和隐融合策略,DiTCtrl确保了语义段之间的平滑过渡和一致的对象运动,无需额外的训练。此外,还提出了MPVBench,这是首个针对多提示视频生成的广泛评估框架,旨在推动该领域未来的研究。
局限性与未来工作
尽管本文的方法展示了最先进的性能,但仍然存在两个主要局限性。首先,与图像生成模型相比,当前开源的视频生成模型在概念组合能力上较弱,偶尔会导致不同语义段之间的属性绑定错误。其次,基于DiT架构的计算开销对推理速度提出了挑战。这些局限性为未来研究提供了有前景的方向,特别是在增强语义理解和架构效率方面。
#DACER
扩散模型与在线强化学习强强联合创造新SOTA!
清华大学智能驾驶课题组在NeurIPS 2024上发表的研究成果DACER,这是一种结合扩散模型和在线强化学习的算法,能够产生多模态动作分布,并提出了基于高斯混合模型的熵正则化方法来提升性能。DACER通过将扩散模型的反向过程作为策略函数,显著提升了在线强化学习算法的整体性能,并在MuJoCo基准测试中取得了优异的结果。
本文介绍清华大学智能驾驶课题组(iDLab)在 NeurIPS 2024 发表的最新研究成果《Diffusion Actor-Critic with Entropy Regulator》。该算法创新性地将扩散模型的反向过程作为策略函数,使在线强化学习算法能够产生多模态动作分布。此外,本文提出了基于高斯混合模型的熵正则化方法,显著提升了算法的整体性能。该研究工作由清华大学2023级研究生王以诺在李升波教授指导下完成。
Arxiv地址:https://arxiv.org/pdf/2405.15177
代码链接:https://github.com/happy-yan/DACER-Diffusion-with-Online-RL
1 背景
在线强化学习(Online Reinforcement Learning, Online RL) 作为人工智能领域解决复杂序列决策问题的核心方法之一,其应用范围持续扩展。在智能博弈、机器人控制及自动驾驶等传统应用领域取得显著成果的同时,强化学习技术正在大语言模型(Large Language Models, LLM)的微调优化、价值对齐及推理增强等关键环节发挥重要作用。然而在大多数传统的在线强化学习算法中,策略函数通常被参数化为可学习的高斯分布,这限制了它们表达复杂策略的能力。
扩散模型作为一种生成模型因其强大的拟合多模态分布能力而广为人知。它通过逐步添加和移除噪声来学习原始数据分布,在图像和视频生成领域表现出色。在RL中,策略网络可以被视为一种状态条件生成模型。Online RL通过与环境交互来学习控制策略,而Offline RL无需与环境互动,主要从先前收集的数据中学习策略[1]。在实际应用中,许多控制问题都有优秀的模拟器,使用Offline RL并不合适,因为具有互动能力的Online RL表现更佳。然而,扩散模型直接用于Online RL可能遇到的问题包括:
- 扩散模型的损失函数项本质上是一种模仿学习损失项,但与Offline RL不同,Online RL中并不存在可供模仿的数据;
- 扩散模型的反向过程无法进行解析求熵,这使得其难以与最大熵强化学习框架相结合,从而导致算法收敛性能不佳。
为了解决上述的问题,清华大学研究团队提出了一种基于扩散模型的在线强化学习算法DACER(Diffusion Actor-Critic with Entropy Regulator) 。我们将DACER建立在去噪扩散概率模型(DDPM)[2]的基础上。受到Kaiming He[3]启发,扩散模型的表示能力主要来源于反向扩散过程而非正向,因此我们将扩散模型的反向过程重新概念化为一种新的策略近似函数,利用其强大的表示能力来提升RL算法的性能。这个新策略函数的优化目标是最大化期望Q值。在RL中,最大化熵对于策略探索至关重要,但扩散策略的熵难以解析确定。因此,我们选择在固定间隔处采样动作,并使用高斯混合模型(GMM) 来拟合动作分布,可计算每个状态下策略的近似熵。这些熵的平均值之后被用作当前扩散策略熵的近似。最后,我们使用估计的熵来平衡扩散策略在训练过程中的探索与利用。
2 DACER的关键技术
2.1 扩散策略表征
将条件扩散模型的反向过程用作参数化策略:
采样过程可以重新表述为:
2.2 扩散策略学习
在Online RL中,由于没有可供模仿的数据集,我们放弃了行为克隆项和模仿学习框架。策略学习的目标是最大化由扩散网络在给定状态下生成的动作的期望Q值:
此外,我们使用课题组提出的分布式Q学习[4]的方法来缓解值函数的过估计问题。然而,直接使用上述扩散策略学习方法进行训练时,会因策略动作过于确定性而导致性能不佳。
2.3 扩散策略与熵调节器
对于每个状态,我们使用扩散策略来采样N个动作,然后使用高斯混合模型(GMM)来拟合策略分布。我们可以通过以下方式估计对应于该状态的动作分布的熵[3]:
类似于最大化熵的RL,我们根据估计的熵学习一个参数α:
最终,我们使用下式在训练的采样阶段调整扩散策略的熵。熵调节机制是解锁探索潜能的关键。
综上所述,DACER算法的整体流程为
3 实验结果
下图为DACER与其他强化学习算法在MuJoCo[6]上的表现对比。图1和表1分别展示了学习曲线和性能策略。在所有评估的任务中,DACER算法始终与所有竞争基准算法的性能相匹配或超越。特别是在Humanoid-v3场景中,DACER相较于DDPG、TD3、PPO、SAC、DSAC和TRPO分别提升了124.7%、111.1%、73.1%、27.3%、9.8%和1131.9%。
为评估策略表征能力,我们将DACER与DSAC、TD3和PPO的性能进行了比较,结果如图2所示。可以看出,DACER的动作倾向于指向不同状态下的最近峰值。DACER的价值函数曲线显示了四个对称的峰值,与之前的分析相符合。相比于DSAC,我们的方法学习到了更优的策略表示,这主要得益于采用扩散模型来参数化策略,而非传统的MLP。相比之下,TD3和PPO的价值函数曲线难以学得四个对称的峰值[7]。总体而言,DACER展示了极佳的策略表征能力。
为展示DACER的多模态能力,我们选择了五个需要多模态策略的点:(0.5, 0.5)、(0.5, -0.5)、(-0.5, -0.5)、(-0.5, 0.5)和(0, 0)。对每个点采样100条轨迹,在图3中绘制。结果显示与DSAC相比,DACER展现了显著的多模态特性。这也解释了为什么只有DACER的Q函数能够学习到几乎完美对称的四个峰值。
在Humanoid-v3任务上,DACER、DSAC、SAC训练收敛后的可视化:
DACER
DSAC
SAC
4 总结
本研究中我们提出了一种基于扩散模型的在线强化学习算法DACER(Diffusion Actor-Critic with Entropy Regulator),旨在克服传统强化学习方法在策略参数化中使用高斯分布的局限性。通过利用扩散模型的反向去噪过程,DACER能够有效地学习多模态分布,使得创建更复杂的策略并提高策略性能成为可能。一个显著的挑战来自于缺乏解析表达式来确定扩散策略的熵,使其难以与最大熵强化学习结合,导致性能不佳。为了解决这一问题,我们采用高斯混合模型(GMM)来估计熵,从而促进了关键参数α的学习,该参数通过调节动作输出中的噪声方差来实现探索和利用的平衡。在MuJoCo基准测试和多模态任务上的实证测试显示了DACER的优越性能。
#通过相机标定提高视觉应用的准确性
什么是相机标定
相机校准就像验光师检查眼睛一样。就像眼科医生测量眼睛如何处理视觉信息一样,相机校准可以帮助我们了解相机如何将 3D 世界转换为 2D 图像。这种理解对于从智能手机摄影到自动驾驶汽车等各种应用都至关重要。
从本质上讲,相机校准依赖于一个非常优雅的数学方程:x = PX
- x表示图像中的二维点
- P是相机矩阵(包含所有相机参数)
- X表示现实世界中的 3D 点
可以将相机矩阵视为P相机将 3D 场景转换为 2D 图像的个人“配方”。此矩阵包含两组关键成分:
1. 内部参数(相机的“个性”)
- 焦距:视野“放大”的程度
- 主点:图像中心的真正位置
- 倾斜:像素的形状和排列方式
- 长宽比:像素宽度和高度之间的关系
2. 外部参数(相机的“位置”)
- 旋转:相机指向哪个方向
- 翻译:相机在空间中的位置
为什么需要相机标定
想象一下,仅使用一张照片测量两座建筑物之间的距离。如果没有适当的校准,您可能会得到完全错误的测量结果!这就是相机校准如此重要的原因:
- 镜头失真校正:有没有注意到广角自拍照会让脸部看起来有点扭曲?这就是镜头失真。
- 精确的测量:对于制造业和建筑业等行业至关重要。
- 增强计算机视觉:帮助人工智能系统通过摄像头准确地解读世界。
- 改进的增强现实:使虚拟物体与现实世界正确对齐。
如何校准相机:分步指南
要校准相机,请按照以下步骤操作:
1. 准备校准目标:最常用的目标是棋盘图案。您可以将此图案打印在纸上,或使用已知尺寸的方格实体棋盘。
2. 拍摄图像:从不同角度和距离拍摄棋盘的多张照片。确保每张图像中都能看到整个图案。
3. 检测角点:使用软件工具检测每个图像中棋盘上方格的角点。
4. 计算参数:利用检测到的角和已知的正方形尺寸,使用张的方法或 OpenCV 函数等算法计算内在和外在参数。
5. 评估校准:通过计算重投影误差来检查校准的准确性。
一个简单的 Python 实现Demo
以下是使用 OpenCV 校准相机的实际示例:
import cv2
import numpy as np
import glob# Termination criteria for corner sub-pixel accuracy
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)# Prepare object points (3D points in real-world space)
objp = np.zeros((6*7, 3), np.float32)
objp[:, :2] = np.mgrid[0:7, 0:6].T.reshape(-1, 2)# Arrays to store object points and image points
objpoints = [] # 3D point in real-world space
imgpoints = [] # 2D points in image plane# Load images
images = glob.glob('path/to/calibration/images/*.jpg') # Update with your pathfor img in images:gray = cv2.imread(img)gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)# Find the chessboard cornersret, corners = cv2.findChessboardCorners(gray, (7, 6), None)if ret:objpoints.append(objp)corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)imgpoints.append(corners2)# Calibrate the camera
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)print("Camera matrix:\n", mtx)
print("Distortion coefficients:\n", dist)
准备您自己的校准图像:
- 打印棋盘图案或以数字方式创建一个棋盘图案。
- 拍摄图像时确保良好的光照条件。
- 从各个角度拍摄至少 10 至 15 张图像以获得准确的结果。
- 将这些图像保存在专用文件夹中,以便在编码期间轻松访问。
相机校准的实际应用
相机校准在各个领域都具有广泛的实际应用。以下是其发挥关键作用的一些关键领域:
1. 三维重建
在虚拟现实 (VR) 和增强现实 (AR) 等应用中,准确的 3D 重建至关重要。相机校准允许系统通过了解不同图像在三维空间中彼此之间的关系,从多个 2D 图像创建精确的 3D 模型。这在需要逼真交互的游戏和模拟环境中尤为重要。
2. 机器人技术
机器人在很大程度上依赖视觉输入来导航和与环境互动。摄像头校准使机器人能够准确感知周围物体的距离和大小。例如,在自动驾驶汽车中,经过校准的摄像头有助于确定障碍物和其他车辆的位置,从而促进安全导航。
3. 增强现实
在增强现实应用中,将数字信息叠加到现实世界需要虚拟元素和现实世界物体之间的精确对齐。相机校准可确保虚拟内容相对于物理环境的位置和比例正确,从而增强用户体验。
4. 医学成像
在内窥镜或放射学等医学成像技术中,相机校准对于准确的诊断和治疗计划至关重要。它确保图像反映真实的解剖尺寸,帮助医疗专业人员做出明智的决定。
5. 体育分析
摄像机校准用于体育技术,以分析运动员的动作和比赛动态。通过校准运动场或竞技场周围的摄像机,分析师可以捕捉运动员和设备的精确动作,从而制定更好的训练方法和策略。
相机校准乍一看可能很复杂,但这是一个基本过程,可以帮助我们从相机中获取最准确的信息。无论您是业余摄影师还是开发计算机视觉应用程序,了解相机校准对于获得精确的结果都至关重要。
#SparseViT
参数高效的稀疏化视觉Transformer
本文介绍了四川大学吕建成团队与澳门大学合作提出的SparseViT模型,这是一种参数高效的稀疏化视觉Transformer,专门针对图像篡改检测(IML)领域设计。SparseViT通过稀疏自注意力机制和可学习的多尺度监督机制,实现了对非语义特征的自适应提取,并在多个基准数据集上展现了卓越的性能。
论文:https://arxiv.org/abs/2412.14598
代码:https://github.com/scu-zjz/SparseViT
单位:四川大学(吕建成团队),澳门大学
背景简介:
随着图像编辑工具和图像生成技术的快速发展,图像处理变得非常方便。然而图像在经过处理后不可避免的会留下伪影(操作痕迹),这些伪影可分为语义和非语义特征。因此目前几乎所有的图像篡改检测模型(IML)都遵循“语义分割主干网络”与“精心制作的手工制作非语义特征提取”相结合的设计,这种方法严重限制了模型在未知场景的伪影提取能力。
研究内容:
利用非语义信息往往在局部和全局之间保持一致性,同时相较于语义信息在图像不同区域表现出更大的独立性,SparseViT 提出了以稀疏自注意力为核心的架构,取代传统 Vision Transformer (ViT) 的全局自注意力机制,通过稀疏计算模式,使得模型自适应提取图像篡改检测中的非语义特征。研究团队在统一的评估协议下复现并对比多个现有的最先进方法,系统验证了 SparseViT 的优越性。同时,框架采用模块化设计,用户可以灵活定制或扩展模型的核心模块,并通过可学习的多尺度监督机制增强模型对多种场景的泛化能力。此外,SparseViT 极大地降低了计算量(最高减少 80% 的 FLOPs),实现了参数效率与性能的兼顾,展现了其在多基准数据集上的卓越表现。SparseViT 有望为图像篡改检测领域的理论与应用研究提供新视角,为后续研究奠定基础。
SparseViT总体架构的设计概览图如下所示:
图1:SparseViT总体架构
主要的组件包含:
1. 负责高效特征捕获的 Sparse Self-Attention
Sparse Self-Attention 是 SparseViT 框架的核心组件,专注于在减少计算复杂度的同时高效捕获篡改图像中的关键特征即非语义特征。传统的自注意力机制由于patch进行token-to-token的注意力计算,导致模型对语义信息过度拟合,使得非语义信息在受到篡改后表现出的局部不一致性被忽视 。为此,Sparse Self-Attention 提出了基于稀疏编码的自注意力机制,如 \{ REF _Ref184761431 \h 图 2}所示, 通过对输入特征图施加稀疏性约束, 设输入的特征图 ,我们不是对 的整个特征上应用注意力,而是将特征分成形状为 的张量块,表示将特征图分解为 个大小为 的不重叠的张量块,分别在这些张量块上进行自注意力计算。
图2:稀疏自注意力
这一机制通过对特征图进行区域划分,使模型在训练中专注于非语义特征的提取,提升了对图像篡改伪影的捕捉能力。相比传统自注意力,Sparse Self-Attention 减少了约 80% 的 FLOPs,同时保留了高效的特征捕获能力,特别是在复杂场景中表现卓越。模块化的实现方式还允许用户根据需求对稀疏策略进行调整,从而满足不同任务的需求。
2. 负责多尺度特征融合的 Learnable Feature Fusion (LFF)
Learnable Feature Fusion (LFF) 是 SparseViT 中的重要模块,旨在通过多尺度特征融合机制提高模型的泛化能力和对复杂场景的适应性。不同于传统的固定规则特征融合方法,LFF 模块通过引入可学习参数,动态调整不同尺度特征的重要性,从而增强了模型对图像篡改伪影的敏感度。
LFF 通过从稀疏自注意力模块输出的多尺度特征中学习特定的融合权重,优先强化与篡改相关的低频特征,同时保留语义信息较强的高频特征。模块设计充分考虑了 IML 任务的多样化需求,既能针对微弱的非语义伪影进行细粒度处理,又能适应大尺度的全局特征提取。LFF 的引入显著提升了 SparseViT 在跨场景、多样化数据集上的性能,同时减少了无关特征对模型的干扰,为进一步优化 IML 模型性能提供了灵活的解决方案。
研究总结:
简而言之:
SparseViT具有以下四个贡献:
- 我们揭示了篡改图像的语义特征需要连续的局部交互来构建全局语义,而非语义特征由于其局部独立性,可以通过稀疏编码实现全局交互。
- 基于语义和非语义特征的不同行为,我们提出使用稀疏自注意机制自适应地从图像中提取非语义特征。
- 为了解决传统多尺度融合方法的不可学习性,我们引入了一种可学习的多尺度监督机制。
- 我们提出的SparseViT在不依赖手工特征提取器的情况下保持了参数效率,并在四个公共数据集上实现了最先进的(SoTA)性能和出色的模型泛化能力。 SparseViT通过利用语义特征和非语义特征之间的差异性,使模型能够自适应地提取在图像篡改定位中更为关键的非语义特征,为篡改区域的精准定位提供了全新的研究思路。相关代码和操作文档、使用教程已完全开源在GitHub上(https://github.com/scu-zjz/SparseViT)。该代码有着完善的更新计划,仓库将被长期维护,欢迎全球研究者使用和提出改进意见。
SparseViT的主要科研成员来自四川大学吕建成团队,合作方为澳门大学潘治文教授团队。
#1.58-bit FLUX
参数减少99.5%,媲美全精度FLUX!字节跳动等发布首个1.58-bit FLUX量化模型
字节跳动等机构发布的1.58-bit FLUX量化模型,该模型将FLUX视觉Transformer的参数减少99.5%,在保持与全精度FLUX相当的性能的同时,显著降低了存储需求和推理内存。通过采用高效的线性内核和无监督量化方法,1.58-bit FLUX在文本生成图像(T2I)基准测试中表现出色,展示了在大模型推理中的新SOTA。
文章链接:https://arxiv.org/pdf/2412.18653
项目链接:https://chenglin-yang.github.io/1.58bit.flux.github.io/
git主页:https://github.com/Chenglin-Yang
亮点分析
- 1.58-bit FLUX,第一个将 FLUX 视觉 Transformer 的参数(共 119 亿)减少 99.5% 至 1.58-bit 的量化模型,无需依赖图像数据,大幅降低存储需求。
- 开发了一个高效的线性内核,针对 1.58-bit 计算进行了优化,实现了显著的内存减少和推理加速。
- 证明了 1.58-bit FLUX 在具有挑战性的 T2I 基准测试中,性能与全精度 FLUX 模型相当。
总结速览
解决的问题
- 当前文本生成图像(T2I)模型,如 DALLE 3、Stable Diffusion 3 等,参数量巨大,推理时内存需求高,难以在资源有限的设备(如移动设备)上部署。
- 本文重点研究极低比特量化(1.58-bit)在 T2I 模型中的可行性,以减少存储和内存需求,同时提升推理效率。
提出的方案
- 选用 FLUX.1-dev 模型作为量化目标,通过后训练量化方法将其权重压缩为 1.58-bit(值限制为 {-1, 0, +1}),无需访问图像数据。
- 开发专用的低比特操作优化内核,进一步提升推理效率。
应用的技术
- 1.58-bit 权重量化:使用类似 BitNet b1.58 的方法,将模型的线性层权重压缩至 1.58-bit,并通过 2-bit 有符号整数存储权重,从而实现极低比特化。
- 无监督量化方法:完全依赖 FLUX.1-dev 模型本身的自监督机制,无需依赖混合精度方案或额外的训练数据。
- 定制化内核:针对低比特操作优化的推理内核,降低内存使用并缩短推理延迟。
达到的效果
- 存储效率:模型存储需求减少 7.7×,从 16-bit 压缩到 2-bit。
- 推理效率:推理时的内存使用减少 5.1×,推理延迟显著改善。
- 生成质量:在 GenEval 和 T2I Compbench 基准测试上,生成质量与全精度 FLUX 基本持平,验证了方案的有效性和实用性。
实验结果
设置
量化:使用一个校准数据集进行量化,数据集由 Parti-1k 数据集和 T2I CompBench 训练集的提示语组成,共计 7,232 条提示语。整个过程完全不依赖图像数据,不需要额外的数据集。量化将 FLUX 中 FluxTransformerBlock 和 FluxSingleTransformerBlock 的所有线性层权重压缩至 1.58-bit,占模型总参数的 99.5%。
评估:在 GenEval 数据集 和 T2I CompBench 验证集上评估 FLUX 和 1.58-bit FLUX,遵循官方的图像生成流程。
- GenEval 数据集:包含 553 条提示语,每条提示语生成 4 张图像。
- T2I CompBench 验证集:包含 8 个类别,每个类别有 300 条提示语,每条提示语生成 10 张图像,总计生成 24,000 张图像进行评估。
- 所有图像均以 1024 × 1024 的分辨率生成,适用于 FLUX 和 1.58-bit FLUX。
结果
性能:在 T2I Compbench 和 GenEval 基准测试中,1.58-bit FLUX 与全精度 FLUX 的性能表现相当,具体结果见表 1 和表 2。在应用自定义线性内核前后,性能变化微乎其微,进一步验证了实现的准确性。
效率:如下图 2 所示,1.58-bit FLUX 在模型存储和推理内存上取得了显著提升。在推理延迟方面,如下表 3 所示,特别是在低性能但易于部署的 GPU(如 L20 和 A10)上,改进更为显著。
结论与讨论
本文提出了 1.58-bit FLUX,将 99.5% 的 Transformer 参数量化至 1.58-bit,并通过自定义计算内核实现了以下改进:
- 存储需求减少:模型存储需求降低 7.7 倍。
- 推理内存减少:推理内存使用减少超过 5.1 倍。
尽管实现了这些压缩效果,1.58-bit FLUX 在 T2I 基准测试中表现出与全精度模型相当的性能,同时保持了较高的视觉质量。希望 1.58-bit FLUX 能够激励社区开发更适合移动设备的模型。
当前局限性
关于速度改进的局限性
- 尽管 1.58-bit FLUX 降低了模型大小和内存消耗,但由于缺乏激活值量化和更高级的内核优化,其延迟改进有限。
- 鉴于目前取得的成果,希望激励社区开发适用于 1.58-bit 模型的自定义内核实现。
关于视觉质量的局限性
- 如下图 1、图 3 和图 4 所示,1.58-bit FLUX 能生成与文本提示高度一致的生动逼真的图像,但在渲染超高分辨率细节时仍落后于原始 FLUX 模型。
- 计划在未来研究中缩小这一差距。
#基于计算机视觉实现海面漏油检测
海上石油泄漏是石油泄漏到海洋环境中造成的灾难性环境事件。石油泄漏对海洋生态系统、野生动物和沿海社区构成重大威胁,并可能造成长期深远的影响。
由于到达受影响地区的后勤困难,清理漏油是一项昂贵的工作。在派出清理人员之前,必须精确测量泄漏的特征,例如体积、厚度和范围,以最大限度地利用资源并节省成本。这时计算机视觉就成为必不可少的工具。
本将向您展示如何使用标记数据来训练实例分割模型,以便远程了解和评估漏油事件。
计算机视觉如何帮助清理漏油
从空中拍摄的石油泄漏高分辨率图像或视频可以使用计算机视觉模型进行分析,从而准确测量泄漏量。获取的信息可帮助专家确定特定泄漏最合适、最有效的清理方法。
例如,如果泄漏量相对较薄且分布广泛,则机械遏制和回收技术(如部署围油栏和撇油器)可能就足够了。另一方面,如果泄漏量较大或分布范围较大,则焚烧或使用化学分散剂可能更合适。
通过计算机视觉分析了解泄漏的特性,响应团队可以选择最具成本效益和环保的清理方法。
清理完成后,计算机视觉还可以促进对受影响区域的后期评估和监控。通过比较清洁前后的图像,专家可以评估清洁操作的有效性,识别任何残留污染,并在必要时规划进一步的补救措施。
将计算机视觉整合到石油泄漏应对流程中,在节省成本、高效分配资源和改善决策方面带来了显著的好处。
石油泄漏数据收集和标记
在本项目中,使用图像分割(特别是实例分割)来检测油的厚度。以下三个类用于标记数据集并检测油厚度:
- 彩虹
- 光泽
- 真彩色
本项目的漏油数据集来自Roboflow Universe上的开源图像。以下是项目中使用的示例图像。
https://universe.roboflow.com/tim-4ijf0/oil-spill-segmentation?ref=blog.roboflow.com
然后使用Roboflow Annotate或labelme对数据集进行标注:
在标注数据集中的所有图像之后,将生成数据集,以便下一步进行模型训练。
石油泄漏模型训练与测试
数据集准备好后,即可使用Roboflow Train进行训练,这不仅促进了模型训练过程,而且还对其进行了优化以实现无缝部署。
在这个项目中,重点是训练模型进行实例分割,从而能够准确检测和描绘图像中的各个物体。
如下图所示,该模型经过训练后,平均精度(mAP) 得分高达 81.3%。该得分证明该模型能够准确地检测和分割训练图像中的对象。
在 Roboflow 的测试阶段,该模型表现出了良好的结果,如下图所示。值得注意的是,该模型准确识别了被归类为“彩虹”的漏油,这证明该模型能够有效地从图像中检测和分类不同类型的漏油。
石油泄漏监测系统概述
Roboflow 云上训练的模型可通过 API 访问,从而对收到的图像或视频进行预测。
在石油泄漏检测系统中,可以设计一个系统架构,将嵌入摄像头和 GSM 模块的无人机用于检查海域并捕捉目标区域的图像。然后利用部署的模型将这些图像发送进行处理,以预测石油泄漏的存在和范围。
由此得出的预测结果可以为有关采取适当行动消除漏油的决策过程提供参考。
图像推理:
from ultralytics import YOLOmodel = YOLO("best.pt")
model.predict(source="oil_spill_drone.jpg", show=True, save=True, hide_labels=False, hide_cnotallow=False, cnotallow=0.5, save_txt=False, save_crop=False, line_thickness=2)
视频推理:
from ultralytics import YOLOmodel = YOLO("best.pt")
model.predict(source="drone_footage_oil_spill_original.mp4", show=True, save=True, hide_labels=False, hide_cnotallow=False, cnotallow=0.5, save_txt=False, save_crop=False, line_thickness=2)
决策应用程序接收预测结果,并应用预定义的标准或算法来评估漏油的严重程度和范围。根据这些信息,可以决定采取适当的行动来消除或减轻漏油。
这些决策可能涉及部署清洁人员、启动遏制措施或实施进一步评估。通过整合无人机、漏油推理应用程序和决策应用程序,该系统为高效的漏油检测和响应提供了全面的解决方案。
#使用Anomalib实现图像异常检测和定位
Anomalib 库的介绍是这样的:“Anomalib 是一个深度学习库,旨在收集最先进的异常检测算法,用于在公共和私有数据集上进行基准测试。Anomalib 提供了最近文献中描述的几种现成的异常检测算法实现...”。
https://github.com/openvinotoolkit/anomalib?source=post_page-----fb363639104f--------------------------------
Anomalib 是一个非常强大的库,可以处理与图像异常检测和定位相关的任务。数据管理以及不同最先进模型的使用都包含在易于使用的函数和 API 中。然而,有时文档会参差不齐且不清楚。本文中,我们想深入图像异常检测世界,分析库的每个步骤和所有有趣的细节,从自定义数据集构建到训练模型服务。
构建自定义数据集
Anomalib 允许我们使用专门的 API 将基准数据集用作MVTec。另一方面,并非每个数据集都具有 MVTec 的结构,也并非每个数据集都具有异常图像,其中异常区域被适当分割。
为了增强对库的信心,我通过简化实际工业项目的规范构建了一个玩具自定义数据集。问题如下。有一台带有许多组件的工业机器。对每个组件执行一系列操作,不时更改其排列。要求验证在每个步骤结束时组件的排列是否符合要求。
为了将机器及其组件图解化,我拿了一个木箱和四个矩形乐高积木,将它们放在一个矩形的角落。初始配置包括所有水平排列的乐高积木。第一个动作是将右上方的积木逆时针旋转 90 度,这样它就从水平方向垂直排列了。因此,左上方的积木逆时针旋转 90 度,然后是左下方,最后是右下方。如图 1 所示,每个最终状态都是每个步骤结束时的正确配置。
任何与正确配置不同的配置都应视为异常配置。实际上,这意味着对组件的操作未正确执行。例如,如图 2 所示,如果在第一步结束时,右上方的乐高积木未完全旋转 90 度,则相应的图像为异常图像,并且异常位于未充分旋转的乐高积木的对应位置。对于此应用,我选择乐高积木旋转 30、45 和 60 度的配置作为异常图像。
为了建立数据集,我用智能手机为每种正确和异常配置录制了一段视频,帧率为 30 fps,分辨率为 1920x1080 像素。在录制过程中,我移动相机从多个角度拍摄场景,甚至不是最佳角度,以便引入真实情况下的噪音。平均而言,我拍摄正确配置约 120 秒,而异常配置约 30 秒。此外,为了引入其他噪音,我将木箱放在带有多种颜色形状的地毯上,这样通过移动相机,背景中的形状也会发生变化。
使用以下脚本,我们可以从相应的视频中提取帧,从而针对每种不同的配置,我们收集标准和异常情况的图像。我对每张图像进行中心裁剪,并将其大小调整为 256x256 像素。
import os
import cv2def extract_frames(video_path, output_folder, final_size, offset):# Open the videovideo = cv2.VideoCapture(video_path)success, frame = video.read()count = 0# Iter to extract the frameswhile success:# Crop the frames to the center to obtain a square framemin_dim = min(frame.shape[0], frame.shape[1])center_x, center_y = frame.shape[1] // 2, frame.shape[0] // 2half_dim = min_dim // 2#print("min_dim: {} - center_x: {} - center_y: {} - half_dim: {}".format(min_dim, center_x, center_y, half_dim))cropped_frame = frame[center_y - half_dim - offset:center_y + half_dim - offset, center_x - half_dim:center_x + half_dim]# Resize the frames to final_sizeresized_frame = cv2.resize(cropped_frame, (final_size, final_size))frame_path = f"{output_folder}/frame_{count}.jpg"cv2.imwrite(frame_path, resized_frame) # Save the framesuccess, frame = video.read() # read the next framecount += 1video.release()cv2.destroyAllWindows()return count
对于每个步骤(我称之为类别),数据集具有以下数量的图像
CATEGORY: one_up
Normal 90_DEG - Number of images: 3638
Abnormal 60_DEG - Number of images: 955
Abnormal 45_DEG - Number of images: 967
Abnormal 30_DEG - Number of images: 965
------------------------------------------------------------------------
CATEGORY: two_up
Normal 90_DEG - Number of images: 3628
Abnormal 60_DEG - Number of images: 921
Abnormal 45_DEG - Number of images: 1042
Abnormal 30_DEG - Number of images: 889
------------------------------------------------------------------------
CATEGORY: three_up
Normal 90_DEG - Number of images: 3672
Abnormal 60_DEG - Number of images: 971
Abnormal 45_DEG - Number of images: 998
Abnormal 30_DEG - Number of images: 982
------------------------------------------------------------------------
CATEGORY: four_up
Normal 90_DEG - Number of images: 3779
Abnormal 60_DEG - Number of images: 996
Abnormal 45_DEG - Number of images: 1058
Abnormal 30_DEG - Number of images: 1015
数据加载
为了使用 Anomalib API 加载数据,然后在自定义数据集上训练和测试模型,文件夹树必须按照图 3 所示进行结构化。对于每个类别的每个文件夹,我必须有一个与正常图像相对应的子目录,即 90_DEG 子目录。在 90_DEG 文件夹的同一级别,必须有另一个名为“异常”的子目录。在异常子目录中,必须有与异常类型一样多的文件夹,即 30_DEG、45_DEG 和 60_DEG,每个文件夹都有相应的异常图像。
为了管理自定义数据集的数据,特别是将其拆分为训练、测试和验证子集,我们可以使用 Folder 类,如下所示。我将重点介绍 one_up 类别,但同样适用于其他类别。
from anomalib.data.image.folder import Folder
from anomalib import TaskType
from anomalib.data.utils import ValSplitMode# set the dataset root for a particular category
dataset_root = "/home/enrico/Projects/Image_Anomaly_Detection/dataset/images_lego_256/one_up"# Create the datamodule
datamodule = Folder(name="one_up",root=dataset_root,normal_dir="90_DEG",abnormal_dir="abnormal",task=TaskType.CLASSIFICATION,seed=42,normal_split_ratio=0.2, # default valueval_split_mode=ValSplitMode.FROM_TEST, # default valueval_split_ratio=0.5, # default valuetrain_batch_size=32, # default valueeval_batch_size=32, # default value#image_size=(512,512)
)# Setup the datamodule
datamodule.setup()
Folder 对象的属性必须填写如下:
- name:类别名称,即存储正常和异常图像的文件夹名称
- root:数据集的目录根,即“ one_up”目录的根
- normal_dir:存储正常图像的文件夹名称,在本例中为“ 90_DEG”
- unusual_dir:存储异常图像的文件夹名称,在本例中为“ abnormal”
- 任务:我们使用分类,因为数据集只有正常和异常图像。如果我们还有每个异常图像的分割掩码,我们可以使用分割
- 种子:每次重复相同的训练、验证和测试分割
- normal_split_ratio:在测试集不包含任何正常图像的情况下,拆分正常训练图像并添加到测试集的比例。默认情况下设置为 0.2
- val_split_mode:确定如何获取验证数据集。默认情况下设置为 FROM_TEST
- val_split_ratio:保留用于验证的训练或测试图像的比例。图像取自训练或测试集,具体取决于 val_split_mode。默认为 0.5
- train_batch_size 和 eval_batch_size:设置用于训练和验证模型的图像数量。默认情况下设置为 32
- image_size:用于设置图像宽度和高度的元组。这里进行了注释,因为我们已经将图像大小调整为 (256,256) 像素
一旦数据模块文件夹对象被实例化,我们就可以提取训练、验证和测试数据加载器来对图像批次进行迭代。图像会自动转换为在 0 和 1 之间标准化的 torch 张量。我们还可以提取与训练、验证和测试分割相对应的数据帧,检查不同数据集中正常和异常图像分布的一些统计数据,并将它们保存为 .csv 文件。
# Train images
i, data_train = next(enumerate(datamodule.train_dataloader()))
print(data_train.keys(), data_train["image"].shape) # it takes a batch of images
# for each key extract the first image
print("data_train['image_path'][0]: {} - data_train['image'][0].shape: {} - data_train['label'][0]: {} - torch.max(data_train['image][0]): {} - torch.min(data_train['image][0]): {}".format(data_train['image_path'][0], data_train['image'][0].shape, data_train['label'][0], torch.max(data_train['image'][0]), torch.min(data_train['image'][0])))
img_train = to_pil_image(data_train["image"][0].clone())# val images
i, data_val = next(enumerate(datamodule.val_dataloader()))
# for each key extract the first image
print("data_val['image_path'][0]: {} - data_val['image'][0].shape: {} - data_val['label'][0]: {}".format(data_val['image_path'][0], data_val['image'][0].shape, data_val['label'][0]))
img_val = to_pil_image(data_val["image"][0].clone())# test images
i, data_test = next(enumerate(datamodule.test_dataloader()))
# for each key extract the first image
print("data_test['image_path'][0]: {} - data_test['image'][0].shape: {} - data_test['label'][0]: {}".format(data_test['image_path'][0], data_test['image'][0].shape, data_test['label'][0]))
img_test = to_pil_image(data_test["image"][0].clone())# from the datamodule extract the train, val and test Pandas dataset and collect all the info in a csv
train_dataset = datamodule.train_data.samples
test_dataset = datamodule.test_data.samples
val_dataset = datamodule.val_data.samples# check the data distribution for each category in each data split
print("TRAIN DATASET FEATURES")
print(train_dataset.info())
print("")
print("IMAGE DISTRIBUTION BY CLASS")
print("")
desc_grouped = train_dataset[['label']].value_counts()
print(desc_grouped)
print("----------------------------------------------------------")
print("TEST DATASET FEATURES")
print(test_dataset.info())
print("")
print("IMAGE DISTRIBUTION BY CLASS")
print("")
desc_grouped = test_dataset[['label']].value_counts()
print(desc_grouped)
print("----------------------------------------------------------")
print("VAL DATASET FEATURES")
print(val_dataset.info())
print("")
print("IMAGE DISTRIBUTION BY CLASS")
print("")
desc_grouped = val_dataset[['label']].value_counts()
print(desc_grouped)datamodule.train_data.samples.to_csv(os.path.join("/home/enrico/Projects/Image_Anomaly_Detection/data", "datamodule_train.csv"), index=False)
datamodule.test_data.samples.to_csv(os.path.join("/home/enrico/Projects/Image_Anomaly_Detection/data", "datamodule_test.csv"), index=False)
datamodule.val_data.samples.to_csv(os.path.join("/home/enrico/Projects/Image_Anomaly_Detection/data", "datamodule_val.csv"), index=False)
dict_keys(['image_path', 'label', 'image']) torch.Size([32, 3, 256, 256])
data_train['image_path'][0]: /home/enrico/Projects/Image_Anomaly_Detection/dataset/images_lego_256/one_up/90_DEG/frame_3613.jpg - data_train['image'][0].shape: torch.Size([3, 256, 256]) - data_train['label'][0]: 0 - torch.max(data_train['image][0]): 0.9725490808486938 - torch.min(data_train['image][0]): 0.0
data_val['image_path'][0]: /home/enrico/Projects/Image_Anomaly_Detection/dataset/images_lego_256/one_up/90_DEG/frame_1000.jpg - data_val['image'][0].shape: torch.Size([3, 256, 256]) - data_val['label'][0]: 0
data_test['image_path'][0]: /home/enrico/Projects/Image_Anomaly_Detection/dataset/images_lego_256/one_up/90_DEG/frame_1003.jpg - data_test['image'][0].shape: torch.Size([3, 256, 256]) - data_test['label'][0]: 0TRAIN DATASET FEATURES
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2911 entries, 0 to 2910
Data columns (total 5 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 image_path 2911 non-null object1 label 2911 non-null object2 label_index 2911 non-null Int64 3 mask_path 2911 non-null object4 split 2911 non-null object
dtypes: Int64(1), object(4)
memory usage: 116.7+ KB
NoneIMAGE DISTRIBUTION BY CLASSlabel
DirType.NORMAL 2911
Name: count, dtype: int64
----------------------------------------------------------
TEST DATASET FEATURES
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1808 entries, 0 to 1807
Data columns (total 5 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 image_path 1808 non-null object1 label 1808 non-null object2 label_index 1808 non-null Int64 3 mask_path 1808 non-null object4 split 1808 non-null object
dtypes: Int64(1), object(4)
memory usage: 72.5+ KB
NoneIMAGE DISTRIBUTION BY CLASSlabel
DirType.ABNORMAL 1444
DirType.NORMAL 364
Name: count, dtype: int64
----------------------------------------------------------
VAL DATASET FEATURES
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1806 entries, 0 to 1805
Data columns (total 5 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 image_path 1806 non-null object1 label 1806 non-null object2 label_index 1806 non-null Int64 3 mask_path 1806 non-null object4 split 1806 non-null object
dtypes: Int64(1), object(4)
memory usage: 72.4+ KB
NoneIMAGE DISTRIBUTION BY CLASSlabel
DirType.ABNORMAL 1443
DirType.NORMAL 363
Name: count, dtype: int64
模型训练与测试
本文中,我不会关注模型的细节和架构。从Anomalib 文档的这个页面,我们可以找到库中实现的所有模型及其原始论文。接下来,我想重点介绍我为自定义数据集找到的最佳模型,即逆向蒸馏模型,并展示如何实现、训练和测试它。在我的 Github存储库中,您还可以找到如何训练和测试 Anomalib 中可用的其他模型。
首先,我实例化了模型。然后我在回调列表中设置了 ModelCheckpoint 和 EarlyStopping 对象。使用 ModelCheckpoint,您可以决定如何在验证阶段保存检查点。在这里,我设置了在每个时期结束时执行验证步骤的条件。因此,如果 AUROC 值大于前一步的值,那么我将覆盖检查点。使用 EarlyStopping,您可以决定如何停止训练过程。在这里,我设置了停止取决于 AUROC 指标趋势的条件。如果它不再超过等于耐心的一定时期数,那么训练就完成了。
然后我设置了记录器和引擎对象。训练开始使用引擎的 fit 函数,以数据模块和之前实例化的模型作为参数。应该记住,对于本次讨论,数据模块设置为读取与一个配置相关的数据。
from anomalib.models import ReverseDistillation
from anomalib import TaskType
from anomalib.data.image.folder import Folder
from anomalib.loggers import AnomalibWandbLogger
from anomalib.engine import Engine
from anomalib.deploy import ExportType
from lightning.pytorch.callbacks import EarlyStopping, ModelCheckpoint# 1 - instantiate the model
model = ReverseDistillation()# 2 - instantiate the callback for chepoint and early stopping
callbacks = [ModelCheckpoint(mode="max",mnotallow="image_AUROC",save_last=True,verbose=True,auto_insert_metric_name=True,every_n_epochs=1,),EarlyStopping(mnotallow="image_AUROC",mode="max",patience=patience,),
]# 3 - instantiate the logger
wandb_logger = AnomalibWandbLogger(project="image_anomaly_detection",name=name_wandb_experiment)# 4 - instantiate the engine
engine = Engine(max_epochs=max_epochs,callbacks=callbacks,pixel_metrics="AUROC",accelerator="auto", # \<"cpu", "gpu", "tpu", "ipu", "hpu", "auto">,devices=1,logger=wandb_logger,task=TaskType.CLASSIFICATION,
)# 5 - fit
print("Fit...")
engine.fit(datamodule=datamodule, model=model)# 6 - test
print("Test...")
engine.test(datamodule=datamodule, model=model)# 7 - export torch weights
print("Export weights...")
path_export_weights = engine.export(export_type=ExportType.TORCH,model=model)print("path_export_weights: ", path_export_weights)
当训练开始时,记录器会打印一些有关模型的信息,特别是可训练参数的数量和估计的维度。
训练完成后,我使用引擎的测试功能开始测试阶段。在这种情况下,引擎会加载测试数据加载器并将最佳模型应用于测试图像。最后,记录器会在测试集上打印 AUROC 和 F1 分数。在最后一步中,我以 torch 格式导出最佳模型的权重,以便我可以在单个图像的推理阶段使用它,如下所述。
结果非常令人印象深刻,即测试集上分类问题的 AUROC 为 0.9999,F1 分数为 0.9997。图 6 中的测试集混淆矩阵也证实了这一点。
测试集验证结果:
尽管二元分类问题的表现几乎完美,但热图显示,在 45_DEG 情况下,异常区域很好地集中在乐高积木周围。对于 30_DEG 和 60_DEG 的情况,预测的热图有点混乱,异常分数较低。
模型推理
有趣的是,如何仅在单个图像上测试模型,这就是在 Web 应用程序中发生的事情。使用 TorchInferencer 对象,我以 torch 格式加载最佳模型的权重。因此,一旦图像被加载和预处理,我就会应用 TorchInferencer 的预测函数来获取结果对象。此对象具有以下属性:
- pred_label:0 表示正常图像,1 表示异常图像
- pred_score:预测为异常图像的分数。因此,如果 pred_label 为 0,则为了确定 pred_score 是否正常,我使用 1-pred_score
- 图像:原始图像
- heat_map:测试图像的热图。区域越热,包含异常的概率就越高
- pred_mask:异常区域对应的黑白掩码
- 分割:根据提取的热图分割出异常区域
从掩模中我还可以提取与异常区域相对应的边界框,如下面的脚本所示。
import sys
from PIL import Image
from anomalib.deploy import TorchInferencer
import numpy as np
import cv2
from torch import as_tensor
from torchvision.transforms.v2.functional import to_dtype, to_image
import torch
from utils import show_image_list# 1 - instantiate the TorchInferencer
inferencer = TorchInferencer(path=path_torch_model,device="cpu")# 2 - load and preprocess the image
image = Image.open(path_image).convert("RGB")
image = image.resize((256, 256))
image = to_dtype(to_image(image), torch.float32, scale=True) if as_tensor else np.array(image) / 255.0# 3 - execute the prediction
result = inferencer.predict(image=image)# result.pred_score gives the score to be anomalous
if result.pred_label == 0:normal_score = 1 - result.pred_scoreprint("Normal - pred_score: {:.4f}".format(normal_score))
else:print("Abnormal - pred_score: {:.4f}".format(result.pred_score))# build the bounding box from the mask
image_bbox = result.image.copy()
# Find the contours of the white mask
contours, _ = cv2.findContours(result.pred_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Create the bbox around the white contours
for contour in contours:x, y, w, h = cv2.boundingRect(contour)cv2.rectangle(image_bbox, (x, y), (x+w, y+h), (255, 0, 0), 2)# stack three time the mask to simulate the three colour channels
mask = cv2.merge((result.pred_mask,result.pred_mask,result.pred_mask))show_image_list(list_images=[result.image, result.heat_map, result.segmentations, mask, image_bbox],list_titles=['image', 'heat_map', 'segmentations', 'mask', 'image_bbox'],num_cols=3,figsize=(20, 10),grid=False,title_fnotallow=20,path_image=path_result)
对 45_DEG 类的测试图像运行脚本,结果如下:
pred_score: 0.8513 - pred_label: 1
Abnormal - pred_score: 0.8513