[{"data":1,"prerenderedAt":359},["ShallowReactive",2],{"content-query-J0Y8FVqWaD":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"cover":11,"type":12,"category":13,"body":14,"_type":353,"_id":354,"_source":355,"_file":356,"_stem":357,"_extension":358},"/technology-blogs/zh/2026-1-13","zh",false,"","开源之夏｜侯博森：基于昇思MindSpore的MVSNet跨框架迁移与实践","将经典的多视角立体匹配模型 MVSNet 从 PyTorch 框架迁移至昇思MindSpore AI框架","2026-1-13","https://obs-mindspore-file.obs.cn-north-4.myhuaweicloud.com/file/2025/06/06/1a18a46ef03442ea8f8d83ba33b0a7af.png","technology-blogs","开发者说",{"type":15,"children":16,"toc":350},"root",[17,25,36,46,54,82,90,98,106,111,116,123,128,136,144,149,157,162,170,175,193,198,206,211,218,226,234,242,247,270,278,286,297,302,313,318,329,334,345],{"type":18,"tag":19,"props":20,"children":22},"element","h1",{"id":21},"开源之夏侯博森基于昇思mindspore的mvsnet跨框架迁移与实践",[23],{"type":24,"value":8},"text",{"type":18,"tag":26,"props":27,"children":29},"div",{"style":28},"text-align: center;",[30],{"type":18,"tag":31,"props":32,"children":35},"img",{"src":33,"style":34,"alt":7},"/category/information/technology-blogs/banner/2026-1-13/1.jpg","display: block;margin: 0 auto;max-width:70%",[],{"type":18,"tag":37,"props":38,"children":39},"p",{},[40],{"type":18,"tag":41,"props":42,"children":43},"strong",{},[44],{"type":24,"value":45},"# 01",{"type":18,"tag":37,"props":47,"children":48},{},[49],{"type":18,"tag":41,"props":50,"children":51},{},[52],{"type":24,"value":53},"项目介绍",{"type":18,"tag":55,"props":56,"children":57},"ul",{},[58,64,69],{"type":18,"tag":59,"props":60,"children":61},"li",{},[62],{"type":24,"value":63},"项目名称：基于MindSpore和多视角立体匹配技术的稠密重建模型",{"type":18,"tag":59,"props":65,"children":66},{},[67],{"type":24,"value":68},"项目描述：本项目旨在将经典的多视角立体匹配模型 MVSNet 从 PyTorch 框架迁移至昇思MindSpore AI框架，实现完整的训练与推理部署功能，为昇思在三维重建领域提供新的解决方案，在计算机视觉领域的应用提供技术支撑。",{"type":18,"tag":59,"props":70,"children":71},{},[72,74],{"type":24,"value":73},"项目源码链接：",{"type":18,"tag":75,"props":76,"children":80},"a",{"href":77,"rel":78},"https://github.com/mindspore-courses/competition/tree/master/summer-ospp/MVSNet_MindSpore",[79],"nofollow",[81],{"type":24,"value":77},{"type":18,"tag":37,"props":83,"children":84},{},[85],{"type":18,"tag":41,"props":86,"children":87},{},[88],{"type":24,"value":89},"# 02",{"type":18,"tag":37,"props":91,"children":92},{},[93],{"type":18,"tag":41,"props":94,"children":95},{},[96],{"type":24,"value":97},"MVSNet迁移思路拆解",{"type":18,"tag":37,"props":99,"children":100},{},[101],{"type":18,"tag":41,"props":102,"children":103},{},[104],{"type":24,"value":105},"1、架构分析与技术选型：",{"type":18,"tag":37,"props":107,"children":108},{},[109],{"type":24,"value":110},"项目首先对 PyTorch 版 MVSNet 的核心模块，包括特征提取、代价体构建、正则化网络、深度回归等模块进行结构拆解与逻辑分析，梳理数据流向与依赖关系，针对 MindSpore 的 API 特性，对 PyTorch 特有操作进行等效替换，重构数据加载与预处理流程。",{"type":18,"tag":37,"props":112,"children":113},{},[114],{"type":24,"value":115},"分步实现各功能模块的 MindSpore 适配，MVSNet的核心模块对标。",{"type":18,"tag":26,"props":117,"children":118},{"style":28},[119],{"type":18,"tag":31,"props":120,"children":122},{"src":121,"style":34,"alt":7},"/category/information/technology-blogs/banner/2026-1-13/2.jpg",[],{"type":18,"tag":37,"props":124,"children":125},{},[126],{"type":24,"value":127},"如上图，MVSNet的核心模块包括特征提取，代价体构建，正则话网络，深度回归等模块，该网络的输入是参考视角和源视角的图像和相机内外参数，输出是参考视角的深度图。在生成完所有参考视角深度图之后，方法将所有深度图融合为点云。",{"type":18,"tag":37,"props":129,"children":130},{},[131],{"type":18,"tag":41,"props":132,"children":133},{},[134],{"type":24,"value":135},"2、核心实现步骤：",{"type":18,"tag":37,"props":137,"children":138},{},[139],{"type":18,"tag":41,"props":140,"children":141},{},[142],{"type":24,"value":143},"步骤一：源码解读与数据准备",{"type":18,"tag":37,"props":145,"children":146},{},[147],{"type":24,"value":148},"深入研读 PyTorch 版 MVSNet 源码，梳理网络结构、数据格式要求及训练流程逻辑，同时下载 DTU、TanksAndTemples 数据集，明确数据组织形式与读写需求。",{"type":18,"tag":37,"props":150,"children":151},{},[152],{"type":18,"tag":41,"props":153,"children":154},{},[155],{"type":24,"value":156},"步骤二： 数据加载模块适配",{"type":18,"tag":37,"props":158,"children":159},{},[160],{"type":24,"value":161},"针对 MindSpore 不直接支持字典返回的特性，设计数据类型转换方案，将字典格式数据显式转为 NumPy 数组，通过 GeneratorDataset 指定数据名称，完成 DTU、TanksAndTemples 数据集的 MindSpore 适配。编写数据加载测试代码，验证数据读取的完整性与正确性。",{"type":18,"tag":37,"props":163,"children":164},{},[165],{"type":18,"tag":41,"props":166,"children":167},{},[168],{"type":24,"value":169},"步骤三： 核心模块迁移与单元测试",{"type":18,"tag":37,"props":171,"children":172},{},[173],{"type":24,"value":174},"依次迁移每一个核心模块：",{"type":18,"tag":55,"props":176,"children":177},{},[178,183,188],{"type":18,"tag":59,"props":179,"children":180},{},[181],{"type":24,"value":182},"特征提取网络：基于 MindSpore 的 nn.Conv2d、nn.ReLU 等算子，实现 8 层共享参数 CNN 的等效迁移，确保输出 32 通道特征图；",{"type":18,"tag":59,"props":184,"children":185},{},[186],{"type":24,"value":187},"代价体构建模块：通过 MindSpore 的矩阵运算 API 实现可微分单应性变换，完成视锥体采样与特征体构造，基于方差运算生成代价体；",{"type":18,"tag":59,"props":189,"children":190},{},[191],{"type":24,"value":192},"正则化网络与深度回归：用 MindSpore 的 nn.Conv3d 实现 3D U-Net 正则化模块，通过 Softmax 与 Soft argmin 完成深度概率图生成与初始深度图计算，适配深度图优化的残差学习逻辑。",{"type":18,"tag":37,"props":194,"children":195},{},[196],{"type":24,"value":197},"每个模块在迁移的时候需要对照API对照表进行一一对比，包括CNN的默认参数也需要确认是否一致，否则会对模型的效果产生很大的影响。完成任何一个模块，都要单独拿出来进行测试：给PyTorch和MindSpore的模块同时输入完全相同的数据，测试前向传播的结果是否一致。",{"type":18,"tag":37,"props":199,"children":200},{},[201],{"type":18,"tag":41,"props":202,"children":203},{},[204],{"type":24,"value":205},"步骤四： 整体训练与性能评估",{"type":18,"tag":37,"props":207,"children":208},{},[209],{"type":24,"value":210},"训练转化完的模型并进行 DTU 数据集的测试，编写 eval.sh 评估脚本，支持深度图生成、点云融合与量化指标计算，与 PyTorch 版 MVSNet 在 DTU 数据集上进行性能对标，验证迁移模型的准确性。",{"type":18,"tag":26,"props":212,"children":213},{"style":28},[214],{"type":18,"tag":31,"props":215,"children":217},{"src":216,"style":34,"alt":7},"/category/information/technology-blogs/banner/2026-1-13/3.jpg",[],{"type":18,"tag":37,"props":219,"children":220},{},[221],{"type":18,"tag":41,"props":222,"children":223},{},[224],{"type":24,"value":225},"# 03",{"type":18,"tag":37,"props":227,"children":228},{},[229],{"type":18,"tag":41,"props":230,"children":231},{},[232],{"type":24,"value":233},"跨框架迁移的挑战：问题定位与解决策略",{"type":18,"tag":37,"props":235,"children":236},{},[237],{"type":18,"tag":41,"props":238,"children":239},{},[240],{"type":24,"value":241},"PyTorch 与 MindSpore 数据集格式不兼容",{"type":18,"tag":37,"props":243,"children":244},{},[245],{"type":24,"value":246},"PyTorch 的 Dataloader 返回字典格式数据，包含图像、相机参数等多类型信息，但 MindSpore 的 GeneratorDataset 不直接支持字典返回，且 DTU 数据集需要返回字符串、字典等格式数据，无法直接适配。",{"type":18,"tag":55,"props":248,"children":249},{},[250,260],{"type":18,"tag":59,"props":251,"children":252},{},[253,258],{"type":18,"tag":41,"props":254,"children":255},{},[256],{"type":24,"value":257},"探索过程：",{"type":24,"value":259}," 最初尝试直接复用 PyTorch 的数据读取逻辑，但运行时出现数据类型不匹配报错；随后尝试在 Dataloader 中直接转换数据类型，但导致部分相机参数信息丢失。",{"type":18,"tag":59,"props":261,"children":262},{},[263,268],{"type":18,"tag":41,"props":264,"children":265},{},[266],{"type":24,"value":267},"最终方案：",{"type":24,"value":269}," 首先解析 PyTorch 字典中的各字段数据，将字符串类型参数转为 NumPy 数组，图像数据保持张量格式并兼容 MindSpore 要求；然后通过 GeneratorDataset 的 column_names 参数指定每个返回数据的名称，确保数据与网络输入接口对齐，这个其实是两个框架的特性区别，只需要稍微修改返回信息的逻辑即可。",{"type":18,"tag":37,"props":271,"children":272},{},[273],{"type":18,"tag":41,"props":274,"children":275},{},[276],{"type":24,"value":277},"# 04",{"type":18,"tag":37,"props":279,"children":280},{},[281],{"type":18,"tag":41,"props":282,"children":283},{},[284],{"type":24,"value":285},"关于开源、成长与选择",{"type":18,"tag":55,"props":287,"children":288},{},[289],{"type":18,"tag":59,"props":290,"children":291},{},[292],{"type":18,"tag":41,"props":293,"children":294},{},[295],{"type":24,"value":296},"是什么机缘让你在开源之夏的诸多项目中选择了昇思MindSpore？",{"type":18,"tag":37,"props":298,"children":299},{},[300],{"type":24,"value":301},"侯博森：一方面，昇思MindSpore 在性能优化、易用性上有着独特优势，且在三维视觉领域的生态建设仍有较大空间，希望通过自己的努力为昇思框架贡献力量；另一方面，MVSNet 作为三维重建领域的经典模型，其迁移工作具有明确的应用价值，能够为后续相关研究提供基础。除此之外，之前有一个工作叫做EPP-MVSNet，是基于MindSpore架构的多视角立体匹配网络，是昇思MindSpore团队已经发表在ICCV上的论文，在早些时候我注意到了这篇论文，但是因为当时对MindSpore并不熟悉所以没仔细研究，我作为三维视觉为研究方向的研究生，这一次刚好借这个机会仔细研究了一下。",{"type":18,"tag":55,"props":303,"children":304},{},[305],{"type":18,"tag":59,"props":306,"children":307},{},[308],{"type":18,"tag":41,"props":309,"children":310},{},[311],{"type":24,"value":312},"这次跨框架迁移的经历，和你以前项目相比，感觉最大的不同是什么？",{"type":18,"tag":37,"props":314,"children":315},{},[316],{"type":24,"value":317},"侯博森：这次经历与我过去的项目有着根本性的不同，核心在于这是一项专门的“跨框架迁移”工作。以往在单一框架内开发时，我主要专注于算法实现本身；而这次的核心任务，则是深入理解两个框架的设计逻辑，并系统性地解决它们在API接口、数据格式与算子行为上的兼容性问题。例如，我需要为PyTorch中的grid_sample等操作找到MindSpore中的功能等效实现，并为此自主整理了详细的API映射表。这也改变了我的工作方式：通用AI工具的辅助作用变得有限，更多时候需要我深入查阅官方文档、在社区中寻找线索并进行自主调试；同时，解决问题的途径也从依赖团队内部经验，转变为积极地从MindSpore开源社区中获取支持并与广大开发者交流。整个过程更像是一次深度的框架原理探索与实践，让我对如何在不同技术生态间进行转换和适配有了全新的认识。",{"type":18,"tag":55,"props":319,"children":320},{},[321],{"type":18,"tag":59,"props":322,"children":323},{},[324],{"type":18,"tag":41,"props":325,"children":326},{},[327],{"type":24,"value":328},"在这个过程中，你对“开源”这个词的理解，有没有发生一些变化？",{"type":18,"tag":37,"props":330,"children":331},{},[332],{"type":24,"value":333},"侯博森：有的，变化很大。以前觉得开源主要就是“把代码公开”。亲身参与后才真正感受到，它的核心在于“协作”与“共享”。我不是一个人在战斗，项目过程中我大量参考了社区的文档、示例代码，遇到棘手问题时会去论坛搜索，也和导师、其他开发者交流。同时，我也努力让自己的工作能更好地被他人使用，比如写清晰的注释、整理完整的文档。我的代码和经验以后也能帮助其他人，这种双向的、持续的价值流动，才是开源生态最有活力的地方。",{"type":18,"tag":55,"props":335,"children":336},{},[337],{"type":18,"tag":59,"props":338,"children":339},{},[340],{"type":18,"tag":41,"props":341,"children":342},{},[343],{"type":24,"value":344},"对于未来也想参与开源，参与昇思MindSpore的学弟学妹，你有什么建议吗？",{"type":18,"tag":37,"props":346,"children":347},{},[348],{"type":24,"value":349},"侯博森：我有几点比较深的体会。第一，别过度依赖“万能”的AI工具，沉下心阅读官方文档、教程是第一位的。第二，培养自主排查问题的能力，遇到报错先别慌，尝试用打印日志、写小单元测试等方式缩小范围，这个过程本身就是极好的学习。第三，勇敢且礼貌地利用社区，论坛、Issue列表、技术群都是宝库，但提问前最好先搜索，提问时把背景、现象、自己试过的方法说清楚。最后，要有“代码即文档”的意识，你写的清晰结构和注释，你整理的README，就是对下一位开发者最好的帮助。当你解决的问题和积累的经验能够回馈社区时，那种成就感远超单纯完成一个项目。",{"title":7,"searchDepth":351,"depth":351,"links":352},4,[],"markdown","content:technology-blogs:zh:2026-1-13.md","content","technology-blogs/zh/2026-1-13.md","technology-blogs/zh/2026-1-13","md",1776506118303]