新闻详情

新闻详情

首页 / 资讯中心 / 详情

Kornia 修复空批次几何变换的 ZeroDivisionError:`transform_points` 与 `PinholeCamera.project` 的 empty-batch 语义

发布时间:2026/11/5 10:45:58来源:尧图网络
Kornia 修复空批次几何变换的 ZeroDivisionError:`transform_points` 与 `PinholeCamera.project` 的 empty-batch 语义
Kornia 修复空批次几何变换的 ZeroDivisionErrortransform_points与PinholeCamera.project的 empty-batch 语义【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址: https://gitcode.com/gh_mirrors/ko/kornia导读本文围绕 Kornia 变更记录 changelog.d/4487.fixed.md对应上游 issue #4466展开剖析transform_points在“空变换批次 非空点轴”这一组合输入下引发的ZeroDivisionError崩溃及其修复方案。文章从底层0 // 0的成因出发结合 transform_points 源码、PinholeCamera.project 实现 与回归测试讲清 Kornia 对空批次empty batch输入的统一约定空输入应返回同形状的空输出而不是崩溃。读完你将掌握这一修复的完整来龙去脉以及在实际几何/相机管线中如何规避同类问题。一、问题背景Kornia 的空批次empty batch约定在 Kornia 的几何管线中张量普遍以批处理batched方式组织。例如 3D 点云形状为(B, N, 3)对应的齐次变换矩阵形状为(B, 4, 4)。当某些输入批次恰好为空batch size 为 0即B 0时Kornia 的既定语义是空输入进空输出出empty-in / empty-out对空集执行变换结果仍为空集且形状与输入保持一致这一约定对批处理数据加载、滑动窗口推理、无标注样本的预处理等场景至关重要——例如一张图像裁剪块image chip内没有任何标注点时变换逻辑不应中断整个管线。本变更记录所修复的正是这一约定被破坏的边角场景变换批次为空(0, 4, 4)而点张量的点轴非空(0, 5, 3)。注意这里点张量的 batch 轴也为 0但由于点轴N5非空旧实现会在广播broadcast变换矩阵时触发崩溃。二、崩溃根因展开变换矩阵时的0 // 0在修复前transform_points的核心逻辑依赖torch.repeat_interleave将变换矩阵广播到与点张量相同的 batch 数量。相关实现见 kornia/geometry/linalg.py广播部分位于repeats points_1.shape[0] // trans_01.shape[0] trans_01 torch.repeat_interleave(trans_01, repeatsint(repeats), dim0)当输入为trans_01.shape (0, 4, 4)空变换批次且points_1.shape (0, 5, 3)时points_1.shape[0] // trans_01.shape[0]即0 // 0Python 中整数0 // 0直接抛出ZeroDivisionError于是整个transform_points在真正开始矩阵乘法之前就崩溃了。值得注意的是0 // 0只有在两个 batch 维度都为 0时才会触发。若只有变换批次为空、点张量 batch 也完全为空(0, 0, 3)除数与被除数同为 0同样崩溃而若变换批次非空如(1, 4, 4)0 // 1 0反而能正常返回空结果。这正是该 bug 表现“不一致”的原因——同样是“空输入”有的形状能通过、有的形状崩溃。三、修复方案提前短路与除零保护本次修复对transform_points做了两处关键改动见 kornia/geometry/linalg.py1. 空点轴提前返回# No points to transform (e.g. an image chip with no annotations): transforming an empty set # yields the same empty set. Return early — the reshape below cannot infer -1 from a # 0-element tensor, so this also avoids a spurious crash on valid empty inputs. if points_1.shape[-2] 0: return points_1当点张量的点轴N 0时直接原样返回。除了规避0 // 0这一早退还有另一层原因后续points_1.reshape(-1, ...)需要从 0 元素张量推断-1维度-1无法从空张量推断本身也会引发运行时错误。提前返回同时规避了这一隐患。2. 除法加保护repeats points_1.shape[0] // trans_01.shape[0] if trans_01.shape[0] 0 else 0当变换批次为空trans_01.shape[0] 0时不再执行除法而是直接将repeats置为 0。此时torch.repeat_interleave对空张量的 repeat 次数为 0结果仍为空张量随后的torch.bmm在空输入下自然产出空输出最终返回与输入形状一致的空结果。3. 修复后的完整行为修复后transform_points的输入输出对应关系为变换矩阵形状点张量形状修复前行为修复后行为(B, 4, 4)B0(B, N, 3)N0正常变换正常变换不变(B, 4, 4)(B, 0, 3)reshape 崩溃或0//0原样返回空点集(0, 4, 4)(0, 5, 3)ZeroDivisionError0//0返回(0, 5, 3)空结果(1, 4, 4)(0, 5, 3)正常返回空结果正常返回空结果不变另外需要说明transform_points的形状校验linalg.py#L203-L210要求两个输入 batch 大小相等或变换批次为 1且最后一维相差 1如 4x4 变换对应 3 维点这些校验在修复前后保持一致未做放宽。四、PinholeCamera.project的连带修复ZeroDivisionError不仅影响transform_points本身还通过调用链传染给了PinholeCamera.project。从 kornia/geometry/camera/pinhole.py#L382-L419 可以看到其投影实现def project(self, point_3d: torch.Tensor) - torch.Tensor: if len(point_3d.shape) 2: raise ValueError(fInput must be at least a 2D tensor. Got {point_3d.shape}) P self.intrinsics self.extrinsics return convert_points_from_homogeneous(transform_points(P, point_3d))project将内参矩阵与外参矩阵相乘得到投影矩阵P形状(B, 4, 4)后直接委托给transform_points完成齐次变换与透视除法。因此当相机批次为空内参/外参为(0, 4, 4)、点张量为(0, 3)时旧实现恰好能“侥幸”通过而当点张量为(0, N, 3)N0时transform_points内部的0 // 0崩溃被直接继承project也随之抛ZeroDivisionError。修复transform_points后PinholeCamera.project对空相机批次 任意点轴形状的空点集均能正确返回空结果无需单独改动project本身——这正是“在底层修复、在上层受益”的典型回归修复模式。从源码结构看kornia.geometry.pose中的同名transform_points入口以及convert_points_from_homogeneous的调用路径也遵循同样的 empty-in/empty-out 约定。五、回归测试如何验证修复本次修复配有专门的回归测试覆盖了此前崩溃的精确输入组合1.transform_points空批次测试见 tests/geometry/test_linalg.py#L56-L79pytest.mark.parametrize(num_dims, [2, 3]) pytest.mark.parametrize(points_shape, [(0, 1), (0, 5)]) def test_transform_points_empty_batch_with_points(self, num_dims, points_shape, device, dtype): # An empty transform batch with a non-empty point axis divided 0 // 0 while expanding the # transforms (kornia#4466); it must return the same empty shape as a B1 transform does. points torch.zeros(*points_shape, num_dims, devicedevice, dtypedtype) empty_trans torch.eye(num_dims 1, devicedevice, dtypedtype).expand(0, -1, -1) single_trans torch.eye(num_dims 1, devicedevice, dtypedtype)[None] out kgl.transform_points(empty_trans, points) assert out.shape points.shape assert out.dtype dtype assert out.shape kgl.transform_points(single_trans, points).shape该测试的断言设计值得注意空批次的结果形状必须与B1变换作用于同一点集的结果形状一致即空输入的结果语义应与“只有一个变换”时的广播结果对齐而不是凭空多出维度。2.PinholeCamera.project继承修复测试见 tests/geometry/camera/test_pinhole.py#L923-L931def test_project_an_empty_batch_with_a_point_axis_4466(self, device, dtype): # Regression for kornia#4466: an empty camera batch projected (0, 3) points but raised # ZeroDivisionError on (0, N, 3), inside transform_points. trans torch.eye(4, devicedevice, dtypedtype).expand(0, 4, 4) empty torch.zeros(0, devicedevice, dtypedtype) camera kornia.geometry.camera.PinholeCamera(trans, trans, empty, empty) assert camera.project(torch.zeros(0, 3, devicedevice, dtypedtype)).shape (0, 2) assert camera.project(torch.zeros(0, 1, 3, devicedevice, dtypedtype)).shape (0, 1, 2)测试同时验证了(0, 3)与(0, 1, 3)两种点形状前者是修复前就能通过的路径后者是修复前崩溃的路径两者修复后均返回正确形状的空张量。此外 tests/geometry/camera/test_pinhole.py#L900-L921 还验证了空相机批次在构造、形状与 dtype 上的一致性以及kornia.geometry.camera.project_points自由函数遵循同样的空进空出约定。六、对开发者代码的影响与建议从本次修复可以提炼出几条对 Kornia 使用者有价值的实践升级后行为变化是“变好”而非“破坏”修复只影响此前抛异常的输入组合。如果你的代码曾依赖捕获ZeroDivisionError来识别空批次升级后需改为直接检查输出形状如out.shape[0] 0或提前判断输入是否为空因为异常不再抛出。空批次语义是 Kornia 的通用约定从 transform_points 到 PinholeCamera.project再到PinholeCamera构造器的空批次支持见 test_pinhole.py#L900-L931 中对kornia#4281的回归Kornia 正在系统性地统一“空输入 → 空输出”的约定。在自己封装几何工具时建议对 batch 维度为 0 的输入做短路返回避免在0 // 0、reshape(-1)等位置踩坑。形状校验仍然有效修复并未放宽输入合法性检查。transform_points仍要求 batch 相等或变换批次为 1linalg.py#L205-L208project仍要求点张量至少为 2 维pinhole.py#L416-L417非法形状依旧会以ValueError明确拒绝便于尽早发现调用方错误。小结变更 4487.fixed.md 修复的是一个小而典型的边界缺陷transform_points在空变换批次配合非空点轴时因0 // 0抛出ZeroDivisionError并通过调用链波及PinholeCamera.project。修复通过“空点轴提前返回 除零保护”双保险让空批次输入在任意形状组合下都稳定返回同形状空结果并配套了 test_linalg.py 与 test_pinhole.py 两组回归测试锁定行为。这一修复也再次印证了 Kornia 几何模块“空进空出”的设计约定为批处理数据管线的健壮性提供了保障。【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址: https://gitcode.com/gh_mirrors/ko/kornia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/4 15:56:54

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/4 22:55:41

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/4 17:01:23

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/4 12:33:12

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/5 4:24:57

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/5 4:24:57

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉