<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>jujimeizuo · Blog</title>
  
  
  <link href="https://blog.jujimeizuo.cn/atom.xml" rel="self"/>
  
  <link href="https://blog.jujimeizuo.cn/"/>
  <updated>2025-12-19T13:50:29.068Z</updated>
  <id>https://blog.jujimeizuo.cn/</id>
  
  <author>
    <name>jujimeizuo</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>HLA-Round-LiHu-Lake-Half-Marathon-2025</title>
    <link href="https://blog.jujimeizuo.cn/2025/11/13/HLA-Round-LiHu-Lake-Half-Marathon-2025/"/>
    <id>https://blog.jujimeizuo.cn/2025/11/13/HLA-Round-LiHu-Lake-Half-Marathon-2025/</id>
    <published>2025-11-13T07:22:22.000Z</published>
    <updated>2025-12-19T13:50:29.068Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>2025.11.2 蠡湖半程马拉松，人生首半马，安全完赛！</p></blockquote><h2 id="赛前"><a href="#赛前" class="headerlink" title="赛前"></a>赛前</h2><ul><li>基本上每周都会跑 2-3 次，距离在 5km 到 10km 之间，最远跑过一次 15km，都没有跑过特别特别长距离。然而在这次比赛前，3 个月内没有训练过，忙论文和秋招。</li><li>先前跑步数据：<a href="https://running-page-nu-seven.vercel.app/">https://running-page-nu-seven.vercel.app/</a></li><li>领物资</li></ul><img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-1.jpg" width="50%"><h2 id="赛中"><a href="#赛中" class="headerlink" title="赛中"></a>赛中</h2><ul><li>早上 5 点半起床，微微冷，只穿了短袖短裤和一件外套保暖，去食堂吃早饭，食堂的早饭都还没上齐hhh，吃了一个包子、一根油条、一个球、一杯豆浆；</li><li>坐地铁去起点，花了得 40mins，车上全是参赛选手，个个都是跑鞋；</li><li>7 点半起跑，但我是 E 区，所以 7 点 50 起跑；</li><li><strong>比赛开始了！</strong></li><li>0-5km 状态很好，很享受；</li><li>5km-10km 状态良好，从第 5km 开始，每隔两公里就有补给站（饮料、水、医疗站、香蕉、能量胶、喷洒、海绵，冰袋等等）；</li><li>10km-15km 状态就不行了，虽然心率没多快，但是两条腿开始酸痛，时不时走一走缓一缓；</li><li>15-20km 都是上坡啊，几乎跑不动了，双腿灌了铅一样，估计跑了 2km，走了 3km；</li><li>最后 1km 冲刺，给自己加油，在 2’50 之前冲线，也做到了；</li></ul><div style="display:flex; gap:8px;">    <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-2.jpg" width="50%">    <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-3.jpg" width="50%"></div><h2 id="赛后"><a href="#赛后" class="headerlink" title="赛后"></a>赛后</h2><ul><li>完赛后领完赛包，挺丰富的，不错不错；</li><li>从比完赛的第一天开始的一个星期之内，第一天完全不能动（十分痛苦），第二天勉强动一动，第三天能慢慢走，然后逐渐恢复；</li><li>希望可以再次参加马拉松，做好训练和规划，pb 2’30 应该没问题吧？</li></ul><div style="display:flex; gap:8px;">  <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-5.jpg" style="width:25%;">  <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-4.jpg" style="width:25%;">  <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-6.jpg" style="width:25%;">  <img src="/images/2025/11/HLA-Round-LiHu-Lake-Half-Marathon-2025-7.jpg" style="width:25%;"></div><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/11/13/HLA-Round-LiHu-Lake-Half-Marathon-2025/">https://blog.jujimeizuo.cn/2025/11/13/HLA-Round-LiHu-Lake-Half-Marathon-2025/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;2025.11.2 蠡湖半程马拉松，人生首半马，安全完赛！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;赛前&quot;&gt;&lt;a href=&quot;#赛前&quot; class=&quot;headerlink&quot; title=&quot;赛前&quot;&gt;&lt;/a&gt;赛前&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;</summary>
      
    
    
    
    
    <category term="Running" scheme="https://blog.jujimeizuo.cn/tags/Running/"/>
    
  </entry>
  
  <entry>
    <title>fall-campus-recruitment-2026</title>
    <link href="https://blog.jujimeizuo.cn/2025/11/05/fall-campus-recruitment-2026/"/>
    <id>https://blog.jujimeizuo.cn/2025/11/05/fall-campus-recruitment-2026/</id>
    <published>2025-11-05T13:30:13.000Z</published>
    <updated>2025-12-19T08:10:13.926Z</updated>
    
    <content type="html"><![CDATA[<blockquote><ul><li>bg 双非本 211 硕，无论文有竞赛，C++ 选手。</li><li>投递岗位包括：<br>1. 后端开发<br>2. 服务端开发（包括游戏）<br>3. 存储开发<br>4. 自动驾驶方向</li></ul><p>投递了相当多公司，几乎都为大厂，少量中小厂、初创，全都挂完了，最后拿到个别 offer。</p></blockquote><h2 id="Post"><a href="#Post" class="headerlink" title="Post"></a>Post</h2><table><thead><tr><th align="center">Company</th><th align="center">job</th><th align="center">Result</th></tr></thead><tbody><tr><td align="center">商汤</td><td align="center">大装置-AI 存储 Infra</td><td align="center">笔试-&gt;一面-&gt;二面-&gt;hr面-&gt;oc</td></tr><tr><td align="center">蔚来</td><td align="center">数据算法-云平台研发</td><td align="center">笔试-&gt;一面-&gt;二面-&gt;三面-&gt;hr面-&gt;oc</td></tr><tr><td align="center">佑驾创新</td><td align="center">C++开发</td><td align="center">笔试-&gt;一面-&gt;二面-&gt;hr面-&gt;oc</td></tr><tr><td align="center">经纬恒润</td><td align="center">C++开发</td><td align="center">一面-&gt;笔试-&gt;二面-&gt;hr面-&gt;oc</td></tr><tr><td align="center">网易雷火</td><td align="center">游戏服务端开发</td><td align="center">笔试-&gt;一面-&gt;二面-&gt;三面挂</td></tr><tr><td align="center">拼多多</td><td align="center">服务端研发</td><td align="center">笔试-&gt;一面-&gt;二面挂</td></tr><tr><td align="center">字节跳动</td><td align="center">音视频 SDK</td><td align="center">一面-&gt;二面挂</td></tr><tr><td align="center">同花顺</td><td align="center">AIME 专项 AIGC</td><td align="center">一面</td></tr><tr><td align="center">小马智行</td><td align="center">研发</td><td align="center">一面后无消息</td></tr><tr><td align="center">元戎启行</td><td align="center">软件研发</td><td align="center">一面挂</td></tr><tr><td align="center">百度</td><td align="center">C++研发</td><td align="center">一面挂</td></tr><tr><td align="center">小米</td><td align="center">影像软件开发</td><td align="center">笔试-&gt;一面后无消息</td></tr><tr><td align="center">滴滴</td><td align="center">存储研发</td><td align="center">笔试-&gt;一面挂</td></tr><tr><td align="center">小红书</td><td align="center">搜广推引擎开发</td><td align="center">笔试-&gt;一面挂</td></tr><tr><td align="center">九识智能</td><td align="center">仿真引擎开发</td><td align="center">笔试过加微信无消息</td></tr><tr><td align="center">柠檬微趣</td><td align="center">游戏服务端研发</td><td align="center">笔试过后转岗客户端，拒面</td></tr><tr><td align="center">高仙机器人</td><td align="center">C++开发</td><td align="center">拒面</td></tr><tr><td align="center">bilibili</td><td align="center">服务端开发</td><td align="center">笔试挂</td></tr><tr><td align="center">京东</td><td align="center">后端开发</td><td align="center">笔试后无消息</td></tr><tr><td align="center">蚂蚁</td><td align="center">C++ 研发</td><td align="center">笔试-&gt;简历挂</td></tr><tr><td align="center">得物</td><td align="center">算法C++</td><td align="center">笔试-&gt;简历挂</td></tr><tr><td align="center">美团</td><td align="center">后端开发</td><td align="center">笔试后放弃</td></tr><tr><td align="center">科大讯飞</td><td align="center">C++研发</td><td align="center">无消息</td></tr><tr><td align="center">Oppo</td><td align="center">软件开发</td><td align="center">无消息</td></tr><tr><td align="center">Vivo</td><td align="center">图像算法</td><td align="center">无消息</td></tr><tr><td align="center">华为</td><td align="center">软件开发</td><td align="center">无消息</td></tr><tr><td align="center">腾讯</td><td align="center">后台开发</td><td align="center">无消息</td></tr><tr><td align="center">小鹏</td><td align="center">C++研发</td><td align="center">无消息</td></tr><tr><td align="center">博世</td><td align="center">软件开发</td><td align="center">无消息</td></tr><tr><td align="center">影石</td><td align="center">C++开发</td><td align="center">无消息</td></tr><tr><td align="center">轻舟智航</td><td align="center">自动驾驶软件开发</td><td align="center">无消息</td></tr><tr><td align="center">猿辅导</td><td align="center">AI 服务端研发</td><td align="center">无消息</td></tr><tr><td align="center">帆软</td><td align="center">开发</td><td align="center">简历挂</td></tr><tr><td align="center">虹软</td><td align="center">开发</td><td align="center">简历挂</td></tr><tr><td align="center">卡尔动力</td><td align="center">自动驾驶仿真开发</td><td align="center">简历挂</td></tr><tr><td align="center">智元机器人</td><td align="center">C++开发</td><td align="center">简历挂</td></tr><tr><td align="center">地平线</td><td align="center">自动驾驶中间件软件开发</td><td align="center">简历挂</td></tr><tr><td align="center">淘天</td><td align="center">C++研发</td><td align="center">简历挂</td></tr><tr><td align="center">米哈游</td><td align="center">游戏服务器开发</td><td align="center">简历挂</td></tr><tr><td align="center">Shopee</td><td align="center">后端开发</td><td align="center">简历挂</td></tr><tr><td align="center">莉莉丝</td><td align="center">引擎开发</td><td align="center">简历挂</td></tr><tr><td align="center">理想</td><td align="center">开发</td><td align="center">简历挂</td></tr><tr><td align="center">速腾聚创</td><td align="center">软件开发</td><td align="center">简历挂</td></tr><tr><td align="center">大疆</td><td align="center">客户端开发</td><td align="center">简历挂</td></tr><tr><td align="center">零跑</td><td align="center">仿真开发</td><td align="center">简历挂</td></tr><tr><td align="center">特斯拉</td><td align="center">C++开发</td><td align="center">简历挂</td></tr><tr><td align="center">Minimax</td><td align="center">软件开发</td><td align="center">简历挂</td></tr><tr><td align="center">文远知行</td><td align="center">研发</td><td align="center">简历挂</td></tr><tr><td align="center">快手</td><td align="center">研发</td><td align="center">简历挂</td></tr><tr><td align="center">卓驭</td><td align="center">C++开发</td><td align="center">简历挂</td></tr></tbody></table><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/11/05/fall-campus-recruitment-2026/">https://blog.jujimeizuo.cn/2025/11/05/fall-campus-recruitment-2026/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;bg 双非本 211 硕，无论文有竞赛，C++ 选手。&lt;/li&gt;
&lt;li&gt;投递岗位包括：&lt;br&gt;1. 后端开发&lt;br&gt;2. 服务端开发（包括游戏）&lt;br&gt;3. 存储开发&lt;br&gt;4. 自动驾驶方向&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;投递了相当多</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>submit on T-RO</title>
    <link href="https://blog.jujimeizuo.cn/2025/10/08/submit-on-T-RO/"/>
    <id>https://blog.jujimeizuo.cn/2025/10/08/submit-on-T-RO/</id>
    <published>2025-10-08T06:44:39.000Z</published>
    <updated>2025-12-19T13:50:29.059Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>从 24 年 11 月写完初稿，经过 11 个月的 24 稿的修订，最终在国庆期间完成 T-RO 投稿。<br>人生第一次写稿、投稿，很多地方不熟悉，遂记录流程。</p></blockquote><h2 id="1-Finish-Manuscript"><a href="#1-Finish-Manuscript" class="headerlink" title="1. Finish Manuscript"></a>1. Finish Manuscript</h2><h3 id="1-1-Download-Template"><a href="#1-1-Download-Template" class="headerlink" title="1.1 Download Template"></a>1.1 Download Template</h3><ul><li>download url: <a href="https://template-selector.ieee.org/secure/templateSelector/publicationType%EF%BC%9B">https://template-selector.ieee.org/secure/templateSelector/publicationType；</a></li><li>选择 Trans 下载 Word or Latex，建议用 Latex；</li><li>中文转英文填写即可，根据 Latex Template 填写对应内容；</li><li>用 VSCode 来编译，查看；</li></ul><img src="/images/2025/10/ieee-trans-template.jpg" width=70%><img src="/images/2025/10/ieee-trans-latex-template.jpg" width=70%><h3 id="1-2-Notices-for-Latex"><a href="#1-2-Notices-for-Latex" class="headerlink" title="1.2 Notices for Latex"></a>1.2 Notices for Latex</h3><ol><li>Regular Paper 建议6-12页（双栏），含图表和参考文献；</li><li>摘要最多 200 字；</li><li>基金和作者信息放在首页左下角；</li><li>参考文献格式：按文中出现顺序编号，文中以方括号引用（如 [1]），具体查看 <a href="https://zhuanlan.zhihu.com/p/632868108">this</a>；<ul><li>期刊名称和会议要用斜体；</li><li>期刊名称前不用 in，会议前用 in；</li><li>参考文献中作者人数少于等于六个需要给出全部作者姓名，多于七个要 et al；</li><li>引号改成“新罗马体Times New Roman”下的引号格式，如<code>“”</code>，而不是<code>&quot;&quot;</code>，tex 为 <code>``&#39;&#39;</code>；</li><li>期刊有 vol. no. pp.，会议有 pp.；</li></ul></li></ol><h2 id="2-Submission-Procedures"><a href="#2-Submission-Procedures" class="headerlink" title="2. Submission Procedures"></a>2. Submission Procedures</h2><p>完整的提交流程查看 <a href="https://www.ieee-ras.org/publications/t-ro/submission-procedures">T-RO PaperCept Submission Procedures</a>。</p><h3 id="2-1-log-in"><a href="#2-1-log-in" class="headerlink" title="2.1 log in"></a>2.1 log in</h3><ul><li><code>PIN</code>：所有的 co-authors 都需要注册一个 <code>PIN</code>；</li><li>完善个人信息；</li><li><code>ORCID</code>：<strong>第一作者</strong>和<strong>通讯作者</strong>需要将 <code>PIN</code> 与 <code>ORCID</code> 进行绑定，在后续会用到；</li></ul><img src="/images/2025/10/tro-login.jpg" width=70%><h3 id="2-2-submit-a-new-paper"><a href="#2-2-submit-a-new-paper" class="headerlink" title="2.2 submit a new paper"></a>2.2 submit a new paper</h3><img src="/images/2025/10/submit-new-paper.jpg" width=70%><h3 id="2-3-Select-the-Type-of-Submission"><a href="#2-3-Select-the-Type-of-Submission" class="headerlink" title="2.3 Select the Type of Submission"></a>2.3 Select the Type of Submission</h3><img src="/images/2025/10/select-type.jpg" width=70%><h3 id="2-4-Choose-to-Whom-to-Submit"><a href="#2-4-Choose-to-Whom-to-Submit" class="headerlink" title="2.4 Choose to Whom to Submit"></a>2.4 Choose to Whom to Submit</h3><img src="/images/2025/10/choose-ed.jpg" width=70%><h3 id="2-5-Authors"><a href="#2-5-Authors" class="headerlink" title="2.5 Authors"></a>2.5 Authors</h3><ul><li>查找所有作者的 <code>PIN</code>，只能通过<strong>姓</strong>查找，比如我姓冯，就搜索 Feng，然后找到对应的 <code>PIN</code>；</li><li>如果没有，注册即可；</li><li>设置通讯作者，该通讯作者的 <code>PIN</code> 必须和 <code>ORCID</code>，不然无法下一步；</li></ul><img src="/images/2025/10/tro-authors.jpg" width=70%><h3 id="2-6-Title-and-Abstract"><a href="#2-6-Title-and-Abstract" class="headerlink" title="2.6 Title and Abstract"></a>2.6 Title and Abstract</h3><ul><li>系统里的摘要，<strong>不能超过 1200 字符</strong>！！！</li></ul><img src="/images/2025/10/title-and-abstract.jpg" width=70%><h3 id="2-7-Keywords"><a href="#2-7-Keywords" class="headerlink" title="2.7 Keywords"></a>2.7 Keywords</h3><ul><li>三个必须是和 RAS Subject Area 关联的，比如 <code>SLAM</code>，<code>Dynamics</code>，剩下一个可以自己填；</li></ul><img src="/images/2025/10/tro-keywords.jpg" width=70%><h3 id="2-8-Notices"><a href="#2-8-Notices" class="headerlink" title="2.8 Notices"></a>2.8 Notices</h3><img src="/images/2025/10/tro-notices.jpg" width=70%><h3 id="2-9-Cover-note"><a href="#2-9-Cover-note" class="headerlink" title="2.9 Cover note"></a>2.9 Cover note</h3><ul><li>填写 cover note，对主编说的话，指出创新点，模板可以从 Reference 中查看；</li></ul><img src="/images/2025/10/tro-cover-note.jpg" width=70%><h3 id="2-10-Overview"><a href="#2-10-Overview" class="headerlink" title="2.10 Overview"></a>2.10 Overview</h3><img src="/images/2025/10/tro-overview.jpg" width=70%><h3 id="2-11-File-Upload"><a href="#2-11-File-Upload" class="headerlink" title="2.11 File Upload"></a>2.11 File Upload</h3><ul><li>上传 Manuscript PDF；</li><li>Finish!</li></ul><img src="/images/2025/10/tro-file-upload.jpg" width=70%><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://ras.papercept.net/journals/tro/scripts/login.pl">Log In IEEE T-RO</a></li><li><a href="https://www.ieee-ras.org/publications/t-ro">IEEE Transactions on Robotics (T-RO)</a></li><li><a href="https://www.ieee-ras.org/publications/t-ro/submission-procedures">T-RO PaperCept Submission Procedures</a></li><li><a href="https://template-selector.ieee.org/secure/templateSelector/publicationType">IEEE-Template Selector</a></li><li><a href="https://www.aje.cn/arc/ieee-transactions-on-robotics">IEEE Transactions on Robotics期刊介绍及投稿模板</a></li><li><a href="https://zhuanlan.zhihu.com/p/614196902">IEEE Transactions on Robotics，投稿过程交流</a></li><li><a href="https://docs.google.com/document/d/1OalFYqVfxKKMelF79U3B93SjmIEiTnJC12wPJrKeSDM/edit?tab=t.0">IEEE EDITORIAL STYLE MANUAL FOR AUTHORS</a></li><li><a href="https://2048ai.net/681d7431a5baf817cf49bf2f.html?depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~activity-17-110293088-blog-121700538.235%5Ev43%5Epc_blog_bottom_relevance_base6">使用Latex排版一篇IEEE Robotics and Automation Letters期刊文章</a></li><li><a href="https://www.cnblogs.com/max1z/p/16493154.html">IEEE Transaction期刊模板使用注意事项</a></li><li><a href="https://zhuanlan.zhihu.com/p/632868108">关于IEEE Transactions论文的参考文献格式</a></li><li><a href="https://blog.csdn.net/fangfang12138/article/details/125950806">IEEE RAL投初稿</a></li><li><a href="https://www.jianshu.com/p/47d2549fee5e">论文投稿之投稿信（Cover Letter）写法–附真实案例</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/10/08/submit-on-T-RO/">https://blog.jujimeizuo.cn/2025/10/08/submit-on-T-RO/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;从 24 年 11 月写完初稿，经过 11 个月的 24 稿的修订，最终在国庆期间完成 T-RO 投稿。&lt;br&gt;人生第一次写稿、投稿，很多地方不熟悉，遂记录流程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1-Finish-Manuscr</summary>
      
    
    
    
    
    <category term="paper" scheme="https://blog.jujimeizuo.cn/tags/paper/"/>
    
  </entry>
  
  <entry>
    <title>SE(3)-Sim(3)-SL(4)-Projective Ambiguity</title>
    <link href="https://blog.jujimeizuo.cn/2025/08/19/SE-3-Sim-3-SL-4-projective-ambiguity/"/>
    <id>https://blog.jujimeizuo.cn/2025/08/19/SE-3-Sim-3-SL-4-projective-ambiguity/</id>
    <published>2025-08-19T07:53:06.000Z</published>
    <updated>2025-10-08T06:45:58.583Z</updated>
    
    <content type="html"><![CDATA[<h2 id="SE-3-Sim-3-SL-4"><a href="#SE-3-Sim-3-SL-4" class="headerlink" title="SE(3)-Sim(3)-SL(4)"></a>SE(3)-Sim(3)-SL(4)</h2><table><thead><tr><th align="center">特性</th><th align="center">SE(3)</th><th align="center">Sim(3)</th><th align="center">SL(4)</th></tr></thead><tbody><tr><td align="center">变换类型</td><td align="center">刚体变换 (旋转+平移)</td><td align="center">相似变换 (旋转+平移+均匀缩放)</td><td align="center">射影变换 (非线性，行列式为1)</td></tr><tr><td align="center">距离</td><td align="center">保持</td><td align="center">不保持 (按比例改变)</td><td align="center">不保持</td></tr><tr><td align="center">角度</td><td align="center">保持</td><td align="center">保持</td><td align="center">不保持</td></tr><tr><td align="center">形状</td><td align="center">保持</td><td align="center">保持</td><td align="center">不保持 (可能扭曲)</td></tr><tr><td align="center">行列式</td><td align="center">1</td><td align="center">$\lambda^3$, 其中 $\lambda$ 为缩放因子</td><td align="center">1</td></tr></tbody></table><h2 id="Projective-Ambiguity"><a href="#Projective-Ambiguity" class="headerlink" title="Projective Ambiguity"></a>Projective Ambiguity</h2><p>VGGT-SLAM 中指出，投影模糊会导致 Sim(3) 不足以对齐子地图，因为当使用未标定相机时，VGGT 的前馈特性会引入投影歧义——这种歧义除了包含Sim(3)的自由度外，还涉及剪切、拉伸和透视自由度，尤其在帧间视差较小时更为明显。仅靠相似变换无法完全消除这种歧义。</p><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://www.cnblogs.com/code-fun/p/16839467.html">Sim3和Se3</a></li><li><a href="https://immortalqx.github.io/2025/05/29/paper-reading-vggt-slam/">VGGT-SLAM: Dense RGB SLAM Optimized on the SL(4) Manifold</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/08/19/SE-3-Sim-3-SL-4-projective-ambiguity/">https://blog.jujimeizuo.cn/2025/08/19/SE-3-Sim-3-SL-4-projective-ambiguity/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;SE-3-Sim-3-SL-4&quot;&gt;&lt;a href=&quot;#SE-3-Sim-3-SL-4&quot; class=&quot;headerlink&quot; title=&quot;SE(3)-Sim(3)-SL(4)&quot;&gt;&lt;/a&gt;SE(3)-Sim(3)-SL(4)&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;</summary>
      
    
    
    
    
    <category term="cv" scheme="https://blog.jujimeizuo.cn/tags/cv/"/>
    
    <category term="slam" scheme="https://blog.jujimeizuo.cn/tags/slam/"/>
    
  </entry>
  
  <entry>
    <title>MDPI @ Submit and Review</title>
    <link href="https://blog.jujimeizuo.cn/2025/07/23/mdpi-at-submit-and-review/"/>
    <id>https://blog.jujimeizuo.cn/2025/07/23/mdpi-at-submit-and-review/</id>
    <published>2025-07-23T05:37:04.000Z</published>
    <updated>2025-12-19T13:50:29.105Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>导师突然让我审稿，我还从未有过了解，故此熟悉一遍流程（包括投稿和审稿），记录在此。</p></blockquote><h2 id="Submit"><a href="#Submit" class="headerlink" title="Submit"></a>Submit</h2><h3 id="Submitted-Pending-Review"><a href="#Submitted-Pending-Review" class="headerlink" title="Submitted &amp; Pending Review"></a>Submitted &amp; Pending Review</h3><p>提交初稿，可以用 Word 或 Latex 格式，并附上 Cover Letter，按照标准的格式书写（第一段礼貌说明来意及标题作者，第二段简要介绍内容，第三段为书信结尾，下方写明联系方式，并且可以附上自己推荐的审稿人）。提交后稿件便会转入 Pengding Review 状态，此时稿件会进入内审阶段，内审合格后才会发外审。</p><h3 id="Under-Review"><a href="#Under-Review" class="headerlink" title="Under Review"></a>Under Review</h3><p>内审通过后，会收到分配 Assistant Editor 的邮件，稿件状态变为 Under Review，文章会被发给 2-4 个审稿人进行外审。有任何疑问都可以给 Assistant Editor 发邮件询问。</p><h3 id="Pending-Major-Revision"><a href="#Pending-Major-Revision" class="headerlink" title="Pending Major Revision"></a>Pending Major Revision</h3><p>审稿人会给出大修、小修或直接拒稿的意见。大修和小修的稿件会被退回给作者，作者需要按照审稿人的意见进行修改，并在规定时间内重新提交。</p><ul><li>大修：10 天内返回修订的版本，再次发送给审稿人。</li><li>小修：5 天内返回修订的版本，直接由 Academic Editor 决定是否录用。</li><li>时间不够可以申请延期。</li></ul><h3 id="Resubmitted-Revised-Version-Review"><a href="#Resubmitted-Revised-Version-Review" class="headerlink" title="Resubmitted &amp; Revised Version Review"></a>Resubmitted &amp; Revised Version Review</h3><p>针对审稿人意见进行修订。</p><h3 id="Pending-Editor-Decision"><a href="#Pending-Editor-Decision" class="headerlink" title="Pending Editor Decision"></a>Pending Editor Decision</h3><p>收到 “I accept in current form”，文章状态变成 Pending Editor Decision，等待 Academic Editor 决定是否接受发表。</p><h3 id="Paper-Accepted-APC-Confirm"><a href="#Paper-Accepted-APC-Confirm" class="headerlink" title="Paper Accepted &amp; APC Confirm"></a>Paper Accepted &amp; APC Confirm</h3><p>文章接收，会给一个 PDF 奖状，然后生成一个 invoice 进行付费。</p><h3 id="Pending-English"><a href="#Pending-English" class="headerlink" title="Pending English"></a>Pending English</h3><p>接收当天会发完英文修正，由 English Editor 进行润色。</p><h3 id="English-Correction-Done"><a href="#English-Correction-Done" class="headerlink" title="English Correction Done"></a>English Correction Done</h3><p>英文修正完成后，稿件返回 Production Editor 进行检查。</p><h3 id="Author-Profreading"><a href="#Author-Profreading" class="headerlink" title="Author Profreading"></a>Author Profreading</h3><p>Profreading 的邮件由 Production Editor 发出，要求 24 小时内返回稿件。会提出一些图片排版、格式的问题，还有一些可能涉及争议的内容需要确认。开启审阅模式，在Word的批注中逐一对编辑的批注进行回复或修订即可。此时可以向其中添加致谢、支持基金等内容。在这一步也要细致检查文章中是否存在书写错误的地方，这是最后一次较为简单的修改机会了。</p><h3 id="Author-Profreading-Resubmitted"><a href="#Author-Profreading-Resubmitted" class="headerlink" title="Author Profreading Resubmitted"></a>Author Profreading Resubmitted</h3><p>准备好文档、图片压缩包以及附件，此处不需要Cover Letter，直接提交即可。</p><h3 id="xml2pdf-Done"><a href="#xml2pdf-Done" class="headerlink" title="xml2pdf Done"></a>xml2pdf Done</h3><p>XML转换为PDF完成，进入待发表状态。</p><h3 id="Web-Online"><a href="#Web-Online" class="headerlink" title="Web Online"></a>Web Online</h3><p>正式发表，此时便会分配doi号，但需要大约5天时间才会注册成功并生效。</p><h2 id="Review"><a href="#Review" class="headerlink" title="Review"></a>Review</h2><ul><li>当收到审稿邀请时，通常会收到一封邮件，内容包括期刊名称、文章标题、审稿截止日期等信息。你需要在邮件中点击链接确认是否接受审稿邀请。</li></ul><center><img src="/images/2025/07/mdpi-at-submit-and-review-1.png"></center><ul><li>如果接受审稿，那么接下来会给你完整的文章PDF和一些相关信息。</li><li>看完文章之后，需要给出审稿报告和稿件评分，如何撰写优秀的同行评审报告。</li></ul><h3 id="Review-Reports"><a href="#Review-Reports" class="headerlink" title="Review Reports"></a>Review Reports</h3><ul><li>阅读整篇文章以及任何补充材料（如果有的话），密切关注图表、表格、数据和方法。</li><li>你的报告应从整体上对文章进行批判性分析，同时也要对文章中的特定章节和关键概念进行分析。</li><li>请确保您的评论详细具体，以便作者能够正确理解并回应您提出的要点。</li><li>审稿人在并非明显需要提高所审稿件质量的情况下，不得推荐引用自己、关系密切的同事、其他作者或该期刊的作品。</li><li>审稿人不得建议过度引用其本人的作品（自引）、其他作者的作品（荣誉性引用）或投稿期刊的文章，以此增加审稿人&#x2F;作者&#x2F;期刊的引用量。你可按需提供参考文献，但这些文献必须切实提高所审稿件的质量。</li><li>请保持中立的语气，专注于提供建设性的批评意见，以帮助作者改进他们的作品。贬损性的评论将不被容忍。</li><li>审稿人在撰写评审报告时不应使用生成式人工智能工具和其他大语言模型（LLMs）。审稿人对其报告内容负全部责任，使用这些工具可能会侵犯保密权、所有权和数据隐私权。为提高同行评审报告的书面质量而进行的有限使用，例如纠正语法、结构、拼写、标点和格式，可能是可以接受的，但应在提交同行评审报告时予以披露。在任何情况下，审稿人都不应将稿件（全部或部分）、图片、图表、表格或与未发表稿件相关的任何通信上传到任何生成式人工智能工具，因为这样做违反了MDPI与同行评审相关的保密政策。如果确定在撰写评审报告时不当使用了人工智能工具，该报告将被废弃。</li><li>评审报告应包含以下内容：<ul><li><strong>A brief summary</strong> <strong>简要概述</strong>（一小段），概述论文的目的、主要贡献和优势。</li><li><strong>General concept comments</strong><ul><li><strong>Article 文章</strong>：突出薄弱环节、假设的可测试性、方法上的不准确之处、缺少控制变量等。</li><li><strong>Review 评审</strong>：对所涵盖评审主题的完整性、评审主题的相关性、已确定的知识差距、参考文献的恰当性等进行评论。</li><li><strong>Specific comments 具体评论</strong>：需提及行号、表格或图表，指出文本中不准确之处或表意不明的句子。这些评论也应聚焦于科学内容，而非拼写、格式或英语语言问题，因为这些问题后期可由我们内部人员处理。</li></ul></li></ul></li></ul><h3 id="Rating-the-Manuscript"><a href="#Rating-the-Manuscript" class="headerlink" title="Rating the Manuscript"></a>Rating the Manuscript</h3><ul><li>新颖性： 该问题是否具有原创性且定义明确？研究结果是否推动了现有知识的进步？</li><li>范围：该研究是否符合期刊范围*？</li><li>重要性： 结果的解读是否恰当？结果是否具有显著性？所有结论是否合理且有结果支撑？假设是否被谨慎识别？</li><li>质量：文章的撰写方式是否恰当？所呈现的数据和分析是否恰当？是否采用了展示结果的最高标准？</li><li>科学可靠性： 研究设计是否正确且技术上可靠？分析是否采用了最高技术标准？数据是否足够可靠以得出结论？方法、工具、软件和试剂的描述是否足够详细，以便其他研究人员重现结果？原始数据是否可用且正确（如适用）？</li><li>对读者的吸引力： 研究结论是否能引起本刊读者的兴趣？该论文会吸引广泛的读者，还是仅对少数人有吸引力？（请参阅本刊的宗旨和范围。）</li><li>总体价值： 发表这项工作是否有整体益处？该工作是否推动了当前知识的发展？作者是否通过巧妙的实验解决了一个重要的长期存在的问题？作者是否展示了一个有效科学假设的负面结果？</li><li>英语水平： 英语表述是否恰当且易于理解？</li></ul><h3 id="Overall-Recommendation"><a href="#Overall-Recommendation" class="headerlink" title="Overall Recommendation"></a>Overall Recommendation</h3><ul><li>Accept after Minor Revisions（以当前形式录用）：该论文无需任何进一步修改即可录用。</li><li>Reconsider after Major Revisions（小修后接受）：根据审稿人的意见，论文原则上修改后可以接受。作者有五天时间进行小修。</li><li>Reconsider after Major Revisions（大修后重新考虑）：稿件是否被接受将取决于修改情况。作者需逐点回复，如果无法修改审稿人的某些意见，则需提供反驳理由。通常每篇稿件最多可进行两轮大修。作者将被要求在十天内重新提交修改后的论文，修改版本将返回给审稿人以获取进一步意见。</li><li>Reject（拒稿）：文章存在严重缺陷，无原创性贡献，论文可能会被拒稿，且不允许重新投稿至本刊。</li></ul><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://www.mdpi.com/reviewers">MDPI审稿人指南</a></li><li><a href="https://luotianyi.vc/7398.html">【MDPI】Applied Sciences期刊投稿小记</a></li><li><a href="https://www.zhihu.com/question/384813035">请评价一下MDPI旗下的期刊质量如何?</a></li><li><a href="https://news.sciencenet.cn/htmlpaper/2022/1/202212120454847169567.shtm">25年同行评审经验告诉我们：审稿报告这样写 | MDPI 干货分享</a></li><li><a href="https://zhuanlan.zhihu.com/p/606868469">新手入门？请查收这些同行评审注意事项 | MDPI 干货分享</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/07/23/mdpi-at-submit-and-review/">https://blog.jujimeizuo.cn/2025/07/23/mdpi-at-submit-and-review/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;导师突然让我审稿，我还从未有过了解，故此熟悉一遍流程（包括投稿和审稿），记录在此。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;Submit&quot;&gt;&lt;a href=&quot;#Submit&quot; class=&quot;headerlink&quot; title=&quot;Subm</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Mount Google Drive on Linux</title>
    <link href="https://blog.jujimeizuo.cn/2025/05/21/mount-google-drive-on-linux/"/>
    <id>https://blog.jujimeizuo.cn/2025/05/21/mount-google-drive-on-linux/</id>
    <published>2025-05-21T12:09:52.000Z</published>
    <updated>2025-05-26T08:48:35.025Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>想要让 Google Drive 在 Linux 上自动挂载，而 Google Drive 的官方客户端不支持 Linux 系统，这里使用第三方工具 <code>rclone</code> 和 <code>google-drive-ocamlfuse</code>。</p></blockquote><h2 id="Google-API-OAuth2"><a href="#Google-API-OAuth2" class="headerlink" title="Google API &amp; OAuth2"></a>Google API &amp; OAuth2</h2><ol start="0"><li>Check <strong>Reference</strong> for more details.</li><li>Create Google API project</li><li>Create OAuth2 Client ID<ul><li>Application type: Desktop app</li><li>save <code>client_id</code> and <code>client_secret</code></li></ul></li><li>Add users in OAuth Users in Test (7 days) or <strong>Publish App</strong></li></ol><h2 id="rclone"><a href="#rclone" class="headerlink" title="rclone"></a>rclone</h2><h3 id="install"><a href="#install" class="headerlink" title="install"></a>install</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">curl -O https://downloads.rclone.org/rclone-current-linux-amd64.zip</span><br><span class="line">unzip rclone-current-linux-amd64.zip</span><br><span class="line"><span class="built_in">cd</span> rclone-*-linux-amd64</span><br><span class="line"></span><br><span class="line">sudo <span class="built_in">cp</span> rclone /usr/bin/</span><br><span class="line">sudo <span class="built_in">chown</span> root:root /usr/bin/rclone</span><br><span class="line">sudo <span class="built_in">chmod</span> 755 /usr/bin/rclone</span><br><span class="line"></span><br><span class="line">sudo <span class="built_in">mkdir</span> -p /usr/local/share/man/man1</span><br><span class="line">sudo <span class="built_in">cp</span> rclone.1 /usr/local/share/man/man1/</span><br><span class="line">sudo mandb</span><br></pre></td></tr></table></figure><h3 id="exec"><a href="#exec" class="headerlink" title="exec"></a>exec</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rclone config</span><br></pre></td></tr></table></figure><h3 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h3><ul><li>fusermount: option allow_other only allowed if ‘user_allow_other’ is set in&#x2F;etc&#x2F;fuse.conf  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /etc/fuse.conf <span class="comment"># add `user_allow_other`</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="google-drive-ocamlfuse"><a href="#google-drive-ocamlfuse" class="headerlink" title="google-drive-ocamlfuse"></a>google-drive-ocamlfuse</h2><h3 id="install-1"><a href="#install-1" class="headerlink" title="install"></a>install</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo add-apt-repository ppa:alessandro-strada/ppa</span><br><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get install google-drive-ocamlfuse</span><br></pre></td></tr></table></figure><h3 id="mount"><a href="#mount" class="headerlink" title="mount"></a>mount</h3><ul><li>exec below command to get <code>verification_code</code>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">google-drive-ocamlfuse -debug -headless -<span class="built_in">id</span> `client_id` -secret `client_secret`</span><br></pre></td></tr></table></figure></li><li>write <code>verification_code</code> in <code>~/.gdfuse/default/config</code></li><li>create mountpoint: <code>mkdir ~/GoogleDrive</code></li><li>mount: <code>google-drive-ocamlfuse ~/GoogleDrive</code></li><li>check via <code>df -h</code></li></ul><h3 id="FAQ-1"><a href="#FAQ-1" class="headerlink" title="FAQ"></a>FAQ</h3><ul><li>ls: cannot access ‘GoogleDrive’: Input&#x2F;output error  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fusermount -u ~/GoogleDrive</span><br></pre></td></tr></table></figure></li><li>ls: cannot access ‘GoogleDrive’: Transport endpoint is not connected  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fusermount -u ~/GoogleDrive</span><br></pre></td></tr></table></figure></li><li>SOCKS5 Connect Timeout  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> https_proxy=http://127.0.0.1:7890</span><br><span class="line"><span class="built_in">export</span> http_proxy=http://127.0.0.1:7890</span><br></pre></td></tr></table></figure></li></ul><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://github.com/astrada/google-drive-ocamlfuse">google-drive-ocamlfuse</a></li><li><a href="https://developer.aliyun.com/article/529712">google-drive-ocamlfuse在linux挂载【详细版】</a></li><li><a href="https://www.trygek.com/2019/01/google.html">Google硬盘离线下载计划</a></li><li><a href="https://blog.csdn.net/weixin_44929998/article/details/141298064">浏览器可以请求，但是curl失败</a></li><li><a href="https://github.com/astrada/google-drive-ocamlfuse/issues/607">cannot access ‘directory’: Input&#x2F;output error #607</a></li><li><a href="https://github.com/astrada/google-drive-ocamlfuse/issues/624">Request timeout #624</a></li><li><a href="https://github.com/aliyun/ossfs/issues/40">运行一段时间后ls挂载目录出现Transport endpoint is not connected错误 #40</a></li><li><a href="https://github.com/astrada/google-drive-ocamlfuse/issues/474">CURLE_OPERATION_TIMEOUTED, ErrorBuffer: Resolving timed out after 5514 milliseconds during initial setup #474</a></li><li><a href="https://rclone.org/install/">rclone install</a></li><li><a href="https://worktile.com/kb/ask/1051836.html">服务器如何挂载googledrive</a></li><li><a href="https://github.com/rclone/rclone/issues/6844">VolumeDriver.Mount: failed to mount FUSE fs: fusermount: exec: “fusermount3”: executable file not found in $PATH #6844</a></li><li><a href="https://blog.csdn.net/one312/article/details/104588607">fusermount: option allow_other only allowed if ‘user_allow_other’ is set in&#x2F;etc&#x2F;fuse.conf</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/05/21/mount-google-drive-on-linux/">https://blog.jujimeizuo.cn/2025/05/21/mount-google-drive-on-linux/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;想要让 Google Drive 在 Linux 上自动挂载，而 Google Drive 的官方客户端不支持 Linux 系统，这里使用第三方工具 &lt;code&gt;rclone&lt;/code&gt; 和 &lt;code&gt;google-drive-ocamlfus</summary>
      
    
    
    
    
    <category term="linux" scheme="https://blog.jujimeizuo.cn/tags/linux/"/>
    
  </entry>
  
  <entry>
    <title>Update Error on libc and libcrypt</title>
    <link href="https://blog.jujimeizuo.cn/2025/04/16/update-error-on-libc-and-libcrypt/"/>
    <id>https://blog.jujimeizuo.cn/2025/04/16/update-error-on-libc-and-libcrypt/</id>
    <published>2025-04-16T10:58:23.000Z</published>
    <updated>2025-12-19T13:50:29.069Z</updated>
    
    <content type="html"><![CDATA[<blockquote><ol><li>因为最近有需求需要更新 libc 到 2.35，但是我的 Ubuntu 系统是 20.04，最高版本是 2.31（当时我以为是 22.04，所以可以升级到 2.35），然后就从源码中更新 libc，编译、安装，<code>make install</code> 之后，不仅发生错误，而且系统直接崩溃，命令都无法使用！！！</li><li>当我修复好系统之后，又手贱更新了 <code>libc-bin</code>，导致 libcrypt 出错，再次崩溃！！！</li><li>系统：Ubuntu 20.04，系统架构： x86_64</li></ol></blockquote><h2 id="1-系统崩溃时如何操作"><a href="#1-系统崩溃时如何操作" class="headerlink" title="1. 系统崩溃时如何操作"></a>1. 系统崩溃时如何操作</h2><p>当系统故障时，输入所有命令都无效，系统无法正常启动，此时有以下两种方法：</p><h3 id="1-1-救援模式"><a href="#1-1-救援模式" class="headerlink" title="1.1 救援模式"></a>1.1 救援模式</h3><p>开机时，按下 <code>SHIFT + ESC</code> 进入 GRUB 引导加载器页面</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">-----------------------------</span><br><span class="line">|*Ubuntu                    |</span><br><span class="line">|Advanced options for Ubuntu|</span><br><span class="line">-----------------------------</span><br></pre></td></tr></table></figure><p>下面有两种方式进入救援模式：</p><h4 id="1-1-1-Ubuntu"><a href="#1-1-1-Ubuntu" class="headerlink" title="1.1.1 Ubuntu"></a>1.1.1 Ubuntu</h4><ul><li>选择第一个选项并按 e 键进入编辑模式</li><li>在以 linux 开头的一行末尾，删除字符串 <code>$vt_handoff</code> 并添加字符串 <code>systemd.unit=rescue.target</code></li><li>修改完之后，按 <code>Ctrl + x</code> 或 <code>F10</code> 进入救援模式</li></ul><h4 id="1-1-2-Advanced-options-for-Ubuntu"><a href="#1-1-2-Advanced-options-for-Ubuntu" class="headerlink" title="1.1.2 Advanced options for Ubuntu"></a>1.1.2 Advanced options for Ubuntu</h4><p>选择第二个选项后继续选择内核的 <code>recover mode</code>，并选择 root 进入救援模式</p><h3 id="1-2-USB-启动盘"><a href="#1-2-USB-启动盘" class="headerlink" title="1.2 USB 启动盘"></a>1.2 USB 启动盘</h3><p>当救援模式也无法进入系统，可以使用 USB 启动盘来修复系统，制作方法如下：</p><ol><li>准备一个 U 盘，建议 8G 以上，U 盘中的文件会被格式化，确保 U 盘中的文件已备份。</li><li>下载 <a href="http://mirrors.163.com/ubuntu-releases/20.04/">Ubuntu 20.04</a> 系统镜像文件</li><li>使用 <a href="https://rufus.akeo.ie/">Rufus</a> 工具制作启动盘</li></ol><center><img src="/images/2025/04/rufus.png" width="20%"></center><ol start="4"><li>选择 Ubuntu 的 iso 文件。</li><li>然后点击开始，等待完成即可。</li><li>开机时，一直按 F2 进入 BIOS 界面，找到 USB 启动盘启动选项， 调整优先级后保存并启动。</li><li>进入 Ubuntu 系统后，选择 Try Ubuntu 进入系统。</li></ol><h3 id="1-3-挂载崩溃系统"><a href="#1-3-挂载崩溃系统" class="headerlink" title="1.3 挂载崩溃系统"></a>1.3 挂载崩溃系统</h3><p>此时通过前两种方法可以使用命令行或者图形界面进入系统，此时需要先挂载崩溃系统，然后再修复系统。</p><ol><li><p>查看崩溃系统的分区</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo fdisk -l</span><br></pre></td></tr></table></figure><p> 根据自己之前分区的情况，找到崩溃系统的分区，例如我的崩溃系统是 <code>/dev/nveme0n1p7</code></p></li><li><p>挂载崩溃系统</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo mount /dev/nveme0n1p7 /mnt</span><br></pre></td></tr></table></figure></li><li><p>修复系统 ……</p></li><li><p>查看是否修复成功</p><p> 通过更换到崩溃系统的分区，如果没有<strong>核心已转储</strong>，能够正常进入，即修复成功。</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo <span class="built_in">chroot</span> /mnt</span><br></pre></td></tr></table></figure></li></ol><h2 id="2-libc-引起的系统崩溃"><a href="#2-libc-引起的系统崩溃" class="headerlink" title="2. libc 引起的系统崩溃"></a>2. libc 引起的系统崩溃</h2><ul><li><p>当我弄一些东西的时，从源码更新 libc 到 2.35，编译、安装，<code>make install</code> 之后，系统直接崩溃，命令都无法使用！！！</p>  <figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">make[2]: *** [Makefile:84: da.mo] Segmentation fault (core dumped)</span><br><span class="line">make[2]: Leaving directory &#x27;/root/glibc-2.35/po&#x27;</span><br><span class="line">make[1]: *** [Makefile:215: po/subdir_install] Error 2</span><br><span class="line">make[1]: Leaving directory &#x27;/root/glibc-2.35&#x27;</span><br><span class="line">make: *** [Makefile:12: install] Error 2</span><br></pre></td></tr></table></figure></li><li><p>崩溃原因：</p><ul><li>libc.so.6 是 C 运行时库 glibc 的软链接，程序启动和运行时，是根据 libc.so.6 软链接找到glibc库</li><li>lib64&#x2F;libc.so.6 是一个软链接，指向 &#x2F;lib64&#x2F;libc.so-2.1x，2.1x 表示其对应版本，去兼容相应 Ubuntu 版本</li><li>很多基本命命令依赖 glibc，libc.so.6 链接对应版本不一致将导致系统的几乎所有程序不能工作</li></ul></li></ul><h3 id="2-1-方法一"><a href="#2-1-方法一" class="headerlink" title="2.1 方法一"></a>2.1 方法一</h3><ul><li><p>此时不要重启服务器，不要关闭当前终端，还有救！！！（仅限于系统中存在版本正确的 libc.so.6，不然就直接跳转到下面，）</p></li><li><p>如果系统中还有 glibc-2.31.so（<strong>此时备份的重要性</strong>），则创建软连接即可</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /usr/lib64/libc-2.31.so /lib64/libc.so.6</span><br><span class="line"><span class="built_in">ln</span> -s /usr/lib64/ld-2.31.so /lib64/ld-linux-x86-64.so.2</span><br></pre></td></tr></table></figure></li><li><p>并且删除 2.35 相关文件</p></li></ul><h3 id="2-2-方法二"><a href="#2-2-方法二" class="headerlink" title="2.2 方法二"></a>2.2 方法二</h3><ol><li><p>进入救援模式，挂载崩溃系统</p></li><li><p>查看系统适配的 glibc 版本</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ldd --version</span><br></pre></td></tr></table></figure><p> 输出结果如下：</p> <figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ldd (Ubuntu EGLIBC 2.31-0ubuntu6.6) 2.31</span><br><span class="line">Copyright (C) 2020 Free Software Foundation, Inc.</span><br><span class="line">This is free software; see the source for copying conditions.  There is NO</span><br><span class="line">warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span><br><span class="line">Written by Roland McGrath and Ulrich Drepper.</span><br></pre></td></tr></table></figure></li><li><p>查看 libc 中 GLIBC 的版本</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">strings /lib64/libc.so.6 | grep -E <span class="string">&quot;^GLIBC&quot;</span> | <span class="built_in">sort</span> -V -r | <span class="built_in">uniq</span></span><br></pre></td></tr></table></figure><p> 输出结果如下：</p> <figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">GLIBC_2.35</span><br><span class="line">GLIBC_2.34</span><br><span class="line">GLIBC_2.33</span><br><span class="line">GLIBC_2.32</span><br><span class="line">GLIBC_2.31</span><br><span class="line">GLIBC_2.30</span><br><span class="line">GLIBC_2.29</span><br><span class="line">GLIBC_2.28</span><br><span class="line">GLIBC_2.27</span><br><span class="line">GLIBC_2.26</span><br><span class="line">...</span><br></pre></td></tr></table></figure></li><li><p>发现 glibc 还是 2.35 版本，需要降级到 2.31 版本，此时崩溃系统中没有 libc-2.31.so 文件，我发现 USB 启动盘中有这个文件（所以制作启动盘时最好和崩溃系统的版本相同），此时需要将其复制到崩溃系统中</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cp</span> /usr/lib/x86_64-linux-gnu/libc-2.31.so /mnt/lib64/</span><br><span class="line"><span class="built_in">cp</span> /usr/lib/x86_64-linux-gnu/ld-2.31.so /mnt/lib64/</span><br></pre></td></tr></table></figure></li><li><p>然后创建软链接</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /lib64/libc-2.31.so /mnt/lib64/libc.so.6</span><br><span class="line"><span class="built_in">ln</span> -s /lib64/ld-2.31.so /mnt/lib64/ld-linux-x86-64.so.2</span><br></pre></td></tr></table></figure></li><li><p><code>chroot /mnt</code> 查看是否能正常进入，到此修复成功！！！</p></li></ol><h2 id="3-libcrypt-引起的系统崩溃"><a href="#3-libcrypt-引起的系统崩溃" class="headerlink" title="3. libcrypt 引起的系统崩溃"></a>3. libcrypt 引起的系统崩溃</h2><ul><li><p>当我修复好系统之后，又手贱更新了 <code>libc-bin</code>，导致 libcrypt 出错，再次崩溃！！！</p>  <figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/sbin/init: /lib/libcrypt.so.1: version `XCRYPT_2.0` not found (required by lib/systemd/lib/systemd-shared-245.so)</span><br></pre></td></tr></table></figure></li><li><p>崩溃原因：</p><ul><li>程序运行需要 libcrypt.so.1 库中的 XCRYPT_2.0 版本，但系统当前的 libcrypt.so.1 版本不支持 XCRYPT_2.0，由于库版本不兼容导致</li></ul></li><li><p>进入救援模式，挂载崩溃系统</p></li><li><p>查看 libsystemd-shared-245.so 依赖的 libcrypt.so.1 版本</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ldd /lib/systemd/libsystemd-shared-245.so | grep libcrypt.so.1</span><br></pre></td></tr></table></figure><p>  输出结果如下：</p>  <figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/lib/systemd/libsystemd-shared-245.so:/lib64/libcrypt.so.1:version ‘XCRYPT_2.0’ not found(required by /lib/systemd/libsystemd-shared-245.so)</span><br><span class="line">libcrypt.so.1 =&gt; /lib/libcrypt.so.1 (0x00007f2636167000)</span><br></pre></td></tr></table></figure><p>  表示依赖的 libcrypt.so.1 链接于 &#x2F;lib&#x2F;libcrypt.so.1</p></li><li><p>查看 libcrypt.so.1 版本</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">strings /lib/libcrypt.so.1 | grep <span class="string">&quot;XCRYPT_2.0&quot;</span></span><br></pre></td></tr></table></figure><p>  没有输出，说明 &#x2F;liblibcrypt.so.1 中没有 XCRYPT_2.0 版本</p></li><li><p>发现 &#x2F;liblibcrypt.so.1 中确实没有 XCRYPT_2.0 版本，此时需要一个正确的 libcrypt.so.1 文件。</p></li></ul><h3 id="3-1-下载兼容的-libcrypt1"><a href="#3-1-下载兼容的-libcrypt1" class="headerlink" title="3.1 下载兼容的 libcrypt1"></a>3.1 下载兼容的 libcrypt1</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># apt 可用</span></span><br><span class="line">apt download libcrypt1</span><br><span class="line"></span><br><span class="line"><span class="comment"># apt 不可用</span></span><br><span class="line">wget http://deb.debian.org/debian/pool/main/libx/libxcrypt/libcrypt1_4.4.33-2_amd64.deb</span><br><span class="line"></span><br><span class="line">sudo dpkg -i libcrypt1_4.4.33-2_amd64.deb</span><br><span class="line"></span><br><span class="line"><span class="comment"># 修复依赖关系</span></span><br><span class="line">apt install -f</span><br></pre></td></tr></table></figure><h3 id="3-2-创建软连接"><a href="#3-2-创建软连接" class="headerlink" title="3.2 创建软连接"></a>3.2 创建软连接</h3><p>若系统存在包含 XCRYPT_2.0 版本的 libcrypt.so.1 文件（用 strings 查看），则创建软连接即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /usr/lib/x86_64-linux-gnu/libcrypt.so.1 /lib/libcrypt.so.1</span><br></pre></td></tr></table></figure><p>此时使用 perl 命令查看是否修复（崩溃时 perl 也错误），即可大功告成！</p><h2 id="4-总结"><a href="#4-总结" class="headerlink" title="4. 总结"></a>4. 总结</h2><ul><li>对于系统的库文件，一定不要轻易去修改，特别是在 root 权限下！！！<ol><li>内核级 <code>/lib64</code></li><li>系统级 <code>/usr/lib64</code></li><li>root 用户级 <code>/usr/local/lib64</code></li></ol></li><li>任何重要或不确定的文件改动不要轻易执行删除，一定要先<strong>备份</strong>，以备出现故障后能尽快恢复。</li><li>可以使用救援模式或 USB 启动盘来启动第二个系统作为备份和修复已崩溃系统的平台。</li></ul><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://blog.zzstudio.net/uncategory/article_1514.html">centos7 升级 glibc2.25 踩坑记录</a></li><li><a href="https://yellowko.com/about-libc-so-6.html">关于libc.so.6</a></li><li><a href="https://www.cnblogs.com/benjamin77/p/8961037.html">安装glibc错误链接导致系统崩溃，u盘启动紧急救援模式下修复系统。</a></li><li><a href="https://blog.csdn.net/heqiang1995/article/details/133643785">升级glibc导致系统开不了机 系统文件损坏挂载u盘拷入文件 进入救援模式</a></li><li><a href="https://www.antute.com.cn/index.php?id=192">【案例分享】误删lib库导致系统崩溃的恢复</a></li><li><a href="https://developer.aliyun.com/article/1277450">覆盖libc.so.6的惨痛教训</a></li><li><a href="https://www.cnblogs.com/apanly/p/15395786.html">&#x2F;lib64&#x2F;libc.so.6 错误导致的系统崩溃</a></li><li><a href="https://blog.csdn.net/u013553529/article/details/78307520">【笔记】在 Windows 中制作 Ubuntu 系统的USB启动盘</a></li><li><a href="https://zhuanlan.zhihu.com/p/533121821">如何启动 Ubuntu 22.04 进入救援&#x2F;紧急模式 | Linux 中国</a></li><li><a href="https://blog.csdn.net/weixin_43252751/article/details/130305175">ubuntu系统崩溃，甚至Recovery模式和tty都无法进入，这个方法可以救援！</a></li><li><a href="https://blog.csdn.net/eggxo/article/details/136465370?depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-136465370-blog-103188777.235%5Ev43%5Econtrol">强行升级glibc导致Centos8崩溃6小时惊险修复</a></li><li><a href="https://blog.csdn.net/sharksmell/article/details/103188777">Ubuntu 手动更新glibc导致内核崩溃（无法正常关机&#x2F;开机启动失败）</a></li><li><a href="https://weiyan.cc/yuque/%E5%BC%80%E5%8F%91%E8%BF%90%E7%BB%B4/%E9%9B%86%E7%BE%A4/2019-07-13-hpc-experience-glibc/#21-rescue-%E6%A8%A1%E5%BC%8F%E6%AD%A5%E9%AA%A4">一次误删 GLIBC 后的系统恢复经历</a></li><li><a href="https://cloud.tencent.com/developer/ask/sof/116454423">从19.10升级到20.04失败</a></li><li><a href="https://blog.csdn.net/xibeichengf/article/details/48290297">Ubuntu下查看glibc版本</a></li><li><a href="https://unix.stackexchange.com/questions/779871/version-xcrypt-2-0-not-found-after-update-debian-10-to-debian-12">version XCRYPT_2.0 not found after Update Debian 10 to Debian 12</a></li><li><a href="https://github.com/raspberrypi/Raspberry-Pi-OS-64bit/issues/123">libcrypt.so.1: version XCRYPT_2.0 not found#123</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/04/16/update-error-on-libc-and-libcrypt/">https://blog.jujimeizuo.cn/2025/04/16/update-error-on-libc-and-libcrypt/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;因为最近有需求需要更新 libc 到 2.35，但是我的 Ubuntu 系统是 20.04，最高版本是 2.31（当时我以为是 22.04，所以可以升级到 2.35），然后就从源码中更新 libc，编译、安装，&lt;code&gt;make in</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.jujimeizuo.cn/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>Batch vs. Layer vs. Group Normalization</title>
    <link href="https://blog.jujimeizuo.cn/2025/03/17/BN-LN-GN/"/>
    <id>https://blog.jujimeizuo.cn/2025/03/17/BN-LN-GN/</id>
    <published>2025-03-17T02:27:41.000Z</published>
    <updated>2025-03-17T06:21:18.039Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Batch-Normalization"><a href="#Batch-Normalization" class="headerlink" title="Batch Normalization"></a>Batch Normalization</h2><ul><li>在图像预处理过程中通常会对图像进行标准化处理，这样能加速网络的收敛。</li></ul><p>$$<br>\text{image} \overset{\text{preprocess}}{\rightarrow} \text{Conv1} -&gt; \text{feature map} -&gt; \text{Conv2}<br>$$</p><ul><li>上述过程中，对于 Conv1 的输入就是满足某一分布的特征矩阵，但对于 Conv2 而言输入的 feature map 就不一定满足某一分布规律了（<strong>注意这里所说满足某一分布规律并不是指某一个 feature map 的数据要满足分布规律，理论上是指整个训练样本集所对应 feature map 的数据要满足分布规律</strong>）。</li></ul><blockquote><ul><li>Batch Normalization 的目的就是使 feature map 满足均值为 0，方差为 1 的分布规律。</li><li>让 feature map 满足某一分布规律，理论上是指整个训练样本集所对应 feature map 的数据要满足分布规律，即计算整个训练集的 feature map 然后再进行标准化处理，对于大型数据集显然不可能，所以需要使用 Batch Normalization，计算一个 Batch 数据的 feature map 然后再标准化（batch 越大越接近整个数据集的分布）。</li></ul></blockquote><ol><li>训练时要将 traning 参数设置为 True，在验证时将 trainning 参数设置为 False。在pytorch中可通过创建模型的 model.train() 和 model.eval() 方法控制。</li><li>batch size 尽可能设置大点，设置小后表现可能很糟糕，设置的越大求的均值和方差越接近整个训练集的均值和方差。</li><li>建议将 bn 层放在卷积层（Conv）和激活层（例如Relu）之间，且卷积层不要使用偏置 bias，即使使用了偏置 bias 求出的结果也是一样。</li></ol><figure class="highlight python"><figcaption><span>Batch Normalization</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">bn_process</span>(<span class="params">feature, mean, var</span>):</span><br><span class="line">    feature_shape = feature.shape</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(feature_shape[<span class="number">1</span>]):</span><br><span class="line">        <span class="comment"># [batch, channel, height, width]</span></span><br><span class="line">        feature_t = feature[:, i, :, :]</span><br><span class="line">        mean_t = feature_t.mean()</span><br><span class="line">        <span class="comment"># 总体标准差</span></span><br><span class="line">        std_t1 = feature_t.std()</span><br><span class="line">        <span class="comment"># 样本标准差</span></span><br><span class="line">        std_t2 = feature_t.std(ddof=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># bn process</span></span><br><span class="line">        <span class="comment"># 这里记得加上eps和pytorch保持一致</span></span><br><span class="line">        feature[:, i, :, :] = (feature[:, i, :, :] - mean_t) / np.sqrt(std_t1 ** <span class="number">2</span> + <span class="number">1e-5</span>)</span><br><span class="line">        <span class="comment"># update calculating mean and var</span></span><br><span class="line">        mean[i] = mean[i] * <span class="number">0.9</span> + mean_t * <span class="number">0.1</span></span><br><span class="line">        var[i] = var[i] * <span class="number">0.9</span> + (std_t2 ** <span class="number">2</span>) * <span class="number">0.1</span></span><br><span class="line">    <span class="built_in">print</span>(feature)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 随机生成一个batch为2，channel为4，height=width=2的特征向量</span></span><br><span class="line"><span class="comment"># [batch, channel, height, width]</span></span><br><span class="line">feature1 = torch.randn(<span class="number">2</span>, <span class="number">4</span>, <span class="number">2</span>, <span class="number">2</span>)</span><br><span class="line"><span class="comment"># 初始化统计均值和方差</span></span><br><span class="line">calculate_mean = [<span class="number">0.0</span>, <span class="number">0.0</span>]</span><br><span class="line">calculate_var = [<span class="number">1.0</span>, <span class="number">1.0</span>]</span><br><span class="line"><span class="comment"># print(feature1.numpy())</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注意要使用copy()深拷贝</span></span><br><span class="line">bn_process(feature1.numpy().copy(), calculate_mean, calculate_var)</span><br><span class="line"></span><br><span class="line">bn = nn.BatchNorm2d(<span class="number">2</span>, eps=<span class="number">1e-5</span>)</span><br><span class="line">output = bn(feature1)</span><br><span class="line"><span class="built_in">print</span>(output)</span><br></pre></td></tr></table></figure><h2 id="Layer-Normalization"><a href="#Layer-Normalization" class="headerlink" title="Layer Normalization"></a>Layer Normalization</h2><ul><li>Layer Normalization 针对 NLP，例如 RNN，不使用 Batch Normalization 的原因是：在 RNN 这类时序网络中，时序的长度不是一个定值，比如每句话的长短不同，很难使用 BN，所以需要使用 LN。（但 ViT 还是会涉及到 LN）</li><li>Layer Normalization 与 Batch Normalization 的区别在于：<strong>BN 是对于一个 batch 数据的每个 channel 进行 Norm，但 LN 是对单个数据的指定维度进行 Norm 处理，与 batch 无关</strong>。</li><li>LN 指定要 Norm 的维度必须从最后一维开始。</li></ul><figure class="highlight python"><figcaption><span>Layer Normalization</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">layer_norm_process</span>(<span class="params">feature: torch.Tensor, beta=<span class="number">0.</span>, gamma=<span class="number">1.</span>, eps=<span class="number">1e-5</span></span>):</span><br><span class="line">    var_mean = torch.var_mean(feature, dim=[<span class="number">1</span>, <span class="number">2</span>], unbiased=<span class="literal">False</span>)</span><br><span class="line">    <span class="comment"># 均值</span></span><br><span class="line">    mean = var_mean[<span class="number">1</span>]</span><br><span class="line">    <span class="comment"># 方差</span></span><br><span class="line">    var = var_mean[<span class="number">0</span>]</span><br><span class="line"></span><br><span class="line">    <span class="comment"># layer norm process</span></span><br><span class="line">    feature = (feature - mean[..., <span class="literal">None</span>]) / torch.sqrt(var[..., <span class="literal">None</span>] + eps)</span><br><span class="line">    feature = feature * gamma + beta</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> feature</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    t = torch.rand(<span class="number">4</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(t)</span><br><span class="line">    <span class="comment"># 仅在最后一个维度上做norm处理</span></span><br><span class="line">    norm = nn.LayerNorm(normalized_shape=t.shape[-<span class="number">1</span>], eps=<span class="number">1e-5</span>)</span><br><span class="line">    <span class="comment"># 官方layer norm处理</span></span><br><span class="line">    t1 = norm(t)</span><br><span class="line">    <span class="comment"># 自己实现的layer norm处理</span></span><br><span class="line">    t2 = layer_norm_process(t, eps=<span class="number">1e-5</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;t1:\n&quot;</span>, t1)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;t2:\n&quot;</span>, t2)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure><h2 id="Group-Normalization"><a href="#Group-Normalization" class="headerlink" title="Group Normalization"></a>Group Normalization</h2><ul><li>最常用的 BN 有一个缺点，Batch Size 通常较大，当 batch size 小于 16 后 error 明显升高，对于大型网络或 GPU 显存不够的情况下，可以使用 Group Normalization。</li><li>batch size 的大小对 GN 并没有影响，当 batch size 设置较小时，可以采用 GN。</li><li><strong>对于 GN，假设 num_groups &#x3D; 2（原论文默认为 32），假设某层的输出得到 x，根据 num_groups 沿 channel 方向均分成 num_groups 份，然后对每一份求均值和方差</strong>。</li></ul><figure class="highlight python"><figcaption><span>Group Normalization</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">group_norm</span>(<span class="params">x: torch.Tensor,</span></span><br><span class="line"><span class="params">               num_groups: <span class="built_in">int</span>,</span></span><br><span class="line"><span class="params">               num_channels: <span class="built_in">int</span>,</span></span><br><span class="line"><span class="params">               eps: <span class="built_in">float</span> = <span class="number">1e-5</span>,</span></span><br><span class="line"><span class="params">               gamma: <span class="built_in">float</span> = <span class="number">1.0</span>,</span></span><br><span class="line"><span class="params">               beta: <span class="built_in">float</span> = <span class="number">0.</span></span>):</span><br><span class="line">    <span class="keyword">assert</span> <span class="built_in">divmod</span>(num_channels, num_groups)[<span class="number">1</span>] == <span class="number">0</span></span><br><span class="line">    channels_per_group = num_channels // num_groups</span><br><span class="line"></span><br><span class="line">    new_tensor = []</span><br><span class="line">    <span class="keyword">for</span> t <span class="keyword">in</span> x.split(channels_per_group, dim=<span class="number">1</span>):</span><br><span class="line">        var_mean = torch.var_mean(t, dim=[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], unbiased=<span class="literal">False</span>)</span><br><span class="line">        var = var_mean[<span class="number">0</span>]</span><br><span class="line">        mean = var_mean[<span class="number">1</span>]</span><br><span class="line">        t = (t - mean[:, <span class="literal">None</span>, <span class="literal">None</span>, <span class="literal">None</span>]) / torch.sqrt(var[:, <span class="literal">None</span>, <span class="literal">None</span>, <span class="literal">None</span>] + eps)</span><br><span class="line">        t = t * gamma + beta</span><br><span class="line">        new_tensor.append(t)</span><br><span class="line"></span><br><span class="line">    new_tensor = torch.cat(new_tensor, dim=<span class="number">1</span>)</span><br><span class="line">    <span class="keyword">return</span> new_tensor</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    num_groups = <span class="number">2</span></span><br><span class="line">    num_channels = <span class="number">4</span></span><br><span class="line">    eps = <span class="number">1e-5</span></span><br><span class="line"></span><br><span class="line">    img = torch.rand(<span class="number">2</span>, num_channels, <span class="number">2</span>, <span class="number">2</span>)</span><br><span class="line">    <span class="built_in">print</span>(img)</span><br><span class="line"></span><br><span class="line">    gn = nn.GroupNorm(num_groups=num_groups, num_channels=num_channels, eps=eps)</span><br><span class="line">    r1 = gn(img)</span><br><span class="line">    <span class="built_in">print</span>(r1)</span><br><span class="line"></span><br><span class="line">    r2 = group_norm(img, num_groups, num_channels, eps)</span><br><span class="line">    <span class="built_in">print</span>(r2)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure><h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul><li><a href="https://blog.csdn.net/qq_47233366/article/details/126005692">Batch_Normalization 、Layer_Normalization 、Group_Normalization你分的清楚吗</a></li><li><a href="https://blog.csdn.net/qq_37541097/article/details/104434557?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165880395216781683913421%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165880395216781683913421&biz_id=0">Batch Normalization详解</a></li><li><a href="https://blog.csdn.net/qq_37541097/article/details/117653177?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165880395216781683913421%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165880395216781683913421&biz_id=0">Layer Normalization解析</a></li><li><a href="https://blog.csdn.net/qq_37541097/article/details/118016048?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165880395216781683913421%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165880395216781683913421&biz_id=0">Group Normalization详解</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/03/17/BN-LN-GN/">https://blog.jujimeizuo.cn/2025/03/17/BN-LN-GN/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;Batch-Normalization&quot;&gt;&lt;a href=&quot;#Batch-Normalization&quot; class=&quot;headerlink&quot; title=&quot;Batch Normalization&quot;&gt;&lt;/a&gt;Batch Normalization&lt;/h2&gt;&lt;ul&gt;
</summary>
      
    
    
    
    
    <category term="Deep Learning" scheme="https://blog.jujimeizuo.cn/tags/Deep-Learning/"/>
    
  </entry>
  
  <entry>
    <title>RGBD Camera on Astra-S</title>
    <link href="https://blog.jujimeizuo.cn/2025/01/06/RGBD-Camera-on-Astra-S/"/>
    <id>https://blog.jujimeizuo.cn/2025/01/06/RGBD-Camera-on-Astra-S/</id>
    <published>2025-01-06T00:42:35.000Z</published>
    <updated>2025-12-19T13:50:29.247Z</updated>
    
    <content type="html"><![CDATA[<blockquote><ul><li>最近被导师派任务，需要自己采集数据并恢复出三维结构，所以向师兄借用了一个 Astra-S 深度相机，这里记录一下初始使用过程，包括如何安装驱动，如何使用 SDK，如何将数据转换。</li><li>我使用 Ubuntu22.04，Win11 我试过，但是出现问题，找不到驱动，估计是 Win11 的问题，Win10 应该没问题。具体可以看：<a href="https://www.bilibili.com/video/BV1QG411R7JQ/?vd_source=5e048b202705330980eefcc9a56cc5d0">https://www.bilibili.com/video/BV1QG411R7JQ/?vd_source=5e048b202705330980eefcc9a56cc5d0</a></li></ul></blockquote><h2 id="Install-SDK"><a href="#Install-SDK" class="headerlink" title="Install SDK"></a>Install SDK</h2><h3 id="下载链接"><a href="#下载链接" class="headerlink" title="下载链接"></a>下载链接</h3><ul><li><a href="https://vcp.developer.orbbec.com.cn/documentation">3D视觉AI开放平台 Document</a></li><li><a href="https://vcp.developer.orbbec.com.cn/resourceCenter?defaultSelectedKeys=68">OpenNI2 SDK</a></li><li><a href="https://vcp.developer.orbbec.com.cn/resourceCenter?defaultSelectedKeys=72">OpenNI2 SDK Viewer</a></li></ul><p>不过 2025.01.10 之后平台下线了？？？</p><h3 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h3><ul><li>这里不要用 OrbbecSDK Viewer，使用彩色和 IR 没问题，但是深度图像卡顿严重，或许是我的 Ubuntu 出现问题，但我使用 OpenNI2Viewer 没有任何问题。</li><li>如果不需要对其开发，只是用测量图像，可以直接使用 OpenNI2Viewer，不需要安装 SDK。</li></ul><h2 id="Save-RGB-D"><a href="#Save-RGB-D" class="headerlink" title="Save RGB-D"></a>Save RGB-D</h2><ul><li>当我们打开 OpenNI2Viewer 时，可以看到如下界面：</li></ul><img src="/images/2025/01/OpenNI2Viewer.jpeg"><ul><li>然后可以按右键，选择对应的功能，比如设置分辨率、截图、录制等。</li></ul><h3 id="Raw2Png"><a href="#Raw2Png" class="headerlink" title="Raw2Png"></a>Raw2Png</h3><ul><li>在 Linux 中有大量的工具可以打开 Raw，但是这些大量的工具我尝试过好多，从 apt 中安装的 ufraw，找不到，估计是不维护了，还有从源码安装的很多，还有 gimp，太大了，最后选择 ImageJ，小巧轻便，符合我的需求。</li><li>这里使用 ImageJ 进行处理，<a href="http://imagej.net/Fiji/Downloads">http://imagej.net/Fiji/Downloads</a></li><li><code>File-&gt;Import-&gt;Raw...</code><ul><li>对于深度图：<code>Image Type</code>: <code>16-bit unsigned</code></li><li>对于彩色图：<code>Image Type</code>: <code>24-bit RGB</code></li><li>宽度和高度一定要设置正确</li></ul></li><li><code>File-&gt;Save As-&gt;PNG...</code>，得到以下图像：</li></ul><table><thead><tr><th align="center">深度图</th><th align="center">彩色图</th></tr></thead><tbody><tr><td align="center"><img src="/images/2025/01/depth.jpeg"></td><td align="center"><img src="/images/2025/01/rgb.jpeg"></td></tr></tbody></table><ul><li>这只是针对单帧图像，对于大量图片如果单帧处理效率太低，可以通过 ImageJ 批量操作，具体看参考中链接。</li></ul><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://www.yahboom.com/public/upload/upload-html/1640400269/Astra%E7%9B%B8%E6%9C%BA%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95.html">https://www.yahboom.com/public/upload/upload-html/1640400269/Astra%E7%9B%B8%E6%9C%BA%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95.html</a></li><li><a href="https://developer.orbbec.com.cn/module.html?id=4">https://developer.orbbec.com.cn/module.html?id=4</a></li><li><a href="https://blog.csdn.net/qianchuohuan3821/article/details/89498146">https://blog.csdn.net/qianchuohuan3821/article/details/89498146</a></li><li><a href="https://www.bilibili.com/opus/591919202890504930">https://www.bilibili.com/opus/591919202890504930</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/01/06/RGBD-Camera-on-Astra-S/">https://blog.jujimeizuo.cn/2025/01/06/RGBD-Camera-on-Astra-S/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;最近被导师派任务，需要自己采集数据并恢复出三维结构，所以向师兄借用了一个 Astra-S 深度相机，这里记录一下初始使用过程，包括如何安装驱动，如何使用 SDK，如何将数据转换。&lt;/li&gt;
&lt;li&gt;我使用 Ubuntu22.04，Win</summary>
      
    
    
    
    
    <category term="linux" scheme="https://blog.jujimeizuo.cn/tags/linux/"/>
    
  </entry>
  
  <entry>
    <title>Install OpenCV in Ubuntu via Source</title>
    <link href="https://blog.jujimeizuo.cn/2025/01/06/install-opencv-in-ubuntu-via-source/"/>
    <id>https://blog.jujimeizuo.cn/2025/01/06/install-opencv-in-ubuntu-via-source/</id>
    <published>2025-01-06T00:34:26.000Z</published>
    <updated>2025-04-17T01:05:45.415Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>当我在 ubuntu 22.04 中安装 OrbeecSDK 时，需要用到 OpenCV 库，而且是 C++ Version，如果是 Python Version 的话，可以直接通过 pip 安装，但是 C++ Version 的话，会比较麻烦。<br>这篇 <a href="https://zhuanlan.zhihu.com/p/392751819">在 Linux 系统中编译安装 OpenCV</a> 写得非常详细。</p></blockquote><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><ul><li>安装前需要先安装一些依赖库，根据需要安装</li><li>安装过程中会在 make 中卡住，需要等待一大段时间</li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/01/06/install-opencv-in-ubuntu-via-source/">https://blog.jujimeizuo.cn/2025/01/06/install-opencv-in-ubuntu-via-source/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;当我在 ubuntu 22.04 中安装 OrbeecSDK 时，需要用到 OpenCV 库，而且是 C++ Version，如果是 Python Version 的话，可以直接通过 pip 安装，但是 C++ Version 的话，会比较麻烦。&lt;</summary>
      
    
    
    
    
    <category term="linux" scheme="https://blog.jujimeizuo.cn/tags/linux/"/>
    
    <category term="opencv" scheme="https://blog.jujimeizuo.cn/tags/opencv/"/>
    
  </entry>
  
  <entry>
    <title>Activate-MathType</title>
    <link href="https://blog.jujimeizuo.cn/2025/01/03/activate-mathtype/"/>
    <id>https://blog.jujimeizuo.cn/2025/01/03/activate-mathtype/</id>
    <published>2025-01-03T00:21:14.000Z</published>
    <updated>2025-12-19T13:50:29.035Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>在 Win 中通过删除注册表项来重置 MathType 的试用期</p></blockquote><h2 id="打开注册表"><a href="#打开注册表" class="headerlink" title="打开注册表"></a>打开注册表</h2><ol><li><code>Win + R</code> -&gt; <code>regedit</code></li></ol><h2 id="删除注册表项"><a href="#删除注册表项" class="headerlink" title="删除注册表项"></a>删除注册表项</h2><ol><li>删除 <code>HKEY_CURRENT_USER\Software\JavaSoft\Prefs\com\wiris\editor\license</code></li></ol><img src="/images/2025/03/delete-mathtype-in-regedit.png" width="50%"><ol start="2"><li>删除 <code>HKEY_CURRENT_USER\Software\Install Options</code> 下的 <code>Options 7.8</code></li></ol><img src="/images/2025/01/delete-mathtype-in-regedit.png" width="50%"><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://www.changchenghao.cn/n/725494.html">https://www.changchenghao.cn/n/725494.html</a></li><li><a href="https://www.cnblogs.com/JasonCeng/p/15710426.html">https://www.cnblogs.com/JasonCeng/p/15710426.html</a></li><li><a href="https://blog.csdn.net/m0_46667062/article/details/134808661">https://blog.csdn.net/m0_46667062/article/details/134808661</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2025/01/03/activate-mathtype/">https://blog.jujimeizuo.cn/2025/01/03/activate-mathtype/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;在 Win 中通过删除注册表项来重置 MathType 的试用期&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;打开注册表&quot;&gt;&lt;a href=&quot;#打开注册表&quot; class=&quot;headerlink&quot; title=&quot;打开注册表&quot;&gt;&lt;/a&gt;打开注册</summary>
      
    
    
    
    
    <category term="utils" scheme="https://blog.jujimeizuo.cn/tags/utils/"/>
    
  </entry>
  
  <entry>
    <title>The Big Bug in Python</title>
    <link href="https://blog.jujimeizuo.cn/2024/10/15/code-way-in-python/"/>
    <id>https://blog.jujimeizuo.cn/2024/10/15/code-way-in-python/</id>
    <published>2024-10-15T13:53:10.000Z</published>
    <updated>2025-04-17T01:04:55.789Z</updated>
    
    <content type="html"><![CDATA[<p>找了一下午的 Bug，结果是：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">wandb.log</span><br><span class="line">(</span><br><span class="line">    &#123;</span><br><span class="line">        key=value,</span><br><span class="line">    &#125;</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p><strong>python 不是 C++，wandb.log 单独成为一行代码！！！应该写成</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">wandb.log(</span><br><span class="line">    &#123;</span><br><span class="line">        key=value,</span><br><span class="line">    &#125;</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/10/15/code-way-in-python/">https://blog.jujimeizuo.cn/2024/10/15/code-way-in-python/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;找了一下午的 Bug，结果是：&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;</summary>
      
    
    
    
    
    <category term="utils" scheme="https://blog.jujimeizuo.cn/tags/utils/"/>
    
  </entry>
  
  <entry>
    <title>Root-Partition Filled</title>
    <link href="https://blog.jujimeizuo.cn/2024/10/07/root-partition-filled/"/>
    <id>https://blog.jujimeizuo.cn/2024/10/07/root-partition-filled/</id>
    <published>2024-10-07T13:30:46.000Z</published>
    <updated>2024-10-07T13:35:17.017Z</updated>
    
    <content type="html"><![CDATA[<blockquote><ul><li>当我在 docker 容器内 apt install 时，提示根分区即将爆满，所以查询相关内容解决问题。</li><li>以下都是在 ubuntu20.04 下实验。</li></ul></blockquote><h2 id="查找原因"><a href="#查找原因" class="headerlink" title="查找原因"></a>查找原因</h2><p>关于 linux 的磁盘命令，都会使用 <code>dh</code> 或 <code>df</code> 命令，如果要找导致磁盘空间满的目录或文件，使用以下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">du</span> -sh /path/to/* 2&gt;/dev/null | <span class="built_in">sort</span> -hr | <span class="built_in">head</span> -10</span><br></pre></td></tr></table></figure><ol><li>发现 <code>/var</code> 的占空间太大，查询 <code>/var</code> 后，发现它是<strong>动态数据保存位置。主要保存缓存、日志以及软件运行所产生的文件</strong>，再次使用命令，查询 <code>var</code> 目录下的较大目录或文件</li><li>发现有几个目录占比非常大，<code>lib</code>, <code>cache</code>, <code>log</code>, <code>tmp</code> 等等，<code>cache</code> 可以直接删除，<code>log</code> 可以使用命令 <code>journalctl --vacuum - time=7d</code>，删除超过 7 天的旧日志，现在具体来看 <code>/var/lib</code> 目录</li><li>发现 <code>/var/lib/docker</code> 占 40 多个 G，原来镜像的位置保存在这个目录，当然很大，具体查看 <code>overlay2</code> 的性质。现在针对这个目录做一些操作。一般 <code>/home</code> 目录非常大，所以如果把 docker 里的镜像位置都放在 <code>/home</code> 目录，那么会大大减少根分区的磁盘空间，那么开始操作！</li></ol><h2 id="修改-Docker-镜像默认存储位置"><a href="#修改-Docker-镜像默认存储位置" class="headerlink" title="修改 Docker 镜像默认存储位置"></a>修改 Docker 镜像默认存储位置</h2><blockquote><p>由于系统初始分区的原因，导致操作系统中对应根分区不会太大，通过 &#x2F;var 目录不会单独分区。而 docker 镜像默认存储位置是在 <code>/var/lib/docker</code> 下，是使根分区爆炸。<br>查看 docker 容器存放位置：<code>sudo docker info | grep &quot;Docker Root Dir&quot;</code></p></blockquote><h3 id="使用软链接"><a href="#使用软链接" class="headerlink" title="使用软链接"></a>使用软链接</h3><p>解决默认存储容量不足的情况，最直接且最有效的方法就是挂载新的分区到该目录。但是在原有系统空间不变的情况下，所以采用软链接的方式，修改镜像和容器的存放路径达到同样的目的。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mv</span> /var/lib/docker /path/to/docker</span><br><span class="line"><span class="built_in">ln</span> -sf /path/to/docker /var/lib/docker</span><br><span class="line">systemctl restart docker</span><br></pre></td></tr></table></figure><h3 id="指定容器启动参数"><a href="#指定容器启动参数" class="headerlink" title="指定容器启动参数"></a>指定容器启动参数</h3><p>在配置文件中指定容器启动的参数 –graph&#x3D;&#x2F;var&#x2F;lib&#x2F;docker 来指定镜像和容器存放路径。</p><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://cloud.tencent.com/developer/article/1835999">https://cloud.tencent.com/developer/article/1835999</a></li><li><a href="https://blog.csdn.net/BigData_Mining/article/details/104921479">https://blog.csdn.net/BigData_Mining/article/details/104921479</a></li><li><a href="https://blog.csdn.net/wjciayf/article/details/50717773">https://blog.csdn.net/wjciayf/article/details/50717773</a></li><li><a href="https://www.51cto.com/article/707120.html">https://www.51cto.com/article/707120.html</a></li><li><a href="https://cloud.tencent.com/developer/article/1870764">https://cloud.tencent.com/developer/article/1870764</a></li><li><a href="https://www.cnblogs.com/loveer/p/11615627.html">https://www.cnblogs.com/loveer/p/11615627.html</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/10/07/root-partition-filled/">https://blog.jujimeizuo.cn/2024/10/07/root-partition-filled/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;当我在 docker 容器内 apt install 时，提示根分区即将爆满，所以查询相关内容解决问题。&lt;/li&gt;
&lt;li&gt;以下都是在 ubuntu20.04 下实验。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;</summary>
      
    
    
    
    
    <category term="linux" scheme="https://blog.jujimeizuo.cn/tags/linux/"/>
    
  </entry>
  
  <entry>
    <title>Arc Sync</title>
    <link href="https://blog.jujimeizuo.cn/2024/09/23/Arc-Sync/"/>
    <id>https://blog.jujimeizuo.cn/2024/09/23/Arc-Sync/</id>
    <published>2024-09-23T11:59:56.000Z</published>
    <updated>2025-12-19T13:50:29.068Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>使用 Arc 已经快 1 年，最近才发现有 Arc Sync 有在 MacOS、PC、IOS 上的同步问题（目前仅同步 SideBar，遥看未来）。<br>有什么好处？如果你在 work 的时候，突然要离开工位，如果想要在 iPhone 上继续查看电脑上的网页，那么一般情况下你会重新搜索 URL，但是 Arc Sync，可以将电脑上打开的网页直接同步到 iPhone 上，快捷方便！</p></blockquote><h2 id="MacOS"><a href="#MacOS" class="headerlink" title="MacOS"></a>MacOS</h2><ol><li>下载 Arc Desktop (MacOS)、ClashX Pro</li><li>Clash pro 中开启<strong>增强模式 TUN Mode</strong>，ClashX 里没有增强模式</li></ol><center><img src="/images/2024/09/arc-sync-mac-clashpro.jpg" width="20%"></center><ol start="3"><li>在 Arc Desktop 中登录账号，<code>Preferences</code> -&gt; <code>Sync SideBar</code></li></ol><center><table><tr><td><img src="/images/2024/09/arc-sync-mac.jpg"></td><td><img src="/images/2024/09/arc-sync-mac-sidebar.jpg" width="70%"></td></tr></table></center><h2 id="PC"><a href="#PC" class="headerlink" title="PC"></a>PC</h2><ol><li>下载 Arc Desktop (Windows)、Clash for Windows</li><li>Clash for Windows 中开启<strong>增强模式 TUN Mode</strong><ol><li>Windows 无法顺利登陆，进行以下操作</li><li>旁边有一个叹号❗️，提示安装 service mode，<code>service mode</code> -&gt; <code>Manage</code> -&gt; <code>Install</code></li><li>点击 TUN Node 右边的齿轮 ⚙️，点击 DNS IPv6，Save</li><li>重启 Arc</li></ol></li><li>在 Arc Desktop 中登录账号，<code>Settings</code> -&gt; <code>SideBar Sync</code></li></ol><center><img src="/images/2024/09/arc-sync-windows.jpg" width="70%"></center><h2 id="IOS"><a href="#IOS" class="headerlink" title="IOS"></a>IOS</h2><ol><li>从 App Store 下载 Arc Search</li><li>点击右下角 Settings，选择 <code>Sync with Arc Desktop</code>，输入账号密码即可</li><li>点击左下角即可看到同步的 SideBar，包括同时打开的标签页</li><li>记得开魔法</li></ol><center><img src="/images/2024/09/arc-sync-ios.png" width="20%"></center><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/09/23/Arc-Sync/">https://blog.jujimeizuo.cn/2024/09/23/Arc-Sync/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;使用 Arc 已经快 1 年，最近才发现有 Arc Sync 有在 MacOS、PC、IOS 上的同步问题（目前仅同步 SideBar，遥看未来）。&lt;br&gt;有什么好处？如果你在 work 的时候，突然要离开工位，如果想要在 iPhone 上继续查看</summary>
      
    
    
    
    
    <category term="utils" scheme="https://blog.jujimeizuo.cn/tags/utils/"/>
    
  </entry>
  
  <entry>
    <title>LeetCode BitWeek 139</title>
    <link href="https://blog.jujimeizuo.cn/2024/09/15/LeetCode-BitWeek-139/"/>
    <id>https://blog.jujimeizuo.cn/2024/09/15/LeetCode-BitWeek-139/</id>
    <published>2024-09-15T00:17:12.000Z</published>
    <updated>2024-09-15T00:58:52.996Z</updated>
    
    <content type="html"><![CDATA[<h2 id="3285-找到稳定山的下标"><a href="#3285-找到稳定山的下标" class="headerlink" title="3285. 找到稳定山的下标"></a>3285. 找到稳定山的下标</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">stableMountains</span>(<span class="params">self, height: <span class="type">List</span>[<span class="built_in">int</span>], threshold: <span class="built_in">int</span></span>) -&gt; <span class="type">List</span>[<span class="built_in">int</span>]:</span><br><span class="line">        stable = []</span><br><span class="line">        <span class="keyword">for</span> i, x <span class="keyword">in</span> <span class="built_in">enumerate</span>(height):</span><br><span class="line">            <span class="keyword">if</span> i &gt; <span class="number">0</span> <span class="keyword">and</span> height[i - <span class="number">1</span>] &gt; threshold:</span><br><span class="line">                stable.append(i)</span><br><span class="line">        <span class="keyword">return</span> stable</span><br></pre></td></tr></table></figure><h2 id="3286-穿越网格图的安全路径"><a href="#3286-穿越网格图的安全路径" class="headerlink" title="3286. 穿越网格图的安全路径"></a>3286. 穿越网格图的安全路径</h2><p>经典 BFS + dp，设 dp[x][y][h] 表示到达 (x, y) 时剩余 h 血量<strong>是否被走过</strong>。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">findSafeWalk</span><span class="params">(vector&lt;vector&lt;<span class="type">int</span>&gt;&gt;&amp; grid, <span class="type">int</span> health)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> n = <span class="built_in">static_cast</span>&lt;<span class="type">int</span>&gt;(grid.<span class="built_in">size</span>());</span><br><span class="line">        <span class="type">int</span> m = <span class="built_in">static_cast</span>&lt;<span class="type">int</span>&gt;(grid[<span class="number">0</span>].<span class="built_in">size</span>());</span><br><span class="line"></span><br><span class="line">        <span class="type">const</span> <span class="type">static</span> std::vector&lt;<span class="type">int</span>&gt; dx &#123;<span class="number">1</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">0</span>&#125;;</span><br><span class="line">        <span class="type">const</span> <span class="type">static</span> std::vector&lt;<span class="type">int</span>&gt; dy &#123;<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">-1</span>&#125;;</span><br><span class="line"></span><br><span class="line">        std::vector&lt;std::vector&lt;std::vector&lt;<span class="type">bool</span>&gt;&gt;&gt; <span class="built_in">visited</span>(n, std::vector&lt;std::vector&lt;<span class="type">bool</span>&gt;&gt;(m, std::<span class="built_in">vector</span>&lt;<span class="type">bool</span>&gt;(health + <span class="number">1</span>)));</span><br><span class="line"></span><br><span class="line">        std::queue&lt;std::array&lt;<span class="type">int</span>, 3&gt;&gt; q;</span><br><span class="line">        q.<span class="built_in">push</span>(&#123;<span class="number">0</span>, <span class="number">0</span>, health - grid[<span class="number">0</span>][<span class="number">0</span>]&#125;);</span><br><span class="line">        visited[<span class="number">0</span>][<span class="number">0</span>][health] = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (!q.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        <span class="keyword">auto</span> [x, y, h] = q.<span class="built_in">front</span>();</span><br><span class="line">        q.<span class="built_in">pop</span>();</span><br><span class="line">        <span class="keyword">if</span> (h &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (x == n - <span class="number">1</span> <span class="keyword">and</span> y == m - <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">4</span>; i += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="type">int</span> nx = x + dx[i];</span><br><span class="line">        <span class="type">int</span> ny = y + dy[i];</span><br><span class="line">        <span class="keyword">if</span> (nx &lt; <span class="number">0</span> <span class="keyword">or</span> nx &gt;= n <span class="keyword">or</span> ny &lt; <span class="number">0</span> <span class="keyword">or</span> ny &gt;= m <span class="keyword">or</span> h - grid[nx][ny] &lt;= <span class="number">0</span> <span class="keyword">or</span> visited[nx][ny][h - grid[nx][ny]]) &#123;</span><br><span class="line">        <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        q.<span class="built_in">push</span>(&#123;nx, ny, h - grid[nx][ny]&#125;);</span><br><span class="line">                visited[nx][ny][h - grid[nx][ny]] = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="3287-求出数组中最大序列值"><a href="#3287-求出数组中最大序列值" class="headerlink" title="3287. 求出数组中最大序列值"></a>3287. 求出数组中最大序列值</h2><ul><li>前后缀分解 + dp</li><li>设 prefix_or[i][j][mask] 表示 1-i 个数中选 j 个数，使得这 j 个数的或值为 mask。</li><li>设 suffix_or[i][j][mask] 表示 i-n 个数中选 j 个数，使得这 j 个数的或值为 mask。</li><li>if (prefix_or[i][k][mask1] &amp;&amp; suffix_or[i + 1][k][mask2]) ans &#x3D; std::max(ans, mask1 ^ mask2)</li></ul><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> <span class="type">int</span> STATE = <span class="number">1</span> &lt;&lt; <span class="number">7</span>;</span><br><span class="line"><span class="type">bool</span> prefix_or[<span class="number">402</span>][<span class="number">201</span>][STATE];</span><br><span class="line"><span class="type">bool</span> suffix_or[<span class="number">402</span>][<span class="number">201</span>][STATE];</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">maxValue</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; a, <span class="type">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> n = <span class="built_in">static_cast</span>&lt;<span class="type">int</span>&gt;(a.<span class="built_in">size</span>());</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n + <span class="number">1</span>; i += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt;= k; j += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> mask = <span class="number">0</span>; mask &lt; STATE; mask += <span class="number">1</span>) &#123;</span><br><span class="line">        prefix_or[i][j][mask] = suffix_or[i][j][mask] = <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">        prefix_or[<span class="number">0</span>][<span class="number">0</span>][<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line">        suffix_or[n + <span class="number">1</span>][<span class="number">0</span>][<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n - k; i += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt;= std::<span class="built_in">min</span>(i, k); j += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> mask = <span class="number">0</span>; mask &lt; STATE; mask += <span class="number">1</span>) &#123;</span><br><span class="line">    prefix_or[i][j][mask] = prefix_or[i][j][mask] | prefix_or[i - <span class="number">1</span>][j][mask];</span><br><span class="line">        <span class="keyword">if</span> (j)</span><br><span class="line">        prefix_or[i][j][mask | a[i - <span class="number">1</span>]] = prefix_or[i][j][mask | a[i - <span class="number">1</span>]] | prefix_or[i - <span class="number">1</span>][j - <span class="number">1</span>][mask];</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = n; i &gt;= k + <span class="number">1</span>; i -= <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt;= std::<span class="built_in">min</span>(n - i + <span class="number">1</span>, k); j += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> mask = <span class="number">0</span>; mask &lt; STATE; mask += <span class="number">1</span>) &#123;</span><br><span class="line">        suffix_or[i][j][mask] = suffix_or[i][j][mask] | suffix_or[i + <span class="number">1</span>][j][mask];</span><br><span class="line">        <span class="keyword">if</span> (j)</span><br><span class="line">        suffix_or[i][j][mask | a[i - <span class="number">1</span>]] = suffix_or[i][j][mask | a[i - <span class="number">1</span>]] | suffix_or[i + <span class="number">1</span>][j - <span class="number">1</span>][mask];</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = k; i + k &lt;= n; i += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> mask1 = <span class="number">0</span>; mask1 &lt; STATE; mask1 += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!prefix_or[i][k][mask1]) &#123;</span><br><span class="line">        <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> mask2 = <span class="number">0</span>; mask2 &lt; STATE; mask2 += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!suffix_or[i + <span class="number">1</span>][k][mask2]) &#123;</span><br><span class="line">        <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    ans = std::<span class="built_in">max</span>(ans, mask1 ^ mask2);</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="3288-最长上升路径的长度"><a href="#3288-最长上升路径的长度" class="headerlink" title="3288. 最长上升路径的长度"></a>3288. 最长上升路径的长度</h2><ul><li>二维 LIS，先按照 x 从小到大排序，对于 x 相同的点，按照 y 从大到小排序，保证计算 y 的 LIS 时，相同的 x 最多选一个 y。</li><li>选择 x &lt; kx &amp;&amp; y &lt; ky 或 x &gt; kx &amp;&amp; y &gt; ky 的点，计算 LIS。</li></ul><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">maxPathLength</span><span class="params">(vector&lt;vector&lt;<span class="type">int</span>&gt;&gt;&amp; coordinates, <span class="type">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n = <span class="built_in">static_cast</span>&lt;<span class="type">int</span>&gt;(coordinates.<span class="built_in">size</span>());</span><br><span class="line">    <span class="function">std::vector&lt;<span class="type">int</span>&gt; <span class="title">order</span><span class="params">(n)</span></span>;</span><br><span class="line">    std::<span class="built_in">iota</span>(order.<span class="built_in">begin</span>(), order.<span class="built_in">end</span>(), <span class="number">0</span>);</span><br><span class="line">        std::<span class="built_in">sort</span>(order.<span class="built_in">begin</span>(), order.<span class="built_in">end</span>(), [&amp;](<span class="type">int</span> i, <span class="type">int</span> j) &#123;</span><br><span class="line">        <span class="keyword">if</span> (coordinates[i][<span class="number">0</span>] == coordinates[j][<span class="number">0</span>]) &#123;</span><br><span class="line">        <span class="keyword">return</span> coordinates[i][<span class="number">1</span>] &gt; coordinates[j][<span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> coordinates[i][<span class="number">0</span>] &lt; coordinates[j][<span class="number">0</span>];</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        std::vector&lt;<span class="type">int</span>&gt; u;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i += <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> ((coordinates[order[i]][<span class="number">0</span>] &lt; coordinates[k][<span class="number">0</span>] <span class="keyword">and</span> coordinates[order[i]][<span class="number">1</span>] &lt; coordinates[k][<span class="number">1</span>]) </span><br><span class="line">        <span class="built_in">or</span> (coordinates[order[i]][<span class="number">0</span>] &gt; coordinates[k][<span class="number">0</span>] <span class="keyword">and</span> coordinates[order[i]][<span class="number">1</span>] &gt; coordinates[k][<span class="number">1</span>])) &#123;</span><br><span class="line">        <span class="keyword">auto</span> it = std::<span class="built_in">lower_bound</span>(u.<span class="built_in">begin</span>(), u.<span class="built_in">end</span>(), coordinates[order[i]][<span class="number">1</span>]);</span><br><span class="line">        <span class="keyword">if</span> (it == u.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        u.<span class="built_in">push_back</span>(coordinates[order[i]][<span class="number">1</span>]);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        *it = coordinates[order[i]][<span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> (<span class="type">int</span>) u.<span class="built_in">size</span>() + <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/09/15/LeetCode-BitWeek-139/">https://blog.jujimeizuo.cn/2024/09/15/LeetCode-BitWeek-139/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;3285-找到稳定山的下标&quot;&gt;&lt;a href=&quot;#3285-找到稳定山的下标&quot; class=&quot;headerlink&quot; title=&quot;3285. 找到稳定山的下标&quot;&gt;&lt;/a&gt;3285. 找到稳定山的下标&lt;/h2&gt;&lt;figure class=&quot;highlight py</summary>
      
    
    
    
    
    <category term="ACM" scheme="https://blog.jujimeizuo.cn/tags/ACM/"/>
    
  </entry>
  
  <entry>
    <title>Linux Permissions</title>
    <link href="https://blog.jujimeizuo.cn/2024/06/05/Linux-Permissions/"/>
    <id>https://blog.jujimeizuo.cn/2024/06/05/Linux-Permissions/</id>
    <published>2024-06-05T07:02:08.000Z</published>
    <updated>2025-04-17T01:07:06.440Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><ul><li>Linux 系统上对文件的权限有着严格的控制，如果想对某个文件执行某种操作，必须具有对应的权限方可执行成功。</li><li>Linux 下文件的权限类型一般包括读，写，执行。对应字母为 r、w、x。</li><li>Linux 下权限的粒度有<strong>拥有者</strong>、<strong>群组</strong>、<strong>其它组</strong>三种。每个文件都可以针对三个粒度，设置不同的 rwx (读写执行)权限。通常情况下，一个文件只能归属于一个用户和组，如果其它的用户想有这个文件的权限，则可以将该用户加入具备权限的群组，一个用户可以同时归属于多个组。</li><li>Linux 上通常使用 chmod 命令对文件的权限进行设置和更改。</li></ul><h2 id="chmod"><a href="#chmod" class="headerlink" title="chmod"></a>chmod</h2><blockquote><p>更改文件权限，<code>chmod [Option] &lt;mode&gt; &lt;file...&gt;</code></p></blockquote><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">参数说明：</span><br><span class="line"> </span><br><span class="line">[Option]</span><br><span class="line">  -c, --changes          like verbose but report only when a change is made (若该档案权限确实已经更改，才显示其更改动作)</span><br><span class="line">  -f, --silent, --quiet  suppress most error messages  （若该档案权限无法被更改也不要显示错误讯息）</span><br><span class="line">  -v, --verbose          output a diagnostic for every file processed（显示权限变更的详细资料）</span><br><span class="line">       --no-preserve-root  do not treat &#x27;/&#x27; specially (the default)</span><br><span class="line">       --preserve-root    fail to operate recursively on &#x27;/&#x27;</span><br><span class="line">       --reference=RFILE  use RFILE&#x27;s mode instead of MODE values</span><br><span class="line">  -R, --recursive        change files and directories recursively （以递归的方式对目前目录下的所有档案与子目录进行相同的权限变更)</span><br><span class="line">       --help显示此帮助信息</span><br><span class="line">       --version显示版本信息</span><br><span class="line">[mode] </span><br><span class="line">    权限设定字串，详细格式如下 ：</span><br><span class="line">    [ugoa...][[+-=][rwxX]...][,...]，</span><br><span class="line">    其中</span><br><span class="line">    [ugoa...]</span><br><span class="line">    u 表示该档案的拥有者，g 表示与该档案的拥有者属于同一个群体(group)者，o 表示其他以外的人，a 表示所有（包含上面三者）。</span><br><span class="line">    [+-=]</span><br><span class="line">    + 表示增加权限，- 表示取消权限，= 表示唯一设定权限。</span><br><span class="line">    [rwxX]</span><br><span class="line">    r 表示可读取，w 表示可写入，x 表示可执行，X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。</span><br><span class="line"> </span><br><span class="line">[file...]</span><br><span class="line">    文件列表（单个或者多个文件、文件夹）</span><br></pre></td></tr></table></figure><h3 id="rwx"><a href="#rwx" class="headerlink" title="rwx"></a>rwx</h3><p>数字可以表示权限，规定数字 4、2、1 分别表示读、写、执行权限，即 r&#x3D;4，w&#x3D;2，x&#x3D;1。例如经常看到的 777 就是 rwxrwxrwx。</p><p>用数字权限更改格式：<code>chmod &lt;abc&gt; file...</code></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">其中</span><br><span class="line">a,b,c各为一个数字，分别代表User、Group、及Other的权限。</span><br><span class="line">相当于简化版的</span><br><span class="line">chmod u=权限,g=权限,o=权限 file...</span><br><span class="line">而此处的权限将用8进制的数字来表示User、Group、及Other的读、写、执行权限</span><br></pre></td></tr></table></figure><h3 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">-rw------- (600)    只有拥有者有读写权限。</span><br><span class="line">-rw-r--r-- (644)    只有拥有者有读写权限；而属组用户和其他用户只有读权限。</span><br><span class="line">-rwx------ (700)    只有拥有者有读、写、执行权限。</span><br><span class="line">-rwxr-xr-x (755)    拥有者有读、写、执行权限；而属组用户和其他用户只有读、执行权限。</span><br><span class="line">-rwx--x--x (711)    拥有者有读、写、执行权限；而属组用户和其他用户只有执行权限。</span><br><span class="line">-rw-rw-rw- (666)    所有用户都有文件读、写权限。</span><br><span class="line">-rwxrwxrwx (777)    所有用户都有读、写、执行权限。</span><br></pre></td></tr></table></figure><h2 id="chown"><a href="#chown" class="headerlink" title="chown"></a>chown</h2><blockquote><p>更改文件拥有者，<code>chown [Option] user[:group] file...</code></p></blockquote><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">使用权限：root</span><br><span class="line"> </span><br><span class="line">说明：</span><br><span class="line">[Option] : 同上文chmod</span><br><span class="line">user : 新的文件拥有者的使用者 </span><br><span class="line">group : 新的文件拥有者的使用者群体(group)</span><br></pre></td></tr></table></figure><p>例如在普通用户下会经常看到某些文件夹&#x2F;文件“<strong>上锁</strong>”。</p><p>如果用 <code>sudo chmod -R 777</code>，递归将所有文件更改权限，当然能解锁，但是会有很大危险。<br>这个时候就可以用 chown，将文件&#x2F;文件夹的拥有者更改为任意用户，即可解锁🔓。</p><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://blog.csdn.net/u013197629/article/details/73608613">Linux权限详解（chmod、600、644、700、711、755、777、4755、6755、7755）</a></li><li><a href="https://www.cnblogs.com/guojiaxue/p/13084253.html">去除Ubuntu文件夹有锁标志的方法（包含目录下所有文件解锁）</a></li><li><a href="https://blog.csdn.net/weixin_44260459/article/details/122713532">Ubuntu系统下文件带小锁如何解决</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/06/05/Linux-Permissions/">https://blog.jujimeizuo.cn/2024/06/05/Linux-Permissions/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;Introduction&quot;&gt;&lt;a href=&quot;#Introduction&quot; class=&quot;headerlink&quot; title=&quot;Introduction&quot;&gt;&lt;/a&gt;Introduction&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Linux 系统上对文件的权限有着严格的控制，如</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.jujimeizuo.cn/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>Visual SLAM and SfM in Dynamic Environments: A Survey</title>
    <link href="https://blog.jujimeizuo.cn/2024/05/27/Visual-SLAM-and-SfM-in-Dynamic-Environments-A-Survey/"/>
    <id>https://blog.jujimeizuo.cn/2024/05/27/Visual-SLAM-and-SfM-in-Dynamic-Environments-A-Survey/</id>
    <published>2024-05-27T01:03:02.000Z</published>
    <updated>2025-12-19T13:50:29.247Z</updated>
    
    <content type="html"><![CDATA[<h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><blockquote><p>本文介绍 <strong>VSLAM</strong> 和 <strong>SfM</strong> 在<strong>动态环境</strong>下目前所有技术相关的综述。</p></blockquote><p>回顾动态环境中的视觉定位和 3D 重建技术：</p><ul><li>涵盖三个主要问题：<ol><li>如何做好鲁棒 VSLAM</li><li>如何在 3D 中分割和跟踪动态物体</li><li>如何实现联合运动分割和重建</li></ol></li><li>从两个角度来看：<ol><li>作为一个鲁棒性问题：相机前的动态物体导致错误的对应关系（遮挡等），可以通过分割图像中静态和动态特征，将动态部分视为异常值来实现鲁棒性，只用静态部分计算姿态估计。</li><li>作为一个标准 VSLAM 在动态环境中的扩展：将跟踪的特征分割成不同的簇，可以重建每个物体结构（形状）并跟踪轨迹，甚至可以将动态物体插入静态地图中。</li></ol></li><li>现有大致三种思路（分别对应三个主要问题）：<ol><li>排除动态特征来构建静态地图</li><li>提取动态物体而忽略静态背景</li><li>试图同时处理世界中静态和动态的组成成分</li></ol></li></ul><h2 id="综述结构"><a href="#综述结构" class="headerlink" title="综述结构"></a>综述结构</h2><ul><li>鲁棒 VSLAM<ol><li>运动分割<ol><li>背景&#x2F;前景初始化</li><li>几何约束</li><li>光流</li><li>自我运动约束</li><li>深度学习</li></ol></li><li>定位与 3D 重建<ol><li>基于特征</li><li>深度学习</li></ol></li></ol></li><li>动态物体分割与 3D 跟踪<ol><li>动态物体分割<ol><li>统计模型选择</li><li>子空间聚类</li><li>几何</li><li>深度学习</li></ol></li><li>动态物体的 3D 跟踪<ol><li>轨迹三角测量</li><li>粒子滤波</li></ol></li></ol></li><li>联合运动分割与重建<ol><li>因子分解<ol><li>多刚体运动结构（MBSfM）</li><li>非刚性运动结构（NRSfM）</li></ol></li></ol></li></ul><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-1.jpg"></center><h2 id="鲁棒-VSLAM"><a href="#鲁棒-VSLAM" class="headerlink" title="鲁棒 VSLAM"></a>鲁棒 VSLAM</h2><blockquote><p>如果仅基于静态特征计算姿态估计，就可以在动态环境中实现 Robust VSLAM。</p></blockquote><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-2.jpg"></center><h3 id="运动分割"><a href="#运动分割" class="headerlink" title="运动分割"></a>运动分割</h3><blockquote><p>将特征分为两个不同的组，即静态特征和动态特征，来检测图像中的动态部分。</p></blockquote><p>标准的 VSLAM 使用 <strong>计算几何模型（基础&#x2F;单应矩阵）</strong>、<strong>RANSAC</strong>、<strong>辛普森距离</strong> 等去除动态特征点。</p><ul><li>如果静态特征占多数，效果会很好。</li><li>如果相机前的动态物体占据较大，效果不好，其他方法可以利用 <strong>IMU</strong> 估计相机的自我运动来解决。</li></ul><h4 id="背景-前景初始化"><a href="#背景-前景初始化" class="headerlink" title="背景&#x2F;前景初始化"></a>背景&#x2F;前景初始化</h4><p>假设系统对环境有<strong>先验知识</strong>，可以利用该信息来分割。这种先验知识可以附加到背景或前景对象上。如果信息是关于前景对象的，则系统知道在相机前移动的对象的类型或形状。</p><h4 id="几何约束"><a href="#几何约束" class="headerlink" title="几何约束"></a>几何约束</h4><p>利用对极几何特性来分割静态和动态特征。动态特征违反静态场景中在多视图几何中定义的约束，可以从<strong>对极方程</strong>、<strong>三角测量</strong>、<strong>基础矩阵</strong>估计或<strong>重投影误差</strong>中推导出。</p><h4 id="光流"><a href="#光流" class="headerlink" title="光流"></a>光流</h4><p>光流定义了从两个连续图像计算得出的亮度模式的表观运动，对应于图像中的运动场，利用图割算法基于该运动度量来分割动态物体。还有 <strong>3D 版本的场景流</strong>。</p><h4 id="自我运动约束"><a href="#自我运动约束" class="headerlink" title="自我运动约束"></a>自我运动约束</h4><p>标准的 SfM 和 VSLAM 通过<strong>八点法</strong>或<strong>五点法</strong>来计算相机运动。另一种方法假设相机根据给定的外部信息（e.g. 车轮里程计信息）按照特定的参数化进行移动。通过这种强制自我运动约束，可以拟合与相机运动约束相匹配的特征点来对静态特征进行分类。</p><h4 id="深度学习"><a href="#深度学习" class="headerlink" title="深度学习"></a>深度学习</h4><p>从基于特征的运动分割中，上述可以利用光流来分割动态物体。所以可以<strong>通过监督学习来估计光流</strong>。</p><ol><li><strong>FlowNetS</strong>：通过将两张连续图像堆叠作为 CNN 的输入</li><li><strong>FlowNetC</strong>：通过引入一个相关层来比较由两个相同 CNN 流得到的两个特征图</li><li><strong>FlowNet 2.0</strong>:将  <strong>FlowNetS</strong> 和 <strong>FlowNetC</strong> 堆叠成一个更深的网络，并添加一个新的并行网络来处理小位移</li><li>使用立体图像进行场景流估计的扩展，这种光流可以输入到一个更深的网络中以发现运动特征</li><li>在图像空间中明确分割动态物体，采用重建独立成分分析自编码器来学习时空特征。然而，由于时空特征无法学习运动的 3D 几何形状，因此仍然使用几何特征来帮助分割运动。几何和时空特征都被输入到 RNN 中，以进行最终的运动分割</li><li>通过回归给定的 RGB 图像和光流的目标性的粉来分割动态物体。构建两个类似 AlexNet 的并行 CNN，处理 RGB 图像和光流，然后输入到回归网络并生成运动</li><li><strong>R-FCN</strong>：从在线图像序列中分割前景运动时结合实践数据，<strong>FCN</strong> 用于学习空间特征并生成像素稠密预测，但在应用反卷积之前，使用 <strong>GRU</strong> 来建模时间特征。</li></ol><h3 id="定位与-3D-重建"><a href="#定位与-3D-重建" class="headerlink" title="定位与 3D 重建"></a>定位与 3D 重建</h3><blockquote><p>从多张图像中估计相对相机姿态（平移和旋转）以及所观察环境的 3D 结构。</p></blockquote><ul><li>基于特征</li><li>基于深度学习</li></ul><h4 id="基于特征"><a href="#基于特征" class="headerlink" title="基于特征"></a>基于特征</h4><p>在基于特征的 VSLAM 中，提取显著特征来解决图像对应问题。现有的特征提取技术：</p><ol><li>Harris</li><li>SIFT</li><li>SURF</li><li>FAST</li></ol><p>为找到对应关系，使用特征匹配。根据两个相机的光心之间的距离（基线&#x2F;视差）分开的程度来划分。</p><ul><li>基于短基线：可以用基于光流的技术进行匹配</li><li>对于长基线：需要有高度区分度的特征描述子，例如 <strong>SIFT</strong>、<strong>SURF</strong>、<strong>BRIEF</strong>、<strong>BRISK</strong> 等，通过计算这些描述子之间的不相似性来找到对应关系，当数据包含异常值时，需要使用 <strong>RANSAC</strong>、<strong>PROSAC</strong>、<strong>MLESAC</strong> 等排除异常值。</li></ul><p>当图像对应关系已知，2-3 张图像之间的相对位姿可以恢复到一个比例因子。通过对极约束，</p><ol><li>两个视图用八点法或五点法</li><li>三个视图用三交点张量</li><li>如果已经重建了场景的一些 3D 点，可以用 P3P</li></ol><p>当相机位姿被恢复时，通过<strong>三角测量</strong>对两条投影射线进行相交，得到重建场景的 3D 点，但是由于错误的对应关系射线并不总是相交，可以用<strong>中点法</strong>或<strong>最小二乘法</strong>估计交点。为了避免漂移问题，用 <strong>BA</strong> 通过最小化重投影误差来同时相机位姿和 3D 点。另一种高斯-牛顿方法的变体 <strong>LM</strong> 优化。是联合优化场景结构和相机运动的主流方法。</p><p>实际上，有人采用<strong>局部 BA</strong> 优化最后几张图像，比如 ORB-SLAM 中就用到了。</p><h4 id="基于深度学习"><a href="#基于深度学习" class="headerlink" title="基于深度学习"></a>基于深度学习</h4><p>两种主流的方法：</p><ol><li>有监督学习</li></ol><p>监督学习通过最小化与真实姿态相比在预测自我运动时的误差来训练 CNN。在早期工作中，姿态估计被视为在相机平移和旋转的离散空间上的<strong>分类问题</strong>。但近期姿态估计技术都采用基于<strong>回归</strong>的 CNN。由于预测的连续性，回归比分类更准确。</p><p>在回归视觉里程计问题中，目标检测和分类的预训练卷机曾不适用，后续转向基于光流的网络以在不同的环境中泛化学习到的参数。</p><ul><li><strong>Flowdometry</strong>：由两个连续的 CNN 组成，第一个用于预测光流，第二个估计相机运动</li><li>计算两个视图之间自我运动的端到端 CNN，堆叠两个具有具有权重共享的并行 CNN，随后是一个空间金字塔池化 SPP 层，以处理任意输入图像，同时在特征图中保持空间信息。回归层由两个全连接层组成，用于预测相机平移和旋转</li><li><strong>DeepVO</strong>：通过 <strong>RCNN</strong>，从图像序列中学习顺序运动动力学的端到端学习框架。在输出里程计方面效果较好。</li></ul><ol start="2"><li>无监督学习</li></ol><p>在无监督的情况下，CNN 没有真实数据进行训练。相反，该网络通过最小化类似于 <strong>LSD-SLAM</strong> 的光度误差来学习预测相机位姿。</p><ul><li>利用新颖视图合成原则（给定一个源图像合成具有不同位姿的目标图像的问题）。构建两个并行的 CNN 用于预测深度和估计相机位姿。来自源图像的预测深度用于在给定相机变换矩阵和源图像的情况下合成目标图像。通过最小化光度误差，共同训练深度和相机位姿。而不是从深度预测生成目标图像。</li><li>基于深度预测、相机运动以及卷积&#x2F;反卷积网络产生的动态对象分割构建了一个 3D 场景流。场景流通过相机运动进行变换，然后反投影到当前帧以评估光度误差。</li></ul><h2 id="动态物体分割与-3D-跟踪"><a href="#动态物体分割与-3D-跟踪" class="headerlink" title="动态物体分割与 3D 跟踪"></a>动态物体分割与 3D 跟踪</h2><blockquote><p>动态对象分割和 3D 跟踪将特征对应关系基于其运动聚类到不同组中，并在 3D 中跟踪它们的轨迹。</p></blockquote><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-3.jpg"></center><h3 id="动态物体分割"><a href="#动态物体分割" class="headerlink" title="动态物体分割"></a>动态物体分割</h3><blockquote><p>动态物体分割将所有特征对应关系聚类为 n 个不同对象运动。另一个挑战是处理<strong>退化运动</strong>（当一个物体与相机运动在同一平面上且具有相同的方向和速度时）或<strong>相关运动</strong>（两个人一起移动，关节运动）。</p></blockquote><h4 id="统计模型选择"><a href="#统计模型选择" class="headerlink" title="统计模型选择"></a>统计模型选择</h4><p>用 <strong>RANSAC</strong> 或<strong>蒙特卡罗采样迭代</strong>下对数据的子集进行采样，并将运动模型拟合到采样数据中。改运动模型用于构建内点集，并将剩余数据排除为该模型的异常值。然后，对剩余数据（前一个模型的异常值）在此进行采样，以找到并拟合最能描述剩余数据的另一个模型。</p><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-4.jpg"></center><h4 id="子空间聚类"><a href="#子空间聚类" class="headerlink" title="子空间聚类"></a>子空间聚类</h4><p>许多高维数据可以用低维子空间的并集来表示。数据点的一个子空间可以由基向量和低维数据来表示。在子空间聚类框架下的 3D 运动分割问题基本上是找到与每个刚体运动相关联的每个单独子空间，并将数据拟合到这些子空间中。</p><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-5.jpg"></center><h4 id="几何"><a href="#几何" class="headerlink" title="几何"></a>几何</h4><p>几何方法将多视图几何的标准公式从静态场景扩展到包含独立运动物体的动态场景。虽然有一个基本矩阵描述相机相对于静态场景的一般运动，但在动态环境中，将会有 n 个基本矩阵来描述 n 个物体的运动，其中包括一个用于静态特征。</p><ul><li>通过引入多体三线性约束和多体三焦点张量，将多体运动恢复从两个视图扩展到三个视图。将静态场景中的三线性约束和三焦点张量推广到包含多个物体的动态场景。</li></ul><h4 id="深度学习-1"><a href="#深度学习-1" class="headerlink" title="深度学习"></a>深度学习</h4><p>当前用于解决动态物体分割问题的 DNN 依赖于预定义数量的刚体运动。用于生成稠密对象掩码的网络及其相关损失函数可能源自 3D 点云数据或光流。</p><ul><li><strong>SE3-Net</strong>：一种能够从 3D 点云中分割出预定义的 n 个动态对象的 DNN，在 SE(3) 变换中表示。</li><li><strong>SfM-Net</strong>：利用光流来分割动态对象。这是一个能够预测深度、相机运动和动态对象分割的具有几何感知能力的网络。</li></ul><h3 id="动态物体的-3D-跟踪"><a href="#动态物体的-3D-跟踪" class="headerlink" title="动态物体的 3D 跟踪"></a>动态物体的 3D 跟踪</h3><blockquote><p>在 3D 中跟踪动态物体，需要知道动态物体在三维的坐标位置（包括深度信息）。</p></blockquote><h4 id="轨迹三角测量"><a href="#轨迹三角测量" class="headerlink" title="轨迹三角测量"></a>轨迹三角测量</h4><p>标准三角测量，对动态物体并不起作用，因为从相应特征点反向投影的光线并不相交。<br><strong>轨迹三角测量</strong>，作为一种当物体轨迹已知或满足一个参数形式时重建运动物体三维点的技术。</p><ul><li>假设三维点沿着一条未知的三维直线移动。然后重建问题就会变成寻找一条与来自 t 个视图的投影光线相交的三维直线的问题。t 至少是 5。因为来自三个视图的相交直线集会形成一个二次曲面，使得来自第四个视图的光线在两个点相交，此时第五个视图会得出唯一解。</li><li>假设物体不是沿一条直线运动，而是在一个圆锥曲面上运动，则需要 9 个视图得到唯一解。如果圆锥类型已知，则只需要 7 个视图。</li></ul><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-6.jpg"></center><h4 id="粒子滤波"><a href="#粒子滤波" class="headerlink" title="粒子滤波"></a>粒子滤波</h4><p>由于可观测性问题（观测者与目标之间的距离无法被观测到），使用单目相机在三维中跟踪运动物体的问题可以被视为仅方位跟踪（BOT）问题。单目相机可以被视为一个仅方位跟踪传感器，因为它只能提供关于运动物体上被跟踪特征点的方位信息（例如，前一帧和当前帧中观测到的特征相对于相机中心的角度）。对于仅方位跟踪问题，基于滤波器的方法是更可取的，因为它可以对观测者和目标的位置和速度的不确定性进行建模，并且作为目标运动分析问题。</p><h2 id="联合运动分割与重建"><a href="#联合运动分割与重建" class="headerlink" title="联合运动分割与重建"></a>联合运动分割与重建</h2><blockquote><p>不是将多刚体运动分割和动态物体的三维结构重建作为单独且顺序的任务来执行，因式分解可以同时完成。给定特征对应关系，动态物体分割和重建会产生分割特征的运动以及它们的三维结构。</p></blockquote><center><img src="/images/2024/05/VSLAM-SfM-Dynamic-7.jpg"></center><h3 id="因式分解"><a href="#因式分解" class="headerlink" title="因式分解"></a>因式分解</h3><blockquote><p>因式分解是 SfM 最突出的技术之一，可以同时解决分割和重建问题。定理：<strong>在静态场景的短序列中，一个测量矩阵，即包含所有通过所有帧跟踪的特征点的矩阵，最多为四阶（如果在欧式空间使用正交投影模型则为三阶）。</strong></p></blockquote><h4 id="多刚体运动结构（MBSfM）"><a href="#多刚体运动结构（MBSfM）" class="headerlink" title="多刚体运动结构（MBSfM）"></a>多刚体运动结构（MBSfM）</h4><p>将刚体相机运动的 SfM 推广到 n 个刚体运动。</p><h4 id="非刚性运动结构（NRSfM）"><a href="#非刚性运动结构（NRSfM）" class="headerlink" title="非刚性运动结构（NRSfM）"></a>非刚性运动结构（NRSfM）</h4><p>基于因式分解在缩放正投影相机模型下的非刚性运动。</p><h2 id="优点和缺点"><a href="#优点和缺点" class="headerlink" title="优点和缺点"></a>优点和缺点</h2><h3 id="运动分割-1"><a href="#运动分割-1" class="headerlink" title="运动分割"></a>运动分割</h3><table><thead><tr><th>方法</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>背景&#x2F;前景初始化</td><td>当移动对象暂时静止时能够跟踪它们，无需进行新的分割。还可以处理退化运动。</td><td>1. 与背景或物体相关的信息需要事先定义<br>2. 基于检测的跟踪方案可能会阻碍实时能力</td></tr><tr><td>几何约束</td><td>不需要关于背景或动态对象的先验知识。</td><td>1. 不具备处理暂时停止的能力<br>2. 无法区分由动态对象引起的剩余误差还是由错误对应（异常值）引起的，无法处理退化运动</td></tr><tr><td>光流</td><td>不需要关于环境的先验知识，可以实时。</td><td>1. 基于亮度恒定假设，对照明条件变化很敏感<br>2. 处理退化运动困难，当物体在停止后开始移动时需要新的分割</td></tr><tr><td>自我运动约束</td><td>通过拟合符合定义的自我运动的特征，轻松地将静态特征与动态特征分割开来，可以实时，能处理退化运动</td><td>需要相机运动的先验知识，当物体暂时静止时，被视为静态场景的一部分</td></tr></tbody></table><h3 id="动态物体分割-1"><a href="#动态物体分割-1" class="headerlink" title="动态物体分割"></a>动态物体分割</h3><table><thead><tr><th>方法</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>统计模型选择</td><td>1. 只要系统允许计算低维或低自由度运动，就可以处理退化运动<br>2. 不需要关于环境的先验知识<br>3. 基于统计的方法根据内点集的基数来拟合模型，噪声和异常值会自动得到处理</td><td>从随机采样数据中拟合运动模型在计算上复杂度大。（RANSAC 的迭代次数太大）</td></tr><tr><td>子空间聚类</td><td>时间复杂度低，主要基于代数方法</td><td>1. 不能顺序&#x2F;实时运行<br>2. 需要场景中运动数量或子空间所在维度的信息<br>3. 大多数方法使用仿射相机模型，如果场景包含主要的透视效果，该模型会失败<br>4. 对长序列的实施很困难</td></tr><tr><td>几何</td><td>可以处理非线性流形中的数据</td><td>1. 仅支持基本矩阵作为运动模型，无法处理退化运动<br>2. 计算基本矩阵所需的图像相对于运动数量呈指数增长</td></tr></tbody></table><h3 id="动态物体-3D-跟踪"><a href="#动态物体-3D-跟踪" class="headerlink" title="动态物体 3D 跟踪"></a>动态物体 3D 跟踪</h3><table><thead><tr><th>方法</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>轨迹三角测量</td><td>可以逐步进行工作，尽管每次迭代需要几帧，不需要相机运动的先验知识</td><td>1. 限制是物体轨迹应该已知，或应该遵循特定的参数形式（限制了轨迹三角测量在任意物体运动中的应用）<br>2. 处理异常和缺失数据困难，需要几个图像序列才能有唯一解</td></tr><tr><td>粒子滤波</td><td>能够进行动态物体的 3D 重建和跟踪且能实时工作（严格限于少量动态物体），不需要关于物体轨迹的知识</td><td>很难扩展到非刚性重建，不符合恒定速度运动模型</td></tr></tbody></table><h3 id="联合运动分割与重建-1"><a href="#联合运动分割与重建-1" class="headerlink" title="联合运动分割与重建"></a>联合运动分割与重建</h3><table><thead><tr><th>方法</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>因式分解</td><td>1. 运动分割和重建问题可以同时解决<br>2. 不需要关于相机运动的知识<br>3. 可以扩展到非刚性重建</td><td>1. 大多数方法基于正投影或仿射相机模型工作，阻止了它在具有大透视效果条件下的实现<br>2. 不能实时，因为所有特征点轨迹必须事先可用，其次大多数方法基于 SVD，复杂度过高<br>3. 可能需要先验知识（场景中动态对象的数量、测量矩阵的秩或物体的维度）<br>4. 对噪声和异常值敏感<br>5. 缺失数据也是一个问题</td></tr></tbody></table><h3 id="深度学习-2"><a href="#深度学习-2" class="headerlink" title="深度学习"></a>深度学习</h3><table><thead><tr><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>1. 不需要手动特征提取，会使得特征对应问题的减少（噪声、异常值、跟踪丢失、遮挡导致的缺失数据）<br>2. 不需要指定相机模型<br>3. 学习数据非线性表示的能力提供了不同环境中良好泛化的机会，不需要针对不同环境手动微调算法参数的标准基于特征的方法</td><td>1. 动态物体分割和重建技术涉及几何计算，构建一个能理解这种几何并与标准基于特征的技术相比效果更好的 DNN 架构更难<br>2. 提取的时空特征不精确，并且不理解动态对象的几何形状</td></tr></tbody></table><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://www.cs.ox.ac.uk/files/9926/Visual%20Slam.pdf">cs.ox.ac.uk&#x2F;files&#x2F;9926&#x2F;Visual Slam.pdf</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/05/27/Visual-SLAM-and-SfM-in-Dynamic-Environments-A-Survey/">https://blog.jujimeizuo.cn/2024/05/27/Visual-SLAM-and-SfM-in-Dynamic-Environments-A-Survey/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;介绍&quot;&gt;&lt;a href=&quot;#介绍&quot; class=&quot;headerlink&quot; title=&quot;介绍&quot;&gt;&lt;/a&gt;介绍&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;本文介绍 &lt;strong&gt;VSLAM&lt;/strong&gt; 和 &lt;strong&gt;SfM&lt;/strong&gt; 在&lt;stro</summary>
      
    
    
    
    
    <category term="3dCV" scheme="https://blog.jujimeizuo.cn/tags/3dCV/"/>
    
  </entry>
  
  <entry>
    <title>volatile in C++</title>
    <link href="https://blog.jujimeizuo.cn/2024/05/25/volatile/"/>
    <id>https://blog.jujimeizuo.cn/2024/05/25/volatile/</id>
    <published>2024-05-25T11:33:34.000Z</published>
    <updated>2025-04-17T01:10:00.019Z</updated>
    
    <content type="html"><![CDATA[<p><strong>volatile关键字的作用十分特别, 它的作用是避免编译器对相应代码进行优化.</strong></p><h2 id="e-g"><a href="#e-g" class="headerlink" title="e.g."></a>e.g.</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">fun</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">extern</span> <span class="type">unsigned</span> <span class="type">char</span> _end;  <span class="comment">// _end是什么?</span></span><br><span class="line">  <span class="keyword">volatile</span> <span class="type">unsigned</span> <span class="type">char</span> *p = &amp;_end;</span><br><span class="line">  *p = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">while</span>(*p != <span class="number">0xff</span>);</span><br><span class="line">  *p = <span class="number">0x33</span>;</span><br><span class="line">  *p = <span class="number">0x34</span>;</span><br><span class="line">  *p = <span class="number">0x86</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后使用 <code>-O2</code> 编译代码. 尝试去掉代码中的 <code>volatile</code> 关键字, 重新使用 <code>-O2</code> 编译, 并对比去掉 <code>volatile</code> 前后反汇编结果的不同.</p><h2 id="Question"><a href="#Question" class="headerlink" title="Question"></a>Question</h2><blockquote><p>如果代码中p指向的地址最终被映射到一个设备寄存器, 去掉volatile可能会带来什么问题?</p></blockquote><ol><li><strong>缓存不一致</strong>：现代计算机系统中，为了提高性能，会使用缓存来存储经常访问的数据。如果没有 <code>volatile</code> 关键字，编译器可能会将p所指向的寄存器值缓存到 CPU 的寄存器中，而不是每次都从内存中读取。这可能会导致其他线程或设备对该寄存器的修改无法及时被当前线程察觉，从而引发错误的结果。</li><li><strong>指令重排序</strong>：编译器和处理器为了提高性能，可能会对指令进行重排序。在单线程环境下，指令重排序通常不会影响程序的正确性。然而，在多线程或与设备交互的环境中，指令重排序可能会导致意外的结果。如果去掉 <code>volatile</code>，编译器可能会对与p相关的指令进行重排序，从而破坏了程序的预期行为。</li><li><strong>设备同步问题</strong>：设备寄存器通常与外部设备进行交互，这些设备可能有自己的时序 要求。如果没有 <code>volatile</code> 关键字，编译器可能会对与设备寄存器的访问进行优化，导致无法满足设备的同步要求。这可能会导致设备无法正常工作或产生错误的结果。</li></ol><h2 id="Usage"><a href="#Usage" class="headerlink" title="Usage"></a>Usage</h2><ol><li>中断服务程序中修改的供其它程序检测的变量需要加 <code>volatile</code>；</li><li>多任务环境下各任务间共享的标志应该加 <code>volatile</code>；</li><li>存储器映射的硬件寄存器通常也要加 <code>volatile</code> 说明，因为每次对它的读写都可能由不同意义；</li></ol><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://nju-projectn.github.io/ics-pa-gitbook/ics2023/2.5.html#%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA">ics2023&#x2F;2.5</a></li><li><a href="https://www.runoob.com/w3cnote/c-volatile-keyword.html">C&#x2F;C++ 中 volatile 关键字详解</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/05/25/volatile/">https://blog.jujimeizuo.cn/2024/05/25/volatile/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;strong&gt;volatile关键字的作用十分特别, 它的作用是避免编译器对相应代码进行优化.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;e-g&quot;&gt;&lt;a href=&quot;#e-g&quot; class=&quot;headerlink&quot; title=&quot;e.g.&quot;&gt;&lt;/a&gt;e.g.&lt;/h2&gt;&lt;f</summary>
      
    
    
    
    
    <category term="C++" scheme="https://blog.jujimeizuo.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>nvidia-smi unable to load driver</title>
    <link href="https://blog.jujimeizuo.cn/2024/05/17/nvidia-smi-error/"/>
    <id>https://blog.jujimeizuo.cn/2024/05/17/nvidia-smi-error/</id>
    <published>2024-05-17T06:44:50.000Z</published>
    <updated>2025-12-19T13:50:29.063Z</updated>
    
    <content type="html"><![CDATA[<blockquote><ul><li>以下方法，不需要重装驱动，简单快捷。适用于Ubuntu系统下，之前已经安装过驱动，但驱动失效的问题。</li><li>否则需要重新安装驱动，参考<a href="https://blog.csdn.net/wjinjie/article/details/108512153">Ubuntu下安装nvidia显卡驱动</a>。</li></ul></blockquote><h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><p>当使用 <code>nvidia-smi</code> 命令时，出现以下错误：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">NVIDIA-SMI has failed because it couldn&#x27;t communicate with the NVIDIA driver. </span><br><span class="line">Make sure that the latest NVIDIA driver is installed and running.</span><br></pre></td></tr></table></figure><p>估计问题出现原因是 ubuntu 系统更新了，但是 nvidia 驱动无法连接。</p><h2 id="检查驱动是否存在"><a href="#检查驱动是否存在" class="headerlink" title="检查驱动是否存在"></a>检查驱动是否存在</h2><ul><li>使用 <code>nvcc -V</code> 检查驱动和 cuda。</li></ul><center><img src="/images/2024/05/ns-1.jpg" width="50%"></center><p>发现驱动是存在的。</p><h2 id="查看已安装驱动的版本信息"><a href="#查看已安装驱动的版本信息" class="headerlink" title="查看已安装驱动的版本信息"></a>查看已安装驱动的版本信息</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ls /usr/src | grep nvidia</span><br></pre></td></tr></table></figure><center><img src="/images/2024/05/ns-2.jpg" width="50%"></center><p>比如我这里的驱动版本为 nvidia-535.129.03。</p><h2 id="dkms"><a href="#dkms" class="headerlink" title="dkms"></a>dkms</h2><ul><li><code>dkms</code> 是一个框架，用于构建和安装内核模块。它允许你在系统中安装多个内核模块版本，并在内核升级时自动重新编译这些模块。</li><li><code>sudo apt-get install dkms</code></li><li><code>dkms install -m nvidia -v 535.129.03</code></li></ul><p>出现以下错误：</p><center><img src="/images/2024/05/ns-3.jpg" width="50%"></center><p>说明这个版本的文件不存在，需要手动更新。</p><h2 id="更新驱动"><a href="#更新驱动" class="headerlink" title="更新驱动"></a>更新驱动</h2><p>打开软件&amp;更新，根据以下操作选择对应版本（535）。</p><center><img src="/images/2024/05/ns-4.jpg" width="50%"></center><h2 id="重新-dkms"><a href="#重新-dkms" class="headerlink" title="重新 dkms"></a>重新 dkms</h2><center><img src="/images/2024/05/ns-5.jpg" width="50%"></center><p>到这里为止，再次输入 <code>nvidia-smi</code> 就可以查看 GPU 使用状态。</p><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/05/17/nvidia-smi-error/">https://blog.jujimeizuo.cn/2024/05/17/nvidia-smi-error/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;以下方法，不需要重装驱动，简单快捷。适用于Ubuntu系统下，之前已经安装过驱动，但驱动失效的问题。&lt;/li&gt;
&lt;li&gt;否则需要重新安装驱动，参考&lt;a href=&quot;https://blog.csdn.net/wjinjie/articl</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.jujimeizuo.cn/tags/Linux/"/>
    
    <category term="CUDA" scheme="https://blog.jujimeizuo.cn/tags/CUDA/"/>
    
  </entry>
  
  <entry>
    <title>Manhattan and Chebyshev</title>
    <link href="https://blog.jujimeizuo.cn/2024/04/01/Manhattan-and-Chebyshev-switch/"/>
    <id>https://blog.jujimeizuo.cn/2024/04/01/Manhattan-and-Chebyshev-switch/</id>
    <published>2024-04-01T13:33:31.000Z</published>
    <updated>2025-12-19T13:50:29.068Z</updated>
    
    <content type="html"><![CDATA[<h2 id="曼哈顿距离"><a href="#曼哈顿距离" class="headerlink" title="曼哈顿距离"></a>曼哈顿距离</h2><p>定义两个点 $A(x_1, y_1), B(x_2, y_2)$，则 $A, B$ 之间的曼哈顿距离为：</p><p>$$<br>d(A, B) &#x3D; |x_1 - x_2| + |y_1 - y_2|<br>$$</p><blockquote><p>性质</p><ol><li>对称性：$d(A,B)&#x3D;d(B,A)$</li><li>三角不等式：$d(A,C) \le d(A,B)+d(B,C)$</li></ol></blockquote><p><strong>距离原点的曼哈顿距离为 1 组成的点：</strong></p><center><img src="/images/2024/04/manhattan.png" alt="曼哈顿"></center><h2 id="切比雪夫距离"><a href="#切比雪夫距离" class="headerlink" title="切比雪夫距离"></a>切比雪夫距离</h2><p>定义两个点 $A(x_1, y_1), B(x_2, y_2)$，则 $A, B$ 之间的切比雪夫距离为：</p><p>$$<br>d(A, B) &#x3D; \max ( |x_1 - x_2|, |y_1 - y_2| )<br>$$</p><p><strong>距离原点的切比雪夫距离为 1 组成的点：</strong></p><center><img src="/images/2024/04/chebyshev.png" alt="切比雪夫"></center><h2 id="转换"><a href="#转换" class="headerlink" title="转换"></a>转换</h2><h3 id="曼哈顿转切比雪夫"><a href="#曼哈顿转切比雪夫" class="headerlink" title="曼哈顿转切比雪夫"></a>曼哈顿转切比雪夫</h3><p>将代表曼哈顿距离的正方形绕原点逆时针旋转 $\frac{\pi}{4}$，发现两个正方形是相似的，只需要把代表曼哈顿距离的正方形扩大 $\sqrt{2}$ 倍。</p><p>发现原来在代表曼哈顿距离的正方形的四条边上的点 $A(x,y)$ 的坐标由旋转之后变为了<br>$$(x * \cos{\frac{\pi}{4}}-y * \sin{\frac{\pi}{4}}, y * \cos{\frac{\pi}{4}} + x * \sin{\frac{\pi}{4}})$$<br>然后扩大后变为<br>$$A^\prime(\sqrt{2}(x * \cos{\frac{\pi}{4}}-y * \sin{\frac{\pi}{4}}), \sqrt{2}(y * \cos{\frac{\pi}{4}} + x * \sin{\frac{\pi}{4}})) \to A^\prime (x-y, x+y)$$<br>这里的旋转事实上可以理解为坐标轴的旋转。</p><h3 id="切比雪夫转曼哈顿"><a href="#切比雪夫转曼哈顿" class="headerlink" title="切比雪夫转曼哈顿"></a>切比雪夫转曼哈顿</h3><p>通过图形旋转，原来的点 $A(x,y) \to A^\prime(\frac{x+y}{2}, \frac{x-y}{2})$。（由上述逆变换证明）</p><h3 id="恒等式"><a href="#恒等式" class="headerlink" title="恒等式"></a>恒等式</h3><p>$$<br>|x_1 - x_2| + |y_1 - y_2| &#x3D; \max(|x_1^\prime - x_2^\prime|, |y_1^\prime - y_2^\prime|)<br>$$</p><p>其中等式左侧为 $(x_1,y_1)$ 和 $(x_2, y_2)$ 的<strong>曼哈顿距离</strong>，等式右侧 $(x^\prime - y^\prime)&#x3D;(x+y,y-x)$，计算的是 $(x_1^\prime - y_1^\prime)$ 和 $(x_2^\prime - y_2^\prime)$ 两点的曼哈顿距离投影到 $x^\prime$ 轴和 $y^\prime$  轴的线段长度的最大值，即<strong>切比雪夫距离</strong>。</p><h2 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h2><ul><li><a href="https://leetcode.cn/problems/minimize-manhattan-distances/description/">3102. 最小化曼哈顿距离</a></li><li><a href="https://zhuanlan.zhihu.com/p/32878257">曼哈顿距离与切比雪夫距离的转换 - 知乎</a></li><li><a href="https://tom0727.github.io/post/063-%E6%9B%BC%E5%93%88%E9%A1%BF-%E5%88%87%E6%AF%94%E9%9B%AA%E5%A4%AB%E8%B7%9D%E7%A6%BB/">曼哈顿距离 和 切比雪夫距离 - tom0727’s blog</a></li><li><a href="https://www.luogu.com/article/hxr7p6po">常用距离算法详解 - 洛谷专栏</a></li></ul><p><b>本文作者：jujimeizuo</b><br /><b>本文地址<b/>： <a href="https://blog.jujimeizuo.cn/2024/04/01/Manhattan-and-Chebyshev-switch/">https://blog.jujimeizuo.cn/2024/04/01/Manhattan-and-Chebyshev-switch/</a> <br /><b>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0 协议。转载请注明出处！</b></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;曼哈顿距离&quot;&gt;&lt;a href=&quot;#曼哈顿距离&quot; class=&quot;headerlink&quot; title=&quot;曼哈顿距离&quot;&gt;&lt;/a&gt;曼哈顿距离&lt;/h2&gt;&lt;p&gt;定义两个点 $A(x_1, y_1), B(x_2, y_2)$，则 $A, B$ 之间的曼哈顿距离为：&lt;/p&gt;
&lt;</summary>
      
    
    
    
    
    <category term="ACM" scheme="https://blog.jujimeizuo.cn/tags/ACM/"/>
    
  </entry>
  
</feed>
