<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>尹鹏宇 WdBlink</title>
    <description>尹鹏宇 WdBlink 的个人网站。工作流、Skills、Apps，以及一路积累的文字与影像。</description>
    <link>https://wdblink.github.io/</link>
    <atom:link href="https://wdblink.github.io/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Mon, 02 Nov 2026 15:40:31 +0000</pubDate>
    <lastBuildDate>Mon, 02 Nov 2026 15:40:31 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>如何搭建 Windows 远程服务器</title>
        <description>&lt;h1 id=&quot;如何搭建-windows-远程服务器&quot;&gt;如何搭建 Windows 远程服务器&lt;/h1&gt;

&lt;p&gt;如果你的团队并没有购买、搭建专业的内网服务，有没有一种办法能够将异地同事的计算机或者内网服务器等设备组建成一个「虚拟局域网」，让身处各地的同事依然可以像在同一办公室网络环境内协作呢？&lt;/p&gt;

&lt;h2 id=&quot;智能组网把办公室搬到云上&quot;&gt;智能组网：把办公室搬到云上&lt;/h2&gt;

&lt;p&gt;通过「智能组网」这种形式，我们就可以将家中的电脑和办公室的电脑/服务器连接起来。具体而言，智能组网通过类似虚拟局域网的形式组成一个内网，这个内网中的计算机并不再局限于是否处于同一地理位置或者处于同一交换机下，它可以实现和办公室内网互相访问基本相同的效果——所以即便我们离开了办公室，也可以借助智能组网继续访问内网文件服务器或者是直接访问内网的 ERP 等关键业务。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/0cbeee10e5c8ab6c28714c4289a1dade.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;从原理上来看，智能组网通过一个软件层的管理端对设备进行管理，管理端负责设置虚拟的内网网段并提供虚拟路由和交换，同时管理局域网内的设备，设备端则通过专用的客户端通过「虚拟软网卡」和管理端连接，管理端通过对设备端网络情况进行判断来为其提供不同的连接形式。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/db2d0e3bd0095c4e029490199b958b5a.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;例如设备处于一个没有公网 IP 的内网环境中，则这台设备和虚拟内网其他设备的连接就必须通过中继服务器进行，形式上和我们此前普遍使用的 &lt;a href=&quot;https://sspai.com/post/52523&quot;&gt;内网穿透&lt;/a&gt; 类似，访问速度也受限于中继服务器的网络速度；而如果设备拥有公网 IP，则可以通过类似 P2P 连接形式和虚拟内网中其他有公网 IP 的设备进行连接，访问速度则和设备当前网络环境的上传带宽速度有关。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/f8b88d6c3871f087068b4c8eec0b23e3.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;不难看出，智能组网只是基于软件层面的虚拟路由器和交换机，来实现设备管理和虚拟网络地址再分配。这也在一定程度上更适合当前的远程办公场景——毕竟相比物理组网上，软件层的虚拟组网要更简单也更容易进行操作。&lt;/p&gt;

&lt;p&gt;下面简单介绍两款主流的「智能组网」服务，希望可以在春节期间帮助到需要远程办公的你。&lt;/p&gt;

&lt;h2 id=&quot;方案一量大质优的-zerotier&quot;&gt;方案一：量大质优的 ZeroTier&lt;/h2&gt;

&lt;p&gt;首先是这个名为 &lt;a href=&quot;https://sspai.com/link?target=https%3A%2F%2Fwww.zerotier.com%2F&quot;&gt;ZeroTier&lt;/a&gt; 的智能组网服务，一句话评价就是设置简单，上手容易，限制也很少且免费版本就可以满足大多数需求，设备支持上也几乎覆盖了我们可能遇到了所有设备（包括各种 NAS）。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/86cca5c0dee24f376e843a5f0a031677.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;想要使用 ZeroTier 来组建虚拟内网网络其实主要分为两步，注册管理账号并创建虚拟网 ID，然后安装客户端并将设备加入到虚拟网络中。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/1350ac6647909a12f0036c4511fe6612.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;首先登录 &lt;a href=&quot;https://sspai.com/link?target=https%3A%2F%2Fmy.zerotier.com%2F&quot;&gt;ZeroTier&lt;/a&gt; 并注册账号，也可以通过授权登录的形式来注册 ZeroTier 账号。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/472f85c1e80e1588b45d122b573fcb60.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;登录完成之后点击 「Create A Network」来创建你的虚拟网络，然后在这个 Network 网络中进行设置，比如名称、设备的加入方式以及内网网段等。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/40e44fff98a9f22ad2672a0dd80b2daa.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;之后我们下载 App 并将其加入到这个新创建的虚拟网络中。首先我先将我在办公室的 Windows 电脑加入到网络中。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://sspai.com/link?target=https%3A%2F%2Fwww.zerotier.com%2Fdownload%2F&quot;&gt;下载并安装对应的客户端&lt;/a&gt;，运行后在系统托盘处找到 ZeroTier one 并右击选择「Join network」，然后在弹出的输入框中输入前面在网页管理端创建的 16 位字符的 Network ID。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/ddda01e697dc7605dced3c5ff4f8b84d.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如果输入正确，系统会自动生成一个虚拟网络并提示你是否加入，点击加入之后就算是正式加入到这个虚拟局域网中了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/a906a94e0c7f08019cc16681eae23c99.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;当然你也可以通过 在 Windows 终端中输入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipconfig&lt;/code&gt; 来检查你加入的这个虚拟网络下对应的内网 IP 地址。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/307a9e7db28fb42cabfde0787e22ff42.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;以此类推，这里我还为家中的 NAS 也安装了对应的客户端。虽然 ZeroTier 针对不同的 NAS 提供了专门的客户端，但考虑到通用性我直接通过 Docker 镜像来安装。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/1b269823f8f26d5e538cfb5796b62df3.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;首先打开群晖的 Docker 套件，在注册表栏中输入「ZeroTier」来搜索相关的镜像，然后选择「henrist/zerotier-one」这个镜像并下载。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/bc60fbfa167c80de86c06a9fa0f55b1c.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;打开「映像」找到刚才下载的 zerotier-one 镜像，双击后在创建容器中勾选「使用高权限执行容器」，然后在「高级设置」中勾选上「启动自动重新启动」，在「网络」选项卡中勾选「使用与 Docker Host 相同的网络」。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/e55239977710f5d0deac66811d1cae6a.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;切回到「卷」中，点击「添加文件夹」来保存数据，在「文件/文件夹」中定位到存储数据的文件夹（比如 docker/zerotier-one），然后右侧「转载路径」输入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/zerotier-one&lt;/code&gt;，然后点击应用使得容器生效。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/a2d708ed755af72d1968ace5081805f6.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;容器运行后，在「容器」中选中 「zerotier-one」并点击详情，我们接下来需要输入 Network ID 来将 NAS 加入到虚拟内网中，这里在 zerotier-one 中找到「终端机」选项卡，然后点击「新增」-「通过命令启动」，然后输入一个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ash&lt;/code&gt; 并点击确定。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/8ff0cd2659ef9dc6d41e1c16a7d1bbbf.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;紧接着在 ash 这个选项卡的后面输入加入网络 ID 的终端命令：&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zerotier-cli join [你的虚拟内网 ID]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;看到终端显示 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;200 OK&lt;/code&gt; 则表示加入成功了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/9ab7ca51a559b76f98371d26ed7bb856.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这时候在回到 控制 zerotier 管理端并刷新，应该可以看到 NAS 设备也已经顺利加入到虚拟内网中并顺利被分配了一个内网 IP 地址。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/d789c5d31af1b73ba4ec7368849d43a7.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;此时可以通过 ping 地址的方式来测试连通情况，在 Windows 上打开终端然后输入：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping [对应设备的 虚拟内网 IP]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/619e6456dbffee30a88268e4b1b50a7e.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如果两个设备都有对应的公网 IP，那么从 ping 的延迟就能看到其实是非常小的，这样设备之间的连接可以不通过服务器桥接的形式，所以访问上也会更加顺畅。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.sspai.com/2021/01/15/a565189141b7e05aaae86e6b3df4a079.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;至此虚拟内网就已经顺利搭建完成了，你可以像访问内网文件服务器那样，通过 SMB 协议来访问这个千里之外的服务器。如果访问内网服务器中关键业务，则可以直接通过内网 IP 的方式进行访问，再也不需要通过端口映射的方式来进行访问了。&lt;/p&gt;
</description>
        <pubDate>Sat, 28 Jan 2023 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2023/01/28/%E5%A6%82%E4%BD%95%E6%90%AD%E5%BB%BA-Windows-%E8%BF%9C%E7%A8%8B%E6%9C%8D%E5%8A%A1%E5%99%A8/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2023/01/28/%E5%A6%82%E4%BD%95%E6%90%AD%E5%BB%BA-Windows-%E8%BF%9C%E7%A8%8B%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid>
        
        <category>攻略向</category>
        
        
      </item>
    
      <item>
        <title>篮球鞋选购指南</title>
        <description>&lt;h1 id=&quot;篮球鞋选购指南&quot;&gt;篮球鞋选购指南&lt;/h1&gt;

&lt;p&gt;2012年，我在一所封闭式高中上学，再加上我是住宿生，所以平时连校门都没办法出。紧张的高中生活总要找一些东西放松心情，我的方式就是偷偷让走读生帮忙带各种书籍杂志，现在想想那画面甚至能让我联想到《肖申克的救赎》。&lt;/p&gt;

&lt;p&gt;其中每周必买的当属《灌篮》杂志，这本篮球杂志会介绍当周一些NBA重要比赛战报，以及一些球员访谈。&lt;/p&gt;

&lt;p&gt;当然还有篮球鞋。&lt;/p&gt;

&lt;p&gt;某一天，当我拿到同学新帮我买的杂志，并在语文课上偷偷翻看时，一双球鞋的广告宣传图映入我眼帘，科比8代战靴。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://pic1.zhimg.com/80/v2-45df1320f06d393058225dc9bf369569_1440w.jpg?source=d16d100b&quot; alt=&quot;WEN鞋评丨Kobe 8——最痛的回忆-识物&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;0-你为什么需要一双合适的篮球鞋&quot;&gt;0. 你为什么需要一双合适的篮球鞋&lt;/h2&gt;

&lt;p&gt;我强调需要一双“合适”的球鞋而不是“好”球鞋的原因是，虽然球鞋的确可以通过科技配置或者价格高低来定义所谓好坏，但一双球鞋和你脚型、体重、打法等等的契合度，远比鞋子本身用了哪些科技要重要。甚至可以说，一双盲目堆叠科技的球鞋也许不但不会提升你的运动表现，甚至会加大伤病的风险。&lt;/p&gt;

&lt;p&gt;直到有这么一双鞋，你穿上它之后没有感受到什么澎湃的脚感，它的中底不软也不硬。系好鞋带之后鞋面刚好固定住你的脚面，从前脚掌到后跟都没有多余的空间。穿上它踏上球场之后你甚至感觉不到它的存在，你就像拥有了一双加强版的脚，能把注意力全部专注于篮球运动中。你只感觉你常喜欢用的那些技术动作，今天做起来更自如，甚至觉得有那么几个球，身边的防守人都模糊了起来，你变成了你最喜欢的那个球星，把球投进。&lt;/p&gt;

&lt;p&gt;运动完之后，你仍然没有什么感觉，因为你的膝盖和脚都没有像往常那样酸痛，这时你已无法忽略这双鞋的存在，你终于找到了真正为你设计的球鞋。&lt;/p&gt;

&lt;p&gt;2021年距离AJ1发布已经过去了36年，这几十年里篮球鞋的制作工艺不断进步，诞生了无数经典球鞋，再加上近两年国产球鞋的飞速崛起，一定有一双球鞋在等着你，希望这篇文章能帮你找到它。&lt;/p&gt;

&lt;p&gt;我想通过带你以了解自己的脚 $\Rightarrow$ 球鞋的主要性能 $\Rightarrow$ 不同脚以及身体条件需要在意哪种球鞋配置，这样的脉络来逐步定位球鞋，如果没有耐心看完也可以直接跳到文章最后，参考球鞋选购策略的结论总结。&lt;/p&gt;

&lt;h2 id=&quot;1-了解自己的脚&quot;&gt;1. 了解自己的脚&lt;/h2&gt;

&lt;p&gt;在购买合适的鞋子之前，首先要对自己脚部乃至身体有一个足够的了解，主要关注以下几个点：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;脚长宽数据&lt;/p&gt;

    &lt;p&gt;测量方式如下图：&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://pic1.zhimg.com/80/v2-2bbe6d9dc7852c5eb3e635e075000293_1440w.jpg?source=d16d100b&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;在得到自己脚的长宽数据后，还要计算一下长宽比：&lt;/p&gt;

    &lt;p&gt;长/宽 &amp;gt; 2.6则算瘦脚，长/宽&amp;lt;2.5则算偏宽的脚型。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;足弓高度：&lt;/p&gt;

    &lt;p&gt;足弓高度准确测量比较麻烦，但可以根据下边这个示意图自己判断接近于哪个脚型。&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gx9xoam4rej30fa0bgt90.jpg&quot; alt=&quot;扁平足同样可以长年跑步健身！为扁平足正名-健康频道-手机搜狐&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;2-球鞋配置&quot;&gt;2. 球鞋配置&lt;/h2&gt;

&lt;p&gt;目前的球鞋尤其是耐克阿迪的鞋子花里胡哨的设计越来越多，但对篮球运动来说最重要最关键的永远是下边几个方面。只要这几个方面做的不错的球鞋大概率不会翻车。&lt;/p&gt;

&lt;h3 id=&quot;1-防侧翻&quot;&gt;1. 防侧翻&lt;/h3&gt;

&lt;p&gt;打球时崴脚属于是最常见的伤病了，球鞋的防侧翻设计对于防止崴脚至关重要。而且防侧翻设计出了可以防止你崴到脚以外，还能提升球鞋的稳定性，使你的动作更干脆。&lt;/p&gt;

&lt;p&gt;通常在球鞋设计中，实现防侧翻主要通过类似科比4的这种&lt;strong&gt;防侧翻角&lt;/strong&gt;：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gx9zux7dgfj30i20gxq49.jpg&quot; alt=&quot;nimg.ws.126.net&quot; /&gt;&lt;/p&gt;

&lt;p&gt;或者通过前掌宽大的外底设计，比如下图的闪击8等等。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxehakhpntj305k070dft.jpg&quot; alt=&quot;闪击8耐磨吗？闪击8适合什么位置？-趣流网&quot; /&gt;&lt;/p&gt;

&lt;p&gt;我个人更偏爱带有防侧翻角设计的球鞋，因为这种球鞋设计不会令鞋子前掌显得臃肿，也不会牺牲过多的灵活性。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;鞋面的刚性&lt;/strong&gt;对于防侧翻也是比较重要的。想象一下你使用一次完美的cross over脚踝终结防守人的同时，必须有一个刚性较强的鞋面材质来防止你的脚飞出鞋底。&lt;/p&gt;

&lt;h3 id=&quot;2-抓地&quot;&gt;2. 抓地&lt;/h3&gt;

&lt;p&gt;抓地性能应该打过球的都懂，属于能让你正常参与篮球这项运动的基础。在我打球的过程中，在我感受到球鞋和场地扎实的摩擦之后，我才能更自信的做一些变相急停的动作，否则就只能在场上做一些直线跑动，接球跳投之类的。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;外底纹路&lt;/strong&gt;和&lt;strong&gt;外底材质&lt;/strong&gt;是影响抓地性能的主要因素。想要获知一双球鞋的抓地好坏可以参考网上的球鞋评测或者试穿来获知球鞋的抓地性能，这项性能在测评中通常是客观准确的。&lt;/p&gt;

&lt;p&gt;以我的经验来看，人字纹+橡胶底的鞋子抓地在大多数场地都是比较好的。而水晶底的鞋子容易吸灰，在有灰的木地板往往很容易打滑，需要时不时用手去擦鞋底，比较挑场地。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxehnei6wbj30j609iq3m.jpg&quot; alt=&quot;科比4代的人字纹橡胶底&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;3-包裹&quot;&gt;3. 包裹&lt;/h3&gt;

&lt;p&gt;球鞋的包裹性其实是一个非常容易被忽略的方面，我以前买篮球鞋的时候认为球鞋的缓震是篮球鞋最核心的性能。直到我这些年穿了很多球鞋之后，发现球鞋的包裹才是一双鞋的灵魂，也是最难做好的。&lt;/p&gt;

&lt;p&gt;一个完美的球鞋包裹性应该是在系紧鞋带后，前掌完美适配你的脚宽和脚背高度，就像一双手在抓着你的脚一样，使你的脚在运动中不会在鞋子里滑动；后段的包裹能够束缚住你的脚后跟，使你在走路或者运动的时候后跟不会有松动。&lt;/p&gt;

&lt;p&gt;实现这种完美包裹的鞋子通常就会有完美的鞋脚一体性，减轻球鞋的体感重量，从而不会有很强的存在感，使你在运动中能够更专注更自如。&lt;/p&gt;

&lt;p&gt;那么为什么说这是一双鞋最难做好的方面呢？&lt;/p&gt;

&lt;p&gt;首先球鞋厂商需要收集足够多的不同人的脚型数据才能设计出一个适合大多数人的鞋楦。但千人千脚，一双鞋的鞋楦肯定无法适合所有人，因此现在球鞋厂商会设计出好几种鞋楦，配备到不同的球鞋产品线上以适应不同的人群，或者使用类似&lt;strong&gt;飞线&lt;/strong&gt;这种&lt;strong&gt;动态绑定技术&lt;/strong&gt;来增加鞋面的可调节范围。&lt;/p&gt;

&lt;p&gt;另外，鞋面以及内衬材质的选用也会影响球鞋的包裹体验，这就需要在球鞋外观设计、重量、成本、包裹、适用人群等多个方面平衡。可喜的是国产品牌越来越重视鞋楦的开发，已经逐渐拉近了和国外大厂的差距。&lt;/p&gt;

&lt;p&gt;这时候我们一开始测的自己的脚型数据就能派上用场了，网上的球鞋测评通常也会说明球鞋具体适合瘦脚还是宽脚，本文最后也会有一些具体的球鞋推荐。&lt;/p&gt;

&lt;h3 id=&quot;4-抗扭转&quot;&gt;4. 抗扭转&lt;/h3&gt;

&lt;p&gt;对于这球鞋部分性能的关注是我看完&lt;a href=&quot;https://www.notion.so/c179508cee514467861dc7ed6d7d2474#d6a96ca1dd2c40b8bbfdc4267bbd3641&quot;&gt;极客鞋谈的视频&lt;/a&gt;再结合自己的感受之后开始的。&lt;/p&gt;

&lt;p&gt;这期视频里详细讲了抗扭的重要性，总结一下核心影响主要是以下两点：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;鞋的刚性&lt;/p&gt;

    &lt;p&gt;这个在防侧翻部分也提到过。球鞋刚性的重要性更多的体现在比赛强度比较高的情况下，日常打打养生局，做一些小幅度的变相不会给球鞋很大的力，不容易产生形变，这也是耐克敢于给市售版减配的原因。然而这和球鞋减震性能不一样，不存在性能过剩的问题，抗扭不足带来的球鞋刚性缺失是会增加伤病风险、无形之中伤害我们的脚的。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;鞋的自然弯折点&lt;/p&gt;

    &lt;p&gt;由于人行走时，脚部唯一的弯折点应该是趾骨的位置，而我们脚下的球鞋的自然弯折点最好能够配合我们足部的弯折位置。&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxexzs9ocej30q40cw75j.jpg&quot; alt=&quot;image-20211215233741488&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxey08m2bzj309r07pq39.jpg&quot; alt=&quot;image-20211215233807546&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;想象一下如果鞋子自然弯折点在鞋子偏中部的话，则会对足底筋膜造成拉扯，容易引发足底筋膜炎。另一种情况是如果鞋子弯折点过于靠前，或者为了增加球鞋的弹射感有一个大面积且硬质的延伸到前掌的碳板，像下面这种&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxexvwf08nj30gh08p0t6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;那每次往前走都需要跟腱施加更多的拉力，对跟腱则是一种负担。&lt;/p&gt;

&lt;p&gt;通过上面的分析之后，最不伤脚的抗扭设计已经差不多浮出水面了，那就是通过在鞋底大概中部的位置放上一块碳板或者TPU，这样既能保证球鞋的抗扭，也可以将自然弯折点引导到前掌。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxexuvphtvj30nw0hy0u7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxexwszyi5j30rs0rsmy7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;5-足弓支撑&quot;&gt;5. 足弓支撑&lt;/h3&gt;

&lt;p&gt;我们来看这张图，这张图中间这一列很好的展现了不健康的足弓是如何导致&lt;strong&gt;力线不正&lt;/strong&gt;的。力线不正的影响除了腿型的美观以外，还会使力斜向传导到膝盖，损伤我们的膝关节。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gx9xjnh4esj30hs0ep3zo.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;因此对于有扁平足的小伙伴，最好选带有足弓支撑的设计的球鞋。&lt;/p&gt;

&lt;h3 id=&quot;6-缓震与场地感&quot;&gt;6. 缓震与场地感&lt;/h3&gt;

&lt;p&gt;最近的这十几年来篮球鞋最有名的缓震科技当属Nike的Zoom气垫缓震科技了。这项科技由于其软弹适中的澎湃脚感，以及很强的抗衰减能力，可以说是高端篮球鞋的标志了。甚至 Nike 会以 Zoom 的数量、大小、厚度等等来区分篮球产品线的中高低端，而广大篮球爱好者也逐渐接受了这种设定，认为气垫越多越好，越大越好。&lt;/p&gt;

&lt;p&gt;但这种缓震配置真的好到适合所有人吗？&lt;/p&gt;

&lt;p&gt;我们以科比的签名鞋进化过程为例。科比战靴从4代开始每一代的设计都是科比本人高度参与的，科比将他本人对于篮球运动的深刻理解，极致地融入了球鞋设计中。&lt;/p&gt;

&lt;p&gt;4代设计中，科比第一次提出要打造一双最轻的篮球鞋，同时将极简的思路以及跑鞋元素融入了球鞋设计中。于是诞生了这双划时代的球鞋：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxhavk8ct9j30nc0ebjs7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这在当时几乎刷新了人们对于篮球鞋的认知，因为那时候认为篮球鞋一定要有很高的鞋帮才能有效的固定住脚踝，防止伤病，篮球鞋应该是高帮的几乎是公式一般的存在。但科比认为过高的鞋帮会限制他脚踝的灵活性，他作为后卫，需要做大量的变向急停动作，因此一双低帮、轻质的篮球鞋才更适合他的打法。&lt;/p&gt;

&lt;p&gt;回到Zoom气垫在这双鞋的使用上，作为Nike主打球星的签名战靴，它的前掌居然没有Zoom气垫，而只是在后掌放了一块马蹄形Zoom。采用这种配置的结果就是这双鞋前掌有着极低的重心，就像F1赛车一样，在快速移动中有一种“贴地飞行”的感觉，从而使球鞋不需要很多复杂的设计就可以有很强的稳定性和踏实感。&lt;/p&gt;

&lt;p&gt;这种贴地飞行的感觉也可以形容为&lt;strong&gt;场地感&lt;/strong&gt;，你感觉你的脚和场地更加亲近，于是更敢做动作，这对于小体重后卫球员来说是非常重要的性能。&lt;/p&gt;

&lt;p&gt;总结一句话，球鞋缓震性的必要程度取决于你的打法、体重、伤病史，以及对于场地感和缓震感的取舍。如果你是小快灵的后卫，则更薄、缓震科技不是软而是韧的前掌更适合你。而体重大的没有伤病史的人，其实也未必不能考虑科比4这种设计思路的球鞋，不要小看我们人自身进化而来的缓震属性，伤病的预防更多还是要靠自身肌肉的保护，别被气垫等等缓震科技惯坏了双脚。&lt;/p&gt;

&lt;p&gt;感慨一下那时候科比4引领的一波球鞋设计轻量化、简洁化的风潮，诞生了很多优秀的实战鞋。而科比去世后的这两年，耐克球鞋的设计几乎抛弃了科比系列一脉相承的思路，回到了堆叠配置的老路：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gxhbo1rf2dj30e80dydgz.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;但球鞋的实战性能并不一定随配置的堆叠而提升，在NBA赛场上还是有许多球员甚至内线球员穿着10年前的科比4代。&lt;/p&gt;

&lt;h2 id=&quot;4-选购策略&quot;&gt;4. 选购策略&lt;/h2&gt;

&lt;p&gt;总结一下选购策略，选择一双合脚的球鞋时，有的点是必备的，有些是根据自身条件进行取舍的。&lt;/p&gt;

&lt;h5 id=&quot;必备的点&quot;&gt;必备的点&lt;/h5&gt;

&lt;ol&gt;
  &lt;li&gt;足弓支撑（对于扁平足尤为重要）&lt;/li&gt;
  &lt;li&gt;抗扭&lt;/li&gt;
  &lt;li&gt;防侧翻&lt;/li&gt;
  &lt;li&gt;抓地&lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;斟酌选择&quot;&gt;斟酌选择&lt;/h5&gt;

&lt;ol&gt;
  &lt;li&gt;包裹：根据自身脚型条件选择对应鞋楦的鞋子。关注前掌包裹锁定以及后掌是否掉跟，追求鞋脚一体性。&lt;/li&gt;
  &lt;li&gt;缓震：不要选鞋底太软的鞋子。要在意缓震极限和自身体重的适配，不盲目追求澎湃脚感。&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;场地感：前掌的场地感和启动速度对于后卫打法有明显加成，但前掌重心的降低也就意味着牺牲一定的缓震性。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;位置打法：尽量根据自己的打法去选择球鞋，有一个比较偷懒但有效的方法是，可以看自己的打法更接近哪个球星，然后去找这个球星的战靴通常就是最适应这种打法的鞋子。然后再看看这双球星签名鞋是否满足以上说的几点，如果满足，那么它大概率就是一双适合你的鞋子。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;尾声&quot;&gt;尾声&lt;/h2&gt;

&lt;p&gt;我合上《灌篮》杂志，闭上眼许愿，虽然现在买不起这双惊艳到我的鞋子，但等自己工作赚钱了，也就10年后，那时候科比一定每年都还在亲自参与设计新的签名鞋吧，到时候我一定每一代都支持。&lt;/p&gt;

&lt;p&gt;这就是我与篮球鞋的故事，我的球鞋选购指南。&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Dec 2021 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2021/12/08/%E7%90%83%E9%9E%8B%E9%80%89%E8%B4%AD%E6%8C%87%E5%8D%97/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2021/12/08/%E7%90%83%E9%9E%8B%E9%80%89%E8%B4%AD%E6%8C%87%E5%8D%97/</guid>
        
        <category>攻略向</category>
        
        <category>生活指南</category>
        
        
      </item>
    
      <item>
        <title>小样本综述</title>
        <description>&lt;h1 id=&quot;小样本综述&quot;&gt;小样本综述&lt;/h1&gt;

&lt;p&gt;对于“小样本”这个词的定义不同的文章中定义不同，比如齐国君的综述&lt;sup id=&quot;fnref:9&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:9&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;中就将小样本定义为一个更宽泛的场景，即在标记数据少甚至无标记数据场景下所做的研究工作都归为在解决小样本问题。而发表于ACM的一篇综述&lt;sup id=&quot;fnref:10&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:10&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;则将小样本和few-shot划等号。本文主要借鉴的是齐国君综述的划分方法，也方便大体定位Few-Shot在深度学习领域的位置。&lt;/p&gt;

&lt;h2 id=&quot;一引言&quot;&gt;一、引言&lt;/h2&gt;

&lt;p&gt;深度学习方法在很多任务中表现好，多数情况是因为依赖于大量的标记数据，从而将模型训练到接近人的表现。然而在许多任务中，收集大量标注数据是非常困难的，因此催生了很多不使用标注数据来获得鲁棒模型的研究工作，主要包括以下两个大的思路方向：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;无标注数据&lt;/strong&gt;：无标注数据通常来说获取容易且数量较多，这些无标注数据的分布对于一个新的学习任务来说可以起到一定的指引作用。无标注数据主要用在&lt;strong&gt;无监督&lt;/strong&gt;和&lt;strong&gt;半监督方法&lt;/strong&gt;中，至于具体采用哪种方法取决于那些额外的标注数据对于模型训练是否有明显的提升。无标注数据帮助模型形成不同任务之间的域间隙（domain gap），这是无监督和半监督中域适应方法（domain adaption）这一大类方法的核心思路。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;辅助任务&lt;/strong&gt;：可以将小数据任务作为一个辅助任务的边缘信息。也就是说有一个目标任务之后，找到一个相关的、类似的任务来辅助目标任务的训练。其中包括zero-shot learning（无监督，无标注数据）和few-shot learning（半监督，少量的标记数据）。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guyh3hqn9fj61120ibjt202.jpg&quot; alt=&quot;image-20210930110321454&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;11-domain-adaptation&quot;&gt;1.1 Domain adaptation&lt;/h3&gt;

&lt;p&gt;在无监督和半监督领域都有应用到Domain adaptation的方法。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;domain可以理解为场景，比如飞机采集的数据，和卫星采集的数据，就可能为两个domain。在飞机domain训练表现良好的模型，直接换到卫星domain里表现就可能不好。&lt;/li&gt;
  &lt;li&gt;特征空间可以理解为评测体系，好比我要区分人和树，那么特征空间里的特征只需要包括是否有五官、是否有四肢之类简单的特征就足够区分。如果要区分人和人，仅凭五官和是否有四肢这些简单特征显然就不足以区分，也就是说在区分人和树那个特征空间中，不能完成人和人的分类任务&lt;/li&gt;
  &lt;li&gt;domain和特征空间：从上边对domain和特征空间的解释可以分析出，不同的domain会有与其相适应的特征空间，而如果目标任务或者数据来自于不同的domain，就需要domain adaption方法，将source domain和target domain的数据映射到同一个特征空间，于是在特征空间中对source domain训练的目标函数，就可以迁移到target domain上，提高target domain上的准确率。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;人类能够轻易的适应新的domain并识别熟悉的目标，但是检测模型在更换domain之后，会有明显的准确率下降。一些之前的专注于域迁移的深度神经网络模型主要是无监督域迁移方法（UDA），并且需要大量的目标域数据以及耗费大量时间，然而UDA和其他的无监督方法一样，只能处理简单的分类任务，对于目标检测等等需要精确的位置信息以及高分辨率信息的复杂任务，无法满足需求。&lt;/p&gt;

&lt;p&gt;而监督域迁移方法（SDA）基于论文&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;的研究，有限的目标样本仍然可以在很大程度上反映目标域的特征，比如照片、天气状况、外观等等。然而，仅使用少量目标数据样本来学习域不变表示非常具有挑战性，并且检测器需要细粒度的高分辨率特征来进行可靠的定位和分类。&lt;/p&gt;

&lt;h3 id=&quot;12-无监督方法&quot;&gt;1.2 无监督方法&lt;/h3&gt;

&lt;p&gt;无监督方法主要是通过寻求学习到对于数据足够泛化的&lt;strong&gt;表示（representation）&lt;/strong&gt;，来完成各种深度学习任务。比如VAE&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guvalt1t6wj61ef0l8tbb02.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guvarlikjvj60gm06qdg702.jpg&quot; alt=&quot;image-20210927170737918&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这种纯粹基于数据的方法，目前只能处理比较简单的任务，同时应用面比较窄对环境要求苛刻，主要停留在科研阶段。&lt;/p&gt;

&lt;p&gt;与纯无监督的方法相比，&lt;strong&gt;zero-shot learning&lt;/strong&gt; 通常通过词嵌入（word embedding）和视觉属性探讨概念之间的语义相关性，并使用它们将知识从源转移到目标概念。 鉴于一个新的样本，ZSL可以将其分配给看不见的概念（concept），其语义嵌入最接近样本的表示。 ZSL是无监督的，因为ZSL没有使用待识别类的标记样本训练模型。&lt;/p&gt;

&lt;p&gt;ZSL就是希望我们的模型能够对其从没见过的类别进行分类，让机器具有推理能力，实现真正的智能。其中零次（Zero-shot）是指对于要分类的类别对象，一次也不学习。&lt;/p&gt;

&lt;p&gt;假设我们的模型已经能够识别马，老虎和熊猫了，现在需要该模型也识别斑马，那么我们需要告诉模型，怎样的对象才是斑马，但是并不能直接让模型看见斑马。所以模型需要知道的信息是马的样本、老虎的样本、熊猫的样本和样本的标签，以及关于前三种动物和斑马的描述。这样的过程就是语义嵌入或者词嵌入。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guvb4fdqwtj60k00b275m02.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;13-半监督方法&quot;&gt;1.3 半监督方法&lt;/h3&gt;

&lt;p&gt;半监督方法同时使用未标记和有标记的样本来训练模型。 该想法在于，无标注的数据提供了数据通常情况下在特征空间的分布信息，并且可以通过探索该分布来训练强大的模型。 例如，鲁棒模型应该在随机变换（如平移、旋转、甚至随机扰动）下进行稳定和平滑的预测。在这个基础上加入一些监督信息对模型进行校正，从而实现更好的效果。&lt;/p&gt;

&lt;p&gt;Few-Shot learning（FSL）就是半监督方法中比较热门的一个方向。&lt;/p&gt;

&lt;h4 id=&quot;自监督预训练&quot;&gt;自监督预训练&lt;/h4&gt;

&lt;p&gt;自监督预训练通常使用无标记的&lt;strong&gt;source&lt;/strong&gt; data来预训练一个网络，使其能够被迁移到一个在&lt;strong&gt;target&lt;/strong&gt; dataset监督训练过程中。自监督预训练在标记数据成本很高的情景下非常有用，比如医疗和卫星数据中。&lt;/p&gt;

&lt;p&gt;自监督预训练通常需要在一个大的数据集中花费大量的训练时间，比如SimCLR就在ImageNet上训练了3200个epoch。同时instance contrastive learning对于数据增强策略的选择也是比较敏感的，需要许多的实验来选择最优的数据增强策略&lt;sup id=&quot;fnref:11&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:11&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;

&lt;p&gt;预训练策略也可以分为两种：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;generalist pretraining：&lt;/strong&gt;由于特定domain的数据集并不总是可以获取到的，所以作为替代方案，许多实验者会使用在一个很大型的通用的类似于ImageNet这种数据集上预训练模型。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;specialist pretraining&lt;/strong&gt;：在特定的数据集上进行预训练，通常会有更加明显的迁移结果提升&lt;sup id=&quot;fnref:12&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:12&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gwxas54kywj30l606j3zi.jpg&quot; alt=&quot;image-20211130171955181&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;instance-contrastive-learning&quot;&gt;Instance Contrastive Learning&lt;/h5&gt;

&lt;p&gt;通过判定增强过的图片是否来源于同一个原图像来训练网络，比如有名的Kaiming提出的MoCo&lt;sup id=&quot;fnref:14&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:14&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;

&lt;h5 id=&quot;hierarchical-pretraining&quot;&gt;Hierarchical Pretraining&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1gwxh68zqowj30gg09rabc.jpg&quot; alt=&quot;image-20211130210106954&quot; /&gt;&lt;/p&gt;

&lt;p&gt;HPT&lt;sup id=&quot;fnref:13&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:13&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;方法将Generalist Pretraining和Specialist Pretraining方法结合，在使用大的通用数据集预训练之后，再在与目标数据相似的数据集上按顺序进行预训练，从而在利用现有通用模型的同时提高specialist pretraining的性能。&lt;/p&gt;

&lt;h2 id=&quot;二few-shot-learning&quot;&gt;二、Few-shot Learning&lt;/h2&gt;

&lt;h3 id=&quot;21-问题定义&quot;&gt;2.1 问题定义&lt;/h3&gt;

&lt;p&gt;人类非常擅长通过极少量的样本识别一个新物体，比如小孩子只需要书中的一些图片就可以认识什么是“斑马”，什么是“犀牛”。在人类的快速学习能力的启发下，研究人员希望机器学习模型在&lt;strong&gt;学习了一定类别的大量数据后，对于新的类别，只需要少量的样本就能快速学习&lt;/strong&gt;，这就是 Few-shot Learning 要解决的问题。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Few-shot Learning 是&lt;/strong&gt; &lt;strong&gt;Meta Learning 在监督学习领域的应用。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meta Learning&lt;/strong&gt;，又称为 learning to learn，在 meta training 阶段将数据集分解为不同的 meta task，去学习类别变化的情况下模型的泛化能力，在 meta testing 阶段，面对全新的类别，不需要变动已有的模型，就可以完成分类。&lt;/p&gt;

&lt;p&gt;形式化来说，few-shot 的训练集中包含了很多的类别，每个类别中有多个样本。在训练阶段，会在训练集中随机抽取 C 个类别，每个类别 K 个样本（总共 CK 个数据），构建一个 meta-task，作为模型的支撑集（support set）输入；再从这 C 个类中剩余的数据中抽取一批（batch）样本作为模型的预测对象（batch set）。即要求模型从 C*K 个数据中学会如何区分这 C 个类别，&lt;strong&gt;这样的任务被称为 C-way K-shot 问题。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;训练过程中，每次训练（episode）都会采样得到不同 meta-task，所以总体来看，训练包含了不同的类别组合，这种机制使得模型学会不同 meta-task 中的共性部分，比如如何提取重要特征及比较样本相似等，忘掉 meta-task 中 task 相关部分。通过这种学习机制学到的模型，在面对新的未见过的 meta-task 时，也能较好地进行分类。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxyqjdq6lj61hr0grn1g02.jpg&quot; alt=&quot;image-20210930002807562&quot; /&gt;&lt;/p&gt;

&lt;p&gt;下图展示的是一个 3-way 2-shot 的示例，可以看到 meta training 阶段构建了一系列 meta-task 来让模型学习如何根据 support set 预测 batch set 中的样本的标签；meta testing 阶段的输入数据的形式与训练阶段一致（3-way 2-shot），但是会在全新的类别上构建 support set 和 batch。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxr28dxbkj61tm0u0qf902.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Few-shot Learning（FSL）和Zero-shot Learning（ZSL）类似的一点在于，它同样将不同的concept，共享嵌入的特征表示（embedding representation）。不同的是，FSL可以从收集的基础concept开始训练元模型，之后可以用新添加的样本（也就是few-shot中的“few”）来更新模型参数。&lt;/p&gt;

&lt;h3 id=&quot;22-few-shot处理分类问题&quot;&gt;2.2 few-shot处理分类问题&lt;/h3&gt;

&lt;p&gt;早期的 Few-shot Learning 算法研究多集中在图像领域，如下图所示，&lt;strong&gt;Few-shot Learning&lt;/strong&gt; &lt;strong&gt;模型大致可分为三类：&lt;/strong&gt;Mode Based，Metric Based 和 Optimization Based。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxzx5nkycj60qy09dwfb02.jpg&quot; alt=&quot;image-20210930010905121&quot; /&gt;&lt;/p&gt;

&lt;p&gt;其中 Model Based 方法旨在通过模型结构的设计快速在少量样本上更新参数，直接建立输入 x 和预测值 P 的映射函数；Metric Based 方法通过度量 batch 集中的样本和 support 集中样本的距离，借助最近邻的思想完成分类；Optimization Based 方法认为普通的梯度下降方法难以在 few-shot 场景下拟合，因此通过调整优化方法来完成小样本分类的任务。&lt;/p&gt;

&lt;h4 id=&quot;基于模型的方法&quot;&gt;基于模型的方法&lt;/h4&gt;

&lt;p&gt;Meta Network &lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; 的快速泛化能力源自其“快速权重”的机制，在训练过程中产生的梯度被用来作为快速权重的生成。模型包含一个 meta learner 和一个 base learner，meta learner 用于学习 meta task 之间的泛化信息，并使用 memory 机制保存这种信息，base learner 用于快速适应新的 task，并和 meta learner 交互产生预测输出。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gvc9nit5dnj60ia0ermxs02.jpg&quot; alt=&quot;image-20211012092343023&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;基于距离度量学习metric-learning的方法&quot;&gt;基于距离度量学习（metric learning）的方法&lt;/h4&gt;

&lt;p&gt;如果模型能够准确衡量两个图像的相似性（距离），那么它同样也能区分没有见过的无标注图像的距离。&lt;/p&gt;

&lt;p&gt;如果在 Few-shot Learning 的任务中去训练普通的基于 cross-entropy 的神经网络分类器，那么几乎肯定是会过拟合，因为神经网络分类器中有数以万计的参数需要优化。&lt;/p&gt;

&lt;p&gt;相反，很多非参数化的方法（最近邻、K-近邻、Kmeans）是不需要优化参数的，因此可以在 meta-learning 的框架下构造一种可以端到端训练的 few-shot 分类器。该方法是对样本间距离分布进行建模，使得同类样本靠近，异类样本远离。实现方法通常为，在训练过程中以距离或度量为条件对少数标记实例进行预测。常用的距离度量包括consine距离、欧氏距离、卷积网络相似模型、ridge regression、图神经网络。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;孪生网络（Siamese Network）&lt;/strong&gt;&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;通过有监督的方式训练孪生网络来学习，然后重用网络所提取的特征进行 one/few-shot 学习。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guy0342ecdj60o50b2t9b02.jpg&quot; alt=&quot;image-20210930011448668&quot; /&gt;&lt;/p&gt;

&lt;p&gt;具体的网络是一个双路的神经网络，训练时，通过组合的方式构造不同的成对样本，输入网络进行训练，在最上层通过样本对的距离判断他们是否属于同一个类，并产生对应的概率分布。在预测阶段，孪生网络处理测试样本和支撑集之间每一个样本对，最终预测结果为支撑集上概率最高的类别。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;原型网络（Prototype Network）&lt;/strong&gt;&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; 基于这样的想法：每个类别都存在一个原型表达，该类的原型是 support set 在 embedding 空间中的均值。然后，分类问题变成在 embedding 空间中的最近邻。&lt;/p&gt;

&lt;p&gt;如图 6 所示，c1、c2、c3 分别是三个类别的均值中心（称 Prototype），将测试样本 x 进行 embedding 后，与这 3 个中心进行距离计算，从而获得 x 的类别。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guy06z0p2rj60ba078wen02.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;前面介绍的几个网络结构在最终的距离度量上都使用了固定的度量方式，如 cosine，欧式距离等，这种模型结构下所有的学习过程都发生在样本的 embedding 阶段。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relation Network&lt;/strong&gt; &lt;sup id=&quot;fnref:6&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; 认为度量方式也是网络中非常重要的一环，需要对其进行建模，所以该网络不满足单一且固定的距离度量方式，而是训练一个网络来学习（例如 CNN）距离的度量方式，在 loss 方面也有所改变，考虑到 relation network 更多的关注 relation score，更像一种回归，而非 0/1 分类，所以使用了 MSE 取代了 cross-entropy。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guy05zg7w8j60im09swew02.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;optimization-based方法&quot;&gt;Optimization Based方法&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Ravi 等人&lt;/strong&gt; &lt;sup id=&quot;fnref:7&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:7&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; 研究了在少量数据下，基于梯度的优化算法失败的原因，即无法直接用于 meta learning。&lt;/p&gt;

&lt;p&gt;首先，这些梯度优化算法包括 momentum, adagrad, adadelta, ADAM 等，无法在几步内完成优化，特别是在非凸的问题上，多种超参的选取无法保证收敛的速度。&lt;/p&gt;

&lt;p&gt;其次，不同任务分别随机初始化会影响任务收敛到好的解上。虽然 finetune 这种迁移学习能缓解这个问题，但当新数据相对原始数据偏差比较大时，迁移学习的性能会大大下降。我们需要一个系统的学习通用初始化，使得训练从一个好的点开始，它和迁移学习不同的是，它能保证该初始化能让 finetune 从一个好的点开始。&lt;/p&gt;

&lt;p&gt;文章学习的是一个模型参数的更新函数或更新规则。它不是在多轮的 episodes 学习一个单模型，而是在每个 episode 学习特定的模型。&lt;/p&gt;

&lt;p&gt;具体地，学习基于梯度下降的参数更新算法，采用 LSTM 表达 meta learner，用其状态表达目标分类器的参数的更新，最终学会如何在新的分类任务上，对分类器网络（learner）进行初始化和参数更新。这个优化算法同时考虑一个任务的短时知识和跨多个任务的长时知识。&lt;/p&gt;

&lt;p&gt;文章设定目标为通过少量的迭代步骤捕获优化算法的泛化能力，由此 meta learner 可以训练让 learner 在每个任务上收敛到一个好的解。另外，通过捕获所有任务之前共享的基础知识，进而更好地初始化 learner。&lt;/p&gt;

&lt;p&gt;以训练 miniImage 数据集为例，训练过程中，从训练集（64 个类，每类 600 个样本）中随机采样 5 个类，每个类 5 个样本，构成支撑集，去学习 learner；然后从训练集的样本（采出的 5 个类，每类剩下的样本）中采样构成 Batch 集，集合中每类有 15 个样本，用来获得 learner 的 loss，去学习 meta leaner。&lt;/p&gt;

&lt;p&gt;测试时的流程一样，从测试集（16 个类，每类 600 个样本）中随机采样 5 个类，每个类 5 个样本，构成支撑集 Support Set，去学习 learner；然后从测试集剩余的样本（采出的 5 个类，每类剩下的样本）中采样构成 Batch 集，集合中每类有 15 个样本，用来获得 learner 的参数，进而得到预测的类别概率。这两个过程分别如图 8 中虚线左侧和右侧。&lt;/p&gt;

&lt;p&gt;meta learner 的目标是在各种不同的学习任务上学出一个模型，使得可以仅用少量的样本就能解决一些新的学习任务。这种任务的挑战是模型需要结合之前的经验和当前新任务的少量样本信息，并避免在新数据上过拟合。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Finn&lt;/em&gt;&lt;/strong&gt; &lt;sup id=&quot;fnref:8&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:8&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; 提出的方法使得可以在小量样本上，用少量的迭代步骤就可以获得较好的泛化性能，而且模型是容易 fine-tine 的。而且这个方法无需关心模型的形式，也不需要为 meta learning 增加新的参数，直接用梯度下降来训练 learner。&lt;/p&gt;

&lt;p&gt;文章的核心思想是学习模型的初始化参数使得在一步或几步迭代后在新任务上的精度最大化。它学的不是模型参数的更新函数或是规则，它不局限于参数的规模和模型架构（比如用 RNN 或 siamese）。它本质上也是学习一个好的特征使得可以适合很多任务（包括分类、回归、增强学习），并通过 fine-tune 来获得好的效果。&lt;/p&gt;

&lt;p&gt;文章提出的方法，可以学习任意标准模型的参数，并让该模型能快速适配。他们认为，一些中间表达更加适合迁移，比如神经网络的内部特征。因此面向泛化性的表达是有益的。因为我们会基于梯度下降策略在新的任务上进行 finetune，所以目标是学习这样一个模型，它能对新的任务从之前任务上快速地进行梯度下降，而不会过拟合。事实上，是要找到一些对任务变化敏感的参数，使得当改变梯度方向，小的参数改动也会产生较大的 loss。&lt;/p&gt;

&lt;h4 id=&quot;few-shot的baseline范式&quot;&gt;few-shot的baseline范式&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guwnae9vcsj60zu0feq5v02.jpg&quot; alt=&quot;image-20210928210624033&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNly1guwnemzvb1j60yk0gyadq02.jpg&quot; alt=&quot;image-20210928211031655&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;23-few-shot目标检测&quot;&gt;2.3 few-shot目标检测&lt;/h3&gt;

&lt;p&gt;现代卷积神经网络 (CNN) 的发展在一般目标检测 方面取得了巨大进步。 深度卷积网络检测模型需要大量带注释的训练数据才能使其性能饱和 。在小样本学习场景中，深度卷积网络检测模型会遭受更严重的过拟合，而且小样本检测和一般目标检测之间的差距大于小样本图像分类中的相应差距 。 如下表所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxrmsag27j60r206tdhb02.jpg&quot; alt=&quot;image-20210929202219640&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxrs1ulklj60ty0efjvc02.jpg&quot; alt=&quot;image-20210929202722692&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;few-shot-adaptive-faster-r-cnn&quot;&gt;Few-shot Adaptive Faster R-CNN&lt;/h4&gt;

&lt;p&gt;近两年few-shot应用到目标检测任务中的工作有2019年的Few-shot Adaptive Faster R-CNN&lt;sup id=&quot;fnref:4:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;，这篇工作主要创新点是设计了一个特征匹配机制以及强正则化。使用faster-rcnn作为backbone，结合了Domain adaption方法，并且由于结合了监督信息，相较于UDA方法动辄数万步的训练，论文中的Domain adaption方法只需要数百步的回传，提升了计算速度。所提出的SMFR方法使模型能够避免从少数目标数据样本中过度拟合，使得模型训练更稳定。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxy06pr7bj60o509pta502.jpg&quot; alt=&quot;image-20210930000248180&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这是论文里的3way-8shot的结果表：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxy7g4yxlj60dw0mpwgh02.jpg&quot; alt=&quot;image-20210930000946192&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;frustratingly-simple-few-shot-object-detection&quot;&gt;Frustratingly Simple Few-Shot Object Detection&lt;/h4&gt;

&lt;p&gt;这篇文章同样利用了faster-rcnn作为backbone。采用的是分类中之前常见的先用base数据集训练模型，然后固定一部分参数再fine-tune的方法。&lt;/p&gt;

&lt;p&gt;训练分为两步，第一步先在数据集的基础类上训练整个物体探测器，例如Faster R-CNN，然后第二步将少量的新类和基础类组成一个迷你数据集训练模型，这时候只需微调探测器的最后一个层，冻结模型的其他参数。 在微调阶段，提出了一种实例级特征归一化方法来优化检测框的分类。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxykpl3o5j61b80e3q6102.jpg&quot; alt=&quot;image-20210930002231052&quot; /&gt;&lt;/p&gt;

&lt;p&gt;论文中表示他们的方法相比其他的基于meta- learning的方法提升了2～20个百分点：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxyrekfblj61gl0mkjzy02.jpg&quot; alt=&quot;image-20210930002857265&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;fsce-few-shot-object-detection-via-contrastive-proposal-encoding&quot;&gt;FSCE: Few-Shot Object Detection via Contrastive Proposal Encoding&lt;/h4&gt;

&lt;p&gt;这是2021年CVPR发表的最新的方法，主要是基于Frustratingly Simple Few-Shot Object Detection这篇论文方法以及思路的延续和改进。在这项工作中观察并解决了基于微调（fine-tune）的方法的本质弱点——&lt;strong&gt;不断将新实例错误标记为易混淆的类别&lt;/strong&gt;，并将小样本检测性能提高到新的SOTA。&lt;/p&gt;

&lt;p&gt;这篇文章发现在few-shot应用到目标检测时，模型其实能够相对比较好的区分新类和背景，影响准确率的往往是相似类之间的误分类问题。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gvcajjvljvj614p0gidma02.jpg&quot; alt=&quot;image-20211012095429300&quot; /&gt;&lt;/p&gt;

&lt;p&gt;设计了一个CPE loss，借鉴了对抗学习的思想，能够使得特征空间里不同类之间的分布离得更远，其实也是一种度量学习类的方法：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxyw0z21tj60mx0hyn0102.jpg&quot; alt=&quot;image-20210930003323908&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这是第一个在few-shot目标检测 AP50中实现大于50%准确率的方法&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1guxzf37kgxj60jx088t9p02.jpg&quot; alt=&quot;image-20210930005143076&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;参考文献&quot;&gt;参考文献&lt;/h2&gt;

&lt;p&gt;[^]: 
[^]:&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:9&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Small Data Challenges in Big Data Era: A Survey of Recent Progress on Unsupervised and Semi-Supervised Methods &lt;a href=&quot;#fnref:9&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:10&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Generalizing from a Few Examples: A Survey on Few-shot Learning &lt;a href=&quot;#fnref:10&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Few-shot Adaptive Faster R-CNN &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:4:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:11&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Selfaugment: Automatic augmentation policies for self-supervised learning. &lt;a href=&quot;#fnref:11&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:12&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In-domain representation learning for remote sensing &lt;a href=&quot;#fnref:12&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:14&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Momentum Contrast for Unsupervised Visual Representation Learning &lt;a href=&quot;#fnref:14&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:13&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Self-Supervised Pretraining Improves Self-Supervised Pretraining &lt;a href=&quot;#fnref:13&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Munkhdalai, Tsendsuren, and Hong Yu. “Meta networks.” Proceedings of the 34th International Conference on Machine Learning-Volume 70. JMLR. org, 2017. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Siamese neural networks for one-shot image recognition &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Snell, Jake, Kevin Swersky, and Richard Zemel. “Prototypical networks for few-shot learning.” Advances in Neural Information Processing Systems. 2017. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:6&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Sung, Flood, et al. “Learning to compare: Relation network for few-shot learning.” Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2018. &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:7&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Ravi, Sachin, and Hugo Larochelle. “Optimization as a model for few-shot learning.” (2016). &lt;a href=&quot;#fnref:7&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:8&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Finn, Chelsea, Pieter Abbeel, and Sergey Levine. “Model-agnostic meta-learning for fast adaptation of deep networks.” Proceedings of the 34th International Conference on Machine Learning-Volume 70. JMLR. org, 2017. &lt;a href=&quot;#fnref:8&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 30 Sep 2021 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2021/09/30/%E5%B0%8F%E6%A0%B7%E6%9C%AC%E7%BB%BC%E8%BF%B0/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2021/09/30/%E5%B0%8F%E6%A0%B7%E6%9C%AC%E7%BB%BC%E8%BF%B0/</guid>
        
        <category>论文研究笔记</category>
        
        <category>深度学习</category>
        
        <category>AI</category>
        
        
      </item>
    
      <item>
        <title>遥感+深度学习研究综述</title>
        <description>&lt;h1 id=&quot;遥感深度学习研究综述&quot;&gt;遥感+深度学习研究综述&lt;/h1&gt;
&lt;h2 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#deep-learning-for-remote-sensing-images&quot;&gt;Deep Learning for Remote Sensing Images&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#traditional-methods-for-remote-sensing-images&quot;&gt;Traditional Methods for Remote Sensing Images&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#databases&quot;&gt;Databases&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#survey&quot;&gt;Survey&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;deep-learning-for-remote-sensing-images&quot;&gt;Deep Learning for Remote Sensing Images&lt;/h2&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;基于深度学习的遥感图像超分辨率&quot;&gt;基于深度学习的遥感图像超分辨率&lt;/h3&gt;

&lt;p&gt;论文：[TGARS20] Nonpairwise-Trained Cycle Convolutional Neural Network for Single Remote Sensing Image Super-Resolution. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/9151194&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;代码：https://github.com/haopzhang/CycleCNN&lt;/p&gt;

&lt;p&gt;物理方法提升空间分辨率的方法往往会减小传感器进光量以及信噪比，从而导致最终图像画质变差。使用超分辨率算法（super-resolution）则可以绕开前边的物理限制。SR也是一个在图像领域的经典课题，即将低分辨率图像处理为高分辨率图像。&lt;/p&gt;

&lt;p&gt;SR方法可以分为两种：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;单图像超分辨率（single image super-resolution, SISR）&lt;/li&gt;
  &lt;li&gt;多图像超分辨率（multiple images super-resolution, MISR）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;SISR更多的应用于遥感领域&lt;/strong&gt;，因为SISR比起MISR更适用于遥感领域存在多样化的图像传感器的特点。&lt;/p&gt;

&lt;p&gt;传统的SR方法主要基于插值和重建。插值方法包括近邻插值，双线性察之，基于深度学习方法的SR目前主要为SRCNN，VDSR和SRRessNet，显示出很好的效果。&lt;/p&gt;

&lt;h3 id=&quot;基于深度学习的毁坏房屋检测&quot;&gt;基于深度学习的毁坏房屋检测&lt;/h3&gt;

&lt;p&gt;由于垂直图像的内在限制，以及云层的遮挡，使得其在识别建筑物的结构损伤上存在天然的劣势。&lt;/p&gt;

&lt;h3 id=&quot;基于深度学习的遥感图像变化检测&quot;&gt;基于深度学习的遥感图像变化检测&lt;/h3&gt;

&lt;h5 id=&quot;s2looking-a-satellite-side-looking-dataset-for-building-change-detection&quot;&gt;S2Looking: A Satellite Side-Looking Dataset for Building Change Detection&lt;/h5&gt;

&lt;p&gt;这篇工作提出了一个基于卫星图像的建筑物变化监测监督数据集&lt;strong&gt;S2Looking&lt;/strong&gt;。其相较于类似的诸如LEVIR-CD数据集的主要区别为，S2Looking包括同一建筑物的不同拍摄角度，这考验检测模型在角度变化情况下仍然能够识别同一建筑的能力。&lt;/p&gt;

&lt;p&gt;包括5000对标注过的图像，大小为1024×1024，0.5～0.8米/像素。将多了的和少了的建筑物都进行了标注。&lt;/p&gt;

&lt;p&gt;文章在S2Looking数据集上测试了几个在LEVIR-CD数据集上的SOTA模型，发现结果并不好。分析原因主要有三个：&lt;/p&gt;

&lt;p&gt;1) S2Looking有大尺度视野上的观察角变化
2) 明亮度上的差异较大
3) 在农村地区的图像中有各种复杂的场景特征&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gtl2tmpj0gj60u012k10w02.jpg&quot; alt=&quot;image-20210818173644332&quot; /&gt;&lt;/p&gt;

&lt;p&gt;传统方法很容易被多变的图片细节以及质量区别干扰准确率，因此越来越多的深度学习方法应用到这个领域。包括dual atten- tive fully convolutional Siamese networks (DASNet)， image fusion networks (IFN) ， end-to-end change detection based on UNet++ (CD-UNet++) ， fully convolutional Siamese networks based on concatenation and difference (FC-Siam-Conc and FC-Siam- Diff) ，dual-task constrained deep Siamese convolutional network model (DTCDSCN) 。&lt;/p&gt;

&lt;h5 id=&quot;dasnet-dual-attentive-fully-convolutional-siamese-networks-for-change-detection-in-high-resolution-satellite-images&quot;&gt;DASNet: Dual attentive fully convolutional siamese networks for change detection in high-resolution satellite images&lt;/h5&gt;

&lt;p&gt;传统的变化检测可以分为两大类：&lt;strong&gt;基于像素的变化检测&lt;/strong&gt;和&lt;strong&gt;基于目标的变化检测&lt;/strong&gt;。传统的基于像素的变化检测往往会忽略空间信息，以及结构语义信息，并且容易受到噪声影响。DASNet模型针对这一问题提出了解决方案，提出了dual attention机制来定位发生变化的区域从而获得更有区分度的特征表示，这使得学习到的特征更加具有鲁棒性。&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gtmfarg38mj60i20aewev02.jpg&quot; alt=&quot;image-20210819213402543&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/008i3skNgy1gtmf1zfmzsj618g0jvjw102.jpg&quot; alt=&quot;image-20210819212532651&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;2020&quot;&gt;2020&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Remote Sensing Image Super-Resolution Using Novel Dense-Sampling Networks. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/9107103&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Remote Sensing Image Super-Resolution via Mixed High-Order Attention Network. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/9151234&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Coupled Adversarial Training for Remote Sensing Image Super-Resolution. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/8946581&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Nonpairwise-Trained Cycle Convolutional Neural Network for Single Remote Sensing Image Super-Resolution. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/9151194&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Improving the Spatial Resolution of Landsat TM/ETM+ Through Fusion With SPOT5 Images via Learning-Based Super-Resolution. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/6866167&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[TGARS20] Satellite Video Super-Resolution Based on Adaptively Spatiotemporal Neighbors and Nonlocal Similarity Regularization. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/9080534&quot;&gt;Paper&lt;/a&gt;]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;[RemoteSens20] Improved SRGAN for Remote Sensing Image Super-Resolution Across Locations and Sensors. [[Paper]]&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;2019&quot;&gt;2019&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;[TGARS19] Super-Resolution of Single Remote Sensing Image Based on Residual Dense Backprojection Networks. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/8732688&quot;&gt;Paper&lt;/a&gt;]&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;traditional-methods-for-remote-sensing-images&quot;&gt;Traditional Methods for Remote Sensing Images&lt;/h2&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;2019-1&quot;&gt;2019&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;[RemoteSens19] Improving Remote Sensing Image Super-Resolution Mapping Based on the Spatial Attraction Model by Utilizing the Pansharpening Technique. [[Paper]]&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;2018&quot;&gt;2018&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;[TGARS18] Adaptive Super-Resolution for Remote Sensing Images Based on Sparse Representation With Global Joint Dictionary Model. [&lt;a href=&quot;https://ieeexplore.ieee.org/document/8197387&quot;&gt;Paper&lt;/a&gt;]&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;others&quot;&gt;Others&lt;/h2&gt;
&lt;hr /&gt;

&lt;h2 id=&quot;databases&quot;&gt;Databases&lt;/h2&gt;
&lt;hr /&gt;
&lt;ol&gt;
  &lt;li&gt;UC Merced dataset &lt;a href=&quot;http://weegee.vision.ucmerced.edu/datasets/landuse.html&quot;&gt;offical&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;AID dataset &lt;a href=&quot;http://www.lmars.whu.edu.cn/xia/AID-project.html&quot;&gt;offical&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;USC_SIPI image database &lt;a href=&quot;http://sipi.usc.edu/database/database.php.&quot;&gt;offical&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NWPU VHR-10 dataset &lt;a href=&quot;http://pan.baidu.com/s/1hqwzXeG.&quot;&gt;baidu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NWPU-RESISC45 dataset &lt;a href=&quot;https://pan.baidu.com/s/1mifR6tU(BaiduWangpan)#list/path=%2F&quot;&gt;baidu&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;survey&quot;&gt;Survey&lt;/h2&gt;
&lt;hr /&gt;

&lt;h2 id=&quot;related-links&quot;&gt;Related Links&lt;/h2&gt;
&lt;hr /&gt;
</description>
        <pubDate>Wed, 11 Aug 2021 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2021/08/11/%E9%81%A5%E6%84%9F+%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%A0%94%E7%A9%B6%E7%BB%BC%E8%BF%B0/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2021/08/11/%E9%81%A5%E6%84%9F+%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%A0%94%E7%A9%B6%E7%BB%BC%E8%BF%B0/</guid>
        
        <category>论文研究笔记</category>
        
        <category>深度学习</category>
        
        <category>AI</category>
        
        
      </item>
    
      <item>
        <title>你新买的 MacBook air M1 所需的配置工作</title>
        <description>&lt;h1 id=&quot;你新买的-macbook-air-m1-所需的配置工作&quot;&gt;你新买的 MacBook air M1 所需的配置工作&lt;/h1&gt;

&lt;h2 id=&quot;安装brew&quot;&gt;安装brew&lt;/h2&gt;

&lt;p&gt;Homebrew官网：https://docs.brew.sh/Installation#1，M1出来之后brew也是在持续更新。期待M1环境下的软件兼容性越来越好。&lt;/p&gt;

&lt;h3 id=&quot;1-准备目录&quot;&gt;1. 准备目录&lt;/h3&gt;

&lt;p&gt;M1之后，不能放到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt;目录下了。要放到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt&lt;/code&gt;目录下 所以新建&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt&lt;/code&gt;目录，执行:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /opt &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo chmod&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; 777 ./
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;授权给所有用户所有权限。&lt;/p&gt;

&lt;h3 id=&quot;2-安装&quot;&gt;2. 安装&lt;/h3&gt;

&lt;p&gt;进入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt/&lt;/code&gt;路径，在终端中执行:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;homebrew &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; https://github.com/Homebrew/brew/tarball/master | &lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;xz &lt;span class=&quot;nt&quot;&gt;--strip&lt;/span&gt; 1 &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; homebrew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-配置环境变量&quot;&gt;3. 配置环境变量&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo vim /etc/profile 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在最后一行添加&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export PATH=$PATH:/opt/Homebrew/bin&lt;/code&gt;之后终端执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source /etc/profile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;这里遇到一个关键问题是，每次在重启电脑后都需要再次执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source /etc/profile&lt;/code&gt; 配置环境变量。原因是：&lt;/p&gt;

&lt;p&gt;首先&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim ~/.zprofile&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20190126100347400.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25pbmd5YW5nZ2VnZQ==,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;缺少$PATH部分。&lt;/p&gt;

&lt;p&gt;系统先加载/etc/profile 然后再加载~/.bash_profile，由于开始没有红圈圈那部分，最终的环境变量就只有~/.zprofile部分；/etc/profile配置的环境变量均无用。加上就OK了。&lt;/p&gt;

&lt;h2 id=&quot;oh-my-zsh&quot;&gt;oh my zsh&lt;/h2&gt;

&lt;h3 id=&quot;1-安装oh-my-zsh&quot;&gt;1. 安装oh-my-zsh&lt;/h3&gt;

&lt;p&gt;这里提供三种方法安装oh-my-zsh&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1、使用wget安装：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sh -c &quot;$(wget -O- https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;2、使用curl安装：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sh -c &quot;$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;3、手动安装：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -Lo install.sh https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
sh install.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;执行脚本会有命令行交互，询问是否要启用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zsh shell&lt;/code&gt;，回车&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;。开始使用&lt;/p&gt;

&lt;h3 id=&quot;2-设置主题&quot;&gt;2. 设置主题&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oh-my-zsh&lt;/code&gt;提供了很多主题，可以通过命令查看当前使用的主题：&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; ~/.oh-my-zsh/themes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以通过编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.zshrc&lt;/code&gt;文件来修改你的主题&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vi ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;推荐选用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ys&lt;/code&gt;主题，简洁并且该有的信息都有：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/0081Kckwly1gm9uz8mtc5j30jg02ewf0.jpg&quot; alt=&quot;截屏2021-01-03 上午1.18.48&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;3zsh-autosuggestions自动补全插件&quot;&gt;3.&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zsh-autosuggestions&lt;/code&gt;自动补全插件&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;下载该插件到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.oh-my-zsh&lt;/code&gt;的插件目录&lt;/p&gt;

    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone git://github.com/zsh-users/zsh-autosuggestions &lt;span class=&quot;nv&quot;&gt;$ZSH_CUSTOM&lt;/span&gt;/plugins/zsh-autosuggestions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.zshrc&lt;/code&gt;文件&lt;/p&gt;

    &lt;p&gt;找到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugins=(git)&lt;/code&gt;这一行，如果没有添加。更改为如下&lt;/p&gt;

    &lt;pre&gt;&lt;code class=&quot;language-undefined&quot;&gt;plugins=(git zsh-autosuggestions)
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;重启命令&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;tmux&quot;&gt;tmux&lt;/h2&gt;

&lt;p&gt;tmux 是一款终端复用命令行工具，一般用于 Terminal 的窗口管理。在 macOS 下，使用 iTerm2 能应付绝大多数窗口管理的需求。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images2015.cnblogs.com/blog/520689/201701/520689-20170111205923853-1701606139.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如上图所示，iTerm2 能新建多个标签页（快捷键 ⌘T），也能在同一个窗口中分割出多个窗格（快捷键 ⌘D 或 ⌘⇧D）。&lt;/p&gt;

&lt;p&gt;tmux 相比 iTerm2 的优势在于：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;iTerm2 的窗格切换快捷键（⌘⌥→）容易与其他软件全局快捷键冲突（例如 Spectacle 的窗口分割快捷键），tmux 由于存在前缀快捷键，所以不存在快捷键冲突问题；&lt;/li&gt;
  &lt;li&gt;tmux 可以在终端软件重启后通过命令行恢复上次的 session ，而终端软件则不行；&lt;/li&gt;
  &lt;li&gt;tmux 简洁优雅、订制性强，学会之后也能在 Linux 上使用，有助于逼格提升。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;接下来我们花十分钟来掌握下 tmux 的基础用法：&lt;/p&gt;

&lt;h3 id=&quot;安装运行&quot;&gt;安装运行&lt;/h3&gt;

&lt;p&gt;macOS 上使用 Homebrew 安装即可：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew install tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;安装完成后，运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmux&lt;/code&gt; 新建一个 tmux 的会话（session），此时窗口唯一的变化是在底部会出现一个 tmux 的状态栏。我们先按下 tmux 默认的前缀快捷键 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; 将其激活为快捷键接收模式，再按下 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%&lt;/code&gt; ，即可将当前窗口切分为左右两个窗格。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images2015.cnblogs.com/blog/520689/201701/520689-20170111205933322-578444111.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;快捷键&quot;&gt;快捷键&lt;/h3&gt;

&lt;p&gt;一般情况下 tmux 中所有的快捷键都需要和前缀快捷键 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; 来组合使用（注：⌃ 为 Mac 的 control 键），以下是常用的窗格（pane）快捷键列表，大家可以依次尝试下：&lt;/p&gt;

&lt;h4 id=&quot;窗格操作&quot;&gt;窗格操作&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%&lt;/code&gt; 左右平分出两个窗格&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&lt;/code&gt; 上下平分出两个窗格&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; 关闭当前窗格&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{&lt;/code&gt; 当前窗格前移&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;}&lt;/code&gt; 当前窗格后移&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;;&lt;/code&gt; 选择上次使用的窗格&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt; 选择下一个窗格，也可以使用上下左右方向键来选择&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;space&lt;/code&gt; 切换窗格布局，tmux 内置了五种窗格布局，也可以通过 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌥1&lt;/code&gt; 至 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌥5&lt;/code&gt;来切换&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt; 最大化当前窗格，再次执行可恢复原来大小&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; 显示所有窗格的序号，在序号出现期间按下对应的数字，即可跳转至对应的窗格&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;窗口操作&quot;&gt;窗口操作&lt;/h4&gt;

&lt;p&gt;tmux 除了窗格以外，还有窗口（window） 的概念。依次使用以下快捷键来熟悉 tmux 的窗口操作：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c&lt;/code&gt; 新建窗口，此时当前窗口会切换至新窗口，不影响原有窗口的状态&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; 切换至上一窗口&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; 切换至下一窗口&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;w&lt;/code&gt; 窗口列表选择，注意 macOS 下使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃p&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃n&lt;/code&gt; 进行上下选择&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; 关闭当前窗口&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;,&lt;/code&gt; 重命名窗口，可以使用中文，重命名后能在 tmux 状态栏更快速的识别窗口 id&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; 切换至 0 号窗口，使用其他数字 id 切换至对应窗口&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; 根据窗口名搜索选择窗口，可模糊匹配&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://images2015.cnblogs.com/blog/520689/201701/520689-20170111205944010-1132178011.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;会话操作&quot;&gt;会话操作&lt;/h4&gt;

&lt;p&gt;如果运行了多次 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmux&lt;/code&gt; 命令则会开启多个 tmux 会话（session）。在 tmux 会话中，使用前缀快捷键 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; 配合以下快捷键可操作会话：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt; 重命名当前会话&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; 选择会话列表&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt; detach 当前会话，运行后将会退出 tmux 进程，返回至 shell 主进程&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在 shell 主进程下运行以下命令可以操作 tmux 会话：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tmux new -s foo # 新建名称为 foo 的会话
tmux ls # 列出所有 tmux 会话
tmux a # 恢复至上一次的会话
tmux a -t foo # 恢复名称为 foo 的会话，会话默认名称为数字
tmux kill-session -t foo # 删除名称为 foo 的会话
tmux kill-server # 删除所有的会话
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;除以上提到的快捷键以外，tmux 还有许多其他的快捷键和命令，使用前缀快捷键 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; 加 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; 可以查看所有的快捷键列表，该列表视图为 &lt;strong&gt;tmux copy 模式&lt;/strong&gt;，该模式下可使用以下快捷键（无需加 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; 前缀）：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃v&lt;/code&gt; 下一页&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Meta v&lt;/code&gt; 上一页 （tmux 快捷键为 Emacs 风格，这里的 Meta 键可用 Esc 模拟）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃s&lt;/code&gt; 向前搜索&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; 退出 copy 模式&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;常见配置与问题&quot;&gt;常见配置与问题&lt;/h3&gt;

&lt;h4 id=&quot;1鼠标滚屏&quot;&gt;1、鼠标滚屏&lt;/h4&gt;

&lt;p&gt;tmux 默认配置中最糟糕的体验就是滚屏查看和文本复制（大家可以先试试看）。你需要先使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt; 快捷键进入 copy 模式，然后使用翻页、字符定位来选择需要的字符，效率远没有鼠标选择来的快。&lt;/p&gt;

&lt;p&gt;因此 tmux 提供了一些个性化配置项来优化这些配置，首先在 shell 中运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;touch ~/.tmux.conf&lt;/code&gt; 新建用户配置文件。在文件中增加以下内容：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 开启鼠标模式
set -g mode-mouse on

# 允许鼠标选择窗格
set -g mouse-select-pane on

# 如果喜欢给窗口自定义命名，那么需要关闭窗口的自动命名
set-option -g allow-rename off

# 如果对 vim 比较熟悉，可以将 copy mode 的快捷键换成 vi 模式
set-window-option -g mode-keys vi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;配置文件修改完成后，可以 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmux kill-server&lt;/code&gt; 重启所有 tmux 进程，或者在 tmux 会话中使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt; 进入控制台模式，输入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source-file ~/.tmux.conf&lt;/code&gt; 命令重新加载配置。&lt;/p&gt;

&lt;h4 id=&quot;2鼠标复制&quot;&gt;2、鼠标复制&lt;/h4&gt;

&lt;p&gt;tmux 下开启鼠标滚屏后，复制文本有两种方式：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;方法 1：使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌃b&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt; 进入窗格全屏模式，鼠标选择文本的同时按住 option 键 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌥&lt;/code&gt;，然后使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;⌘c&lt;/code&gt; 进行复制；&lt;/li&gt;
  &lt;li&gt;方法 2：开启 iTerm2 「在选择时复制」选项，即可实现自动选择复制。如下图：&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://images2015.cnblogs.com/blog/520689/201701/520689-20170111210013541-836018258.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;3tips&quot;&gt;3、tips&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://hyperpolyglot.org/multiplexers&quot;&gt;screen&lt;/a&gt; 是另外一款终端复用命令行，但他没有 tmux 好看好用；&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard#mac-os-x-pasteboard-access-under-tmux-and-screen&quot;&gt;tmux 有个 bug&lt;/a&gt; ，导致从它启动的 vscode 的复制粘贴快捷键会失效；&lt;/li&gt;
  &lt;li&gt;iTerm2 可以通过 「Preferences -&amp;gt; Profiles -&amp;gt; Keyboard Behavior -&amp;gt; Left option key acts as +Esc」将键盘的左侧 option 键映射为 Meta 键&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 06 Jan 2021 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2021/01/06/%E4%BD%A0%E6%96%B0%E4%B9%B0%E7%9A%84MacBook-air-M1%E6%89%80%E9%9C%80%E7%9A%84%E9%85%8D%E7%BD%AE%E5%B7%A5%E4%BD%9C/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2021/01/06/%E4%BD%A0%E6%96%B0%E4%B9%B0%E7%9A%84MacBook-air-M1%E6%89%80%E9%9C%80%E7%9A%84%E9%85%8D%E7%BD%AE%E5%B7%A5%E4%BD%9C/</guid>
        
        <category>学习笔记</category>
        
        
      </item>
    
      <item>
        <title>Uncertainty on Brats</title>
        <description>&lt;h1 id=&quot;uncertainty-on-brats&quot;&gt;Uncertainty On BraTS&lt;/h1&gt;

&lt;p&gt;uncertainty这项理论应用到临床医学的意义重大，但实际上关于各种uncertainty方法在医学数据上的效果以及挑战的相关研究仍然很少。而以目前的一些研究成果来看，当前的各种方法的表现实际上是非常接近的，值得注意的是，当前的方法虽然在数据集层面上表现不错，但&lt;strong&gt;在具体样本层面上表现很不稳定&lt;/strong&gt;。&lt;strong&gt;辅助网络（auxiliary networks）&lt;/strong&gt;可以替代常规的uncertainty方法因为它们可以适用于预训练模型。&lt;/p&gt;

&lt;p&gt;医疗图像分割领域，不确定性主要关注点在以下三个层次：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;体素级别的uncertainty，这对于辅助医生的诊断至关重要&lt;/li&gt;
  &lt;li&gt;实例分割层面的不确定性（将体素不确定性汇总），能够降低错误率&lt;/li&gt;
  &lt;li&gt;样本层面的不确定性，这样能告诉我们当前得到的分割结果是否成功&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;softMax entropy（baseline）中 uncertainty 的度量：
\(H = -\sum_{c\in C}\frac{p_clog(p_c)}{log(|C|)} \in[0,1]\)&lt;/p&gt;

&lt;p&gt;$p_c$是第$c$类预测的softMax输出，$C$是所有类的集合。&lt;/p&gt;

&lt;h4 id=&quot;几种benchmark&quot;&gt;几种benchmark：&lt;/h4&gt;

&lt;p&gt;a) Bayesian uncer- tainty estimation via test-time dropout [5],&lt;/p&gt;

&lt;p&gt;test-time dropout 可以认为是BNN的近似。T个随机dropout网络生成概率预测，将这些概率的归一化熵用作不确定性的度量，$p_c=\frac{1}{T}\sum^T_{t=1}p_{t,c}$。目前有两种dropout方法，一种是在每个卷积层后都加一个p=0.05的dropout（称为baseline+MC），另一种是在中心位置使用p=0.5的dropout（称为center+MC），两个方法同样使用T=20。&lt;/p&gt;

&lt;p&gt;b) aleatoric uncertainty estimation via a second network output [9]&lt;/p&gt;

&lt;p&gt;MC dropout 衡量模型预测中存在的不确定性，偶然不确定性方法衡量观测中的固有噪声。这种方法学习一个函数$f(x)$，输入训练数据$x$得到两个输出 $[\hat x,\sigma^2]$，这两个输出是经过高斯噪声扰乱的logits的均质和方差。通过 &lt;strong&gt;aleatoric loss&lt;/strong&gt; 来优化两个输出，同时将这两个输出作为uncertainty的度量。&lt;/p&gt;

&lt;p&gt;c) uncertainty estimation via ensembling of networks [10].&lt;/p&gt;

&lt;p&gt;使用k个训练好的网络取平均，$p_c=\frac{1}{K}\sum^K_{k=1}p_{k,c}$。每个独立的网络使用同样的模型算法，但使用不同的子集和不同的初始化参数训练。&lt;/p&gt;

&lt;p&gt;d) Auxiliary network&lt;/p&gt;

&lt;p&gt;辅助网络方法是用来预测样本级的分割表现的。有两个辅助网络：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;auxiliary feat&lt;/strong&gt;，包括三个连续的1*1卷积网络与分割网络的最后一个特征层相连。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;auxiliary segm&lt;/strong&gt;，是一个完全独立的U-net网络，网络的输入为原始图像和分割模型得到的分割mask。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;几种metric&quot;&gt;几种metric：&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Calibration&lt;/strong&gt; ，当一个模型在 $P(y=1&lt;/td&gt;
          &lt;td&gt;f(x)=p)=p$ （二分类模型）时，对于自己的预测$f(x)$置信度为$p$，那么则称为完美的校准。举个例子，这意味着置信度为0.7的模型预测100次，那么刚好其中70个的预测是正确的。&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Uncertainty-Error overlap&lt;/strong&gt; ，通常，分割任务不需要完美的校准，但是对于模型来说，确定哪里出错了并确定哪里正确就足够了。U-E其实表达的是分割错误区域和低置信度区域（阈值控制）之间的重合度。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Corrections&lt;/strong&gt; ，有几个简写需要注意，TPU (uncertainty in the true positives)，TNU (uncertainty in the true negatives)，FPU(uncertainty in the false positives)，FNU(uncertainty in the false negatives)。当满足假阳性的不确定性FPU &amp;gt; 真阴性的不确定性TPU时，可以通过修正假阳性来提升Dice系数。表中BnF（benefit condition for false positive removal）作为简写。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;result&quot;&gt;Result&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/007S8ZIlly1gdzgbrmhetj30pn09had7.jpg&quot; alt=&quot;image-20200419223633325&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Apr 2020 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2020/04/19/Uncertainty-on-Brats/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2020/04/19/Uncertainty-on-Brats/</guid>
        
        <category>论文阅读</category>
        
        
      </item>
    
      <item>
        <title>医疗分割uncertainty综述</title>
        <description>&lt;h1 id=&quot;医疗分割uncertainty综述&quot;&gt;医疗分割uncertainty综述&lt;/h1&gt;

&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;近年来，深度学习推动了医学成像分割领域的最新发展。 但是，先前的工作倾向于将准确性最大化，而忽略了预测不确定性。 在像素级上对不确定性进行建模与精度一样重要，尤其是在医疗场景中，因为它可以使临床医生了解模型输出的可信度。本文对uncertainty的几种基本的方法进行说明，并对2019年将uncertainty方法应用到医疗分割的论文进行综述。&lt;/p&gt;

&lt;h2 id=&quot;1introduction&quot;&gt;1.Introduction&lt;/h2&gt;

&lt;p&gt;目前深度学习在很多领域的表现都非常好，现在大多数深度学习算法几乎只能给出一个&lt;strong&gt;高置信度&lt;/strong&gt;的预测结果，而不能给出模型自己对结果有多么确信。深度学习模型得到的这些高置信度预测通常由softmax产生，因为softmax概率是用快速增长的指数函数计算的，因此对softmax输入（即logit）进行少量添加就会导致输出分布发生实质性变化。&lt;/p&gt;

&lt;p&gt;实际上在理想情况下，当你给我几张猫和狗的图片然后要求我对一张新的猫照片进行分类，那么我应该非常有信心地返回预测。 但是，如果你给我一张鸵鸟的照片，并强迫我确定它是猫还是狗，那么这种情况下，我应该以较低的预测信心返回我的结果。&lt;/p&gt;

&lt;p&gt;模型具有这种能力在很多领域都是至关重要的，比如在无人驾驶领域，能够使机器在决策时采用更加合理的方式。在医疗领域，医生可以通过模型对于诊断的确信度来加以判断等等。&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;假设训练数据集表示为$D = {(x_i,y_i)}^N_{i=1}$，输入为$x_i$ ，分割标注为$y_i$，神经网络的参数为$\theta$。我们可以将神经网络想象成一个条件分布$p(y&lt;/td&gt;
      &lt;td&gt;x,\theta)$。当输入测试数据时，&lt;strong&gt;预测后验分布&lt;/strong&gt;为$p(y_&lt;em&gt;,x_&lt;/em&gt;,D) = \int p(y_*&lt;/td&gt;
      &lt;td&gt;x_*,\theta)p(\theta&lt;/td&gt;
      &lt;td&gt;D)d\theta$，这里$p(\theta&lt;/td&gt;
      &lt;td&gt;D)$是给定训练集得到的参数$\theta$的后验分布。预测的后验分布很难直接得到，因此需要通过某些比较易得的分布$q_\lambda(\theta)$进行近似，其中$\lambda$被称为variational parameters。通过最小化KL散度$KL[q_\lambda(\theta)&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;p(\theta&lt;/td&gt;
      &lt;td&gt;D)]$的相反数，便能得到$p(\theta&lt;/td&gt;
      &lt;td&gt;D)$的近似$q_\lambda(\theta)$。而最终想要得到的&lt;strong&gt;预测不确定性&lt;/strong&gt;是预测后验分布的方差。&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;通常，不确定性主要有两种类型，&lt;strong&gt;偶然不确定性&lt;/strong&gt;和&lt;strong&gt;认知不确定性&lt;/strong&gt;。偶然不确定性是对数据中固有的，不可减少的噪声的度量，通常与数据采集过程相关。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcshyg2awoj30fr06lt9b.jpg&quot; alt=&quot;图1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;认知不确定性是我们对模型参数真实值的不确定性，这是由训练集的有限大小引起的。 随着训练集规模的增加，认知不确定性渐近趋于零。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcsi0mfmjnj30h002a3yt.jpg&quot; alt=&quot;截屏2020-03-13下午6.55.02&quot; /&gt;&lt;/p&gt;

&lt;p&gt;通常情况下认知不确定性很难测量，原因是我们需要数据集提供的ground truth进行训练，而很难获取数据集和真实情况的ground truth的差距。假设训练集有N个图片${x_i}^N_{i=1}$，如果第$i$个图像有D个分割标注者${y^1&lt;em&gt;i,…,y^D_i}$，定义这些像素点的分割标记的偶然不确定性为$V&lt;/em&gt;{p(D)}[y_i]=\frac{1}{D}\sum ^D_{j=1}(y^j_i-\bar{y}&lt;em&gt;i)^2$，其中$\bar{y}_i=\frac{1}{D}\sum ^D&lt;/em&gt;{j=1}y^j_i$。&lt;/p&gt;

&lt;h2 id=&quot;2classical-methods&quot;&gt;2.Classical methods&lt;/h2&gt;

&lt;h3 id=&quot;21-bayesian-nns&quot;&gt;2.1 Bayesian NNs&lt;/h3&gt;

&lt;p&gt;uncertainty中一个&lt;strong&gt;传统并且基本的思想&lt;/strong&gt;来自于贝叶斯网络的应用，思想的关键很简单：在贝叶斯世界观中，所有事物都附有概率分布，包括模型参数（NN中的权重和偏差）。例如在编程语言中，我们拥有可以采用特定值的变量，并且每次访问该变量时，都会获得相同的值。与此相反，在贝叶斯世界中，我们有类似的实体，它们被称为随机变量，每次访问它时都会赋予不同的值。 因此，如果X是代表正态分布的随机变量，则每次访问X时，它的值都会不同。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;从随机变量获取新值的过程称为采样&lt;/strong&gt;。 产生什么值取决于随机变量的相关概率分布。 与随机变量关联的概率分布越广，其值的不确定性就越大，因为根据（宽）概率分布，它可以取任何值。如果随机变量是两次掷骰子的位数之和，则每次掷骰都会获得一个值，该值的概率取决于下图2所示分布。 这意味着最可能获得的点数总和是7，最不可能获得的是2和12。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvsx511y8j30x20n0afu.jpg&quot; alt=&quot;图2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在传统的神经网络中具有固定的权重和偏差，这些权重和偏差决定了如何将输入转换为输出。 在贝叶斯神经网络中，所有权重和偏差都具有附加的概率分布。 为了对图像进行分类，需要对网络进行多次运行，每次都使用一组新的采样权重和偏差，而不是一组输出值，得到的是多个集合。每个运行一次。 输出值集表示输出值的概率分布，因此可以找出每个输出的置信度和不确定性。 如果输入图像是网络从未见过的东西，那么对于所有输出类别，不确定性都将很高，网络应该解释说：“我真的不知道该图像是关于什么的”。&lt;/p&gt;

&lt;p&gt;推理是整个过程中最关键的步骤。它基于著名的贝叶斯定理。
\(P(A|B)=\frac{P(B|A)P(A)}{P(B)}\)
假设A是权重和偏差的初始概率分布（称为&lt;strong&gt;先验priors&lt;/strong&gt;，通常是一些标准分布，如正态或均匀随机），而B是训练数据（图像/标签）。贝叶斯定理的关键思想是，我们想使用数据来找出权重和偏差$P(A|B)$的更新分布（&lt;strong&gt;posterior后验&lt;/strong&gt;）。 就像使用网络的初始随机分配的权重和偏差一样，参数（先验）的初始分布将给我们带来错误的结果。只有使用数据获取参数的更新分布（近似于后验）后，我们才能使用网络对图像进行分类。&lt;/p&gt;

&lt;p&gt;权重和偏差的概率分布通过贝叶斯定理进行更新。变分贝叶斯方法的要点在于，由于我们无法精确地计算后验，因此我们可以找到与其最接近的“行为良好（well-behaved）”的概率分布。 “行为良好”是指可以由一小部分参数（如均值或方差）表示的分布（如正态分布或指数分布）。因此，在“行为良好”的分布中随机初始化这些参数之后可以通过相应的损失函数逐渐梯度下降，更新分布的参数（例如均值或方差），以使得结果分布尽可能更接近要计算的后验，接近度的度量称为&lt;a href=&quot;http://legacydirs.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf&quot;&gt;Evidence Lower Bound（ELBO)&lt;/a&gt;。&lt;/p&gt;

&lt;h3 id=&quot;22-monte-carlo-dropout&quot;&gt;2.2 Monte Carlo Dropout&lt;/h3&gt;

&lt;p&gt;论文链接：&lt;/p&gt;

&lt;p&gt;[1]Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning：https://arxiv.org/pdf/1506.02142.pdf&lt;/p&gt;

&lt;p&gt;[2]Bayesian SegNet: Model Uncertainty in Deep Convolutional Encoder-Decoder Architectures for Scene Understanding:https://arxiv.org/pdf/1511.02680.pdf&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvsf9dmm6j30oz06j41u.jpg&quot; alt=&quot;图3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这篇paper的模型使用dropout作为上面讲到的&lt;a href=&quot;https://towardsdatascience.com/making-your-neural-network-say-i-dont-know-bayesian-nns-using-pyro-and-pytorch-b1c24e6ab8cd&quot;&gt;BNN&lt;/a&gt;中的近似推断方法，因此也使用dropout作为从模型的后验分布中获取样本的方法。 论文[1]将这项技术与贝叶斯卷积神经网络中具有权重分布的伯努利分布的变异推理联系起来。 我们利用这种方法对我们的细分模型执行概率推断，从而产生了Bayesian SegNet。&lt;/p&gt;

&lt;p&gt;通常，精确的后验分布是很难得到的，因此我们需要近似估计这些权重的分布。训练模型的时候使用dropout，并在测试时间使用dropout&lt;strong&gt;采样权重的后验分布&lt;/strong&gt;，以获得softmax类概率的后验分布。 &lt;strong&gt;将这些样本的均值用于细分预测，并使用方差输出每个类别的模型不确定性&lt;/strong&gt;。图4显示了分段预测和模型不确定性估计过程的示意图&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvsfa1punj30zh06vgqk.jpg&quot; alt=&quot;图4&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;23-deep-ensemble&quot;&gt;2.3 Deep Ensemble&lt;/h3&gt;

&lt;p&gt;[3]Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles:https://arxiv.org/pdf/1612.01474.pdf&lt;/p&gt;

&lt;p&gt;与BNN相比（变分推理或MCMC方法），简化了方法的实现，只需要对标准神经网络稍加修改，并且适合于分布式计算，适合部署在大规模深度学习应用中。&lt;/p&gt;

&lt;p&gt;方法相当于将ensemble（把多个模型的预测结果取平均值来获得“model uncertainty”）和对抗训练（提高局部平滑度）结合。只需要很少的超参数调整，并且可以很容易地用于各种架构，例如MLP，CNN等，包括那些不使用Dropout的架构。&lt;/p&gt;

&lt;h2 id=&quot;3医疗影像分割中的应用&quot;&gt;3.医疗影像分割中的应用&lt;/h2&gt;

&lt;h3 id=&quot;31-probabilistic-u-net&quot;&gt;3.1 Probabilistic U-Net&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/abs/1806.05034&lt;/p&gt;

&lt;p&gt;这篇文章是发表在NIPS2017的工作。定义N为标准正态分布，φ, θ是由神经网络参数化的函数。我们可以用prior net和posterior net来建模，两个网络使用相同的结构但不共享权重。下图为&lt;strong&gt;prob-U-Net的架构&lt;/strong&gt;，训练阶段使用图b的网络结构，将图像和ground truth叠加在一起输入到posterior net中，相当于一个encoder将输入编码到正态分布的&lt;strong&gt;隐空间&lt;/strong&gt;，将训练样本输入到prior net中编码到另一个正态分布的隐空间，计算两个分布的KL散度作为损失函数的一部分。由于posterior net的输入有标签信息，所以称其编码后的分布为&lt;strong&gt;后验分布&lt;/strong&gt;，prior net仅有原始图像输入，因此得到的分布为先验分布。通过KL散度训练网络将先验分布和后验分布尽可能相近想要达到的效果是，在使用如下图a网络结构测试和验证时，仅输入图像也能让网络得到近似于“后验”的分布，这个分布的作用是为了进行连续采样，每个采样值再经过上采样插值到作为解码器的U-NET的最后一层特征层中，从而得到不同的预测结果。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gctbp31g1zj30o209uabg.jpg&quot; alt=&quot;图5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这篇文章中使用的数据集为LIDC-IDRI，每个输入数据有4个标注者。&lt;/p&gt;

&lt;h3 id=&quot;32-phiseg&quot;&gt;3.2 PHiSeg&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/abs/1906.04045&lt;/p&gt;

&lt;p&gt;这是一篇发表在MICCAI2019的工作，它解决了prob U-Net在只有一个标注者的时候，生成的多个预测之间差异度不够的问题（如图6第四行）。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcthrqnhm0j30kx0hh76t.jpg&quot; alt=&quot;图6&quot; /&gt;&lt;/p&gt;

&lt;p&gt;作者提出了一种新颖的分层概率模型，该模型可以产生与多个与注释结果的分布紧密匹配的分割样本。 受拉普拉斯金字塔启发，该模型以低分辨率生成输出，然后以越来越高的分辨率不断细化segmentations的分布，来生成image-conditional的分割样本。与先前的工作相比，每个分辨率级别的变化都由单独的隐变量（latent code）控制，从而避免了prob-UNET的问题。&lt;/p&gt;

&lt;p&gt;如图7所示，作者假设给定输入图像x的分割s是根据Fig. 1所示的图形模型从L个尺度的隐变量 &lt;img src=&quot;https://www.zhihu.com/equation?tex=z_l&quot; alt=&quot;[公式]&quot; /&gt; 生成的&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gctobqelfjj30ku044myg.jpg&quot; alt=&quot;图7&quot; /&gt;&lt;/p&gt;

&lt;p&gt;PHiSeg的模型结构如图8所示，和prob U-Net网络结构上的主要区别在于posterior network和prior network的结构换成了U型结构，从而能够生成多尺度的特征层的隐变量，在likelihood network中将这些多尺度信息结合。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gctokks07rj30nl0kr77f.jpg&quot; alt=&quot;图8&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;33-addressing-failure-prediction-by-learning-model-confidence&quot;&gt;3.3 Addressing Failure Prediction by Learning Model Confidence&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/pdf/1910.04851.pdf&lt;/p&gt;

&lt;p&gt;这篇文章是从度量的角度，为深度神经网络模型的预测提供更可靠的置信度度量，配备了这种置信度度量，系统可以决定遵守该预测，或者相反，例如将其移交给人或备用系统或其他传感器，或只是触发警报。&lt;/p&gt;

&lt;p&gt;在分类的背景下，使用神经网络进行置信度估计的一种广泛使用的baseline是采用预测类别的概率值，即softmax层输出给出的最大类别概率（Maximum Class Probability MCP）。但使用MCP作为度量仍然有几个理论缺陷，比如softmax概率是未经校准的，对对抗攻击敏感，并且很难检测离群样本点。&lt;/p&gt;

&lt;p&gt;这项工作中专门解决的另一个重要问题与MCP有关的置信度分数的排名问题： 如图9a所示，对于在CIFAR-10数据集上训练的小型卷积网络，错误预测和正确预测的MCP置信度值重叠。这个问题来自以下原因：由于使用了最大softmax输出，因此MCP在设计上会导致较高的置信度值，即使对于错误的置信度也是如此。 另一方面，如图9b所示，模型相对于真实类别的概率得到了一个较合理的模型置信度。 错误类的置信度分布转移到较小的值，而正确的预测仍与高值相关联，从而使这两种类型的预测之间具有更好的可分离性。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvkyflg8kj30lz08qmy2.jpg&quot; alt=&quot;图9&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;基于此观察，作者提出了一种使用深度神经网络进行故障预测的新方法。 首先基于使用TCP的思想引入了新的置信度标准，为故障预测的背景提供了理论保证。 由于真实类在测试时显然是未知的，因此我们引入了一种从数据中学习给定目标置信度标准的方法如图10所示：假设需要学习的TCP置信度值为$c^&lt;em&gt;(x,y&lt;/em&gt;)=P(Y=y^*&lt;/td&gt;
      &lt;td&gt;w,x)$，提出了一个置信度神经网络ConfidNet，网络参数为$\theta$，网络输出为$\hat{c}(x,\theta)$。训练时需要找到一个接近于$c^&lt;em&gt;(x,y^&lt;/em&gt;)$的$\hat{c}(x,\theta)$。&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvr7w9orkj30mb0be41j.jpg&quot; alt=&quot;图10&quot; /&gt;&lt;/p&gt;

&lt;p&gt;作者在分类和分割数据集上都测试了提出的方法，实验表明，从MCP到贝叶斯不确定性，以及专为故障预测而专门设计的最新方法，作者的方法始终优于前者。并提供了开源代码（https://github.com/google/TrustScore）&lt;/p&gt;

&lt;h3 id=&quot;34-supervised-uncertainty-quantification-for-segmentation-with-multiple-annotations&quot;&gt;3.4 Supervised Uncertainty Quantification for Segmentation with Multiple Annotations&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/pdf/1907.01949.pdf&lt;/p&gt;

&lt;p&gt;这篇工作发表在MICCAI2019上，主要是对prob U-Net进行了两点改进：首先是prob U-Net中不包含衡量认知不确定性的机制，这可以通过在U-Net的最后一个卷积层之后添加变分dropout来实现。其次，假设训练集有N个图片${x_i}^N_{i=1}$，如果第$i$个图像有D个分割标注者${y^1&lt;em&gt;i,…,y^D_i}$，定义这些像素点的分割标记的偶然不确定性为$V&lt;/em&gt;{p(D)}[y_i]=\frac{1}{D}\sum ^D_{j=1}(y^j_i-\bar{y}&lt;em&gt;i)^2$，其中$\bar{y}_i=\frac{1}{D}\sum ^D&lt;/em&gt;{j=1}y^j_i$，标注之间的交叉熵$V_{p(D)}$可以作为校准偶然不确定性的目标。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcvyn4sdjej30ju0c7dk3.jpg&quot; alt=&quot;图11&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在LIDC-IDRI肺结节CT数据集和MICCAI2012前列腺MRI数据集上训练并测试模型，证明模型可以改善预测不确定性估计。 还发现，我们可以提高样本准确性和样本多样性。作者提供了开源代码（https://github.com/stefanknegt/Probabilistic-Unet-Pytorch）&lt;/p&gt;

&lt;h3 id=&quot;35-assessing-reliability-and-challenges-of-uncertainty-estimations-for-medical-image-segmentation&quot;&gt;3.5 Assessing Reliability and Challenges of Uncertainty Estimations for Medical Image Segmentation&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/pdf/1907.03338.pdf&lt;/p&gt;

&lt;p&gt;这篇工作发表在MICCAI2019上。作者将几种uncertainty主流方法（Baseline uncertainty: Softmax entropy；MC dropout；Aleatoric uncertainty；Ensembles；Auxiliary network.）应用到BraTS2018数据集上评估了它们的Dice和uncertainty的质量。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcw0pribraj30lq080dic.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Aleatoric方法和large dropout的方法性能最差。 aleatoric方法无法在分割错误的位置（即较低的U-E）产生不确定性，因此无法通过校正来改善分割结果，而MC dropout主要对分割性能和ECE产生负面影响。结果进一步表明，与非MC版本（baseline和中心）相比，MC dropout通常可以提高ECE，UE和Dice系数，但dropout概率设置较大会导致较差的性能，基于MC dropout的方法在很大程度上取决于dropout对分割性能的影响。&lt;/p&gt;

&lt;p&gt;ensemble方法会按顺序生成最可靠的结果，并且通常是一个不错的选择（如果资源允许的话）。&lt;/p&gt;

&lt;p&gt;作者还观察到辅助网络的良好性能，这些网络通常经过了良好的校准，并受益于其细分网络（即baseline模型）的良好细分性能。&lt;/p&gt;

&lt;p&gt;关于指标，作者注意到低ECE值源于对ECE产生积极影响的大量低置信度背景区域。这也解释了BraTS数据集的较低ECE值，由于附加的图像尺寸，该数据集包含比ISIC数据集更多的背景。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcw0qa6cwjj30lu09c771.jpg&quot; alt=&quot;图12&quot; /&gt;&lt;/p&gt;

&lt;p&gt;上图结果表明，尽管当前在体素方面的不确定性度量在数据集级别（即D列数据集中的所有体素）都得到了很好的校准，但它们在样本级别（S1，S2，S3列）上往往会失败。 原因是样本级别的校准误差（校准不足或过度校准）可以在数据集级别平均。基于所提出的基于校准的度量，在本文所研究的方法中没有找到最佳方法。 作者认为，通过评估总体素不确定性表现以提供样本水平估计的方法不够可靠，无法用作检测失败分割的机制。 因此，在医学图像分割中开发样本级别的不确定性估计很重要，可以解决High-Dimension-Low-Sample-Size（HDLSS）问题，以确保其在实践中的可靠性。&lt;/p&gt;

&lt;h3 id=&quot;36-exploiting-epistemic-uncertainty-of-anatomy-segmentation-for-anomaly-detection-in-retinal-oct&quot;&gt;3.6 Exploiting Epistemic Uncertainty of Anatomy Segmentation for Anomaly Detection in Retinal OCT&lt;/h3&gt;

&lt;p&gt;https://arxiv.org/pdf/1905.12806.pdf&lt;/p&gt;

&lt;p&gt;该工作发表在TMI上。这篇论文虽然没有针对不确定性方法作出优化，但其对不确定性方法的应用思路值得参考。论文提出的方案基于以下假设：认知不确定性与未知的解剖变异性（异常）存在相关性。因此在这项任务中应用认知不确定性估计来检测和分割视网膜OCT图像中的异常是合理的。如图12所示，异常面积和不确定性之间的高度相关性（ρ= 0.91）支持了这种说法。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcw594by1pj30k20a2jt4.jpg&quot; alt=&quot;图13&quot; /&gt;&lt;/p&gt;

&lt;p&gt;方法上这篇论文使用的是MC dropout，以检索像素级认知不确定性估计。 最后，作者引入了一个简单的后处理步骤，即多数射线投射majority-ray-casting，将不确定度图转换为紧凑的异常分段。 该技术基于OCT中的异常紧凑且未分层的假设，从而弥合了层和异常形状之间的间隙。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tva1.sinaimg.cn/large/00831rSTly1gcw59o28lpj30ae0650t5.jpg&quot; alt=&quot;图14&quot; /&gt;&lt;/p&gt;

</description>
        <pubDate>Sun, 22 Mar 2020 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2020/03/22/%E5%8C%BB%E7%96%97%E5%88%86%E5%89%B2uncertainty%E7%BB%BC%E8%BF%B0/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2020/03/22/%E5%8C%BB%E7%96%97%E5%88%86%E5%89%B2uncertainty%E7%BB%BC%E8%BF%B0/</guid>
        
        <category>论文阅读</category>
        
        
      </item>
    
      <item>
        <title>目标检测算法综述</title>
        <description>&lt;h1 id=&quot;目标检测算法综述&quot;&gt;目标检测算法综述&lt;/h1&gt;

&lt;h2 id=&quot;概述-overview&quot;&gt;概述 Overview&lt;/h2&gt;

&lt;p&gt;在深度学习正式介入之前，传统的「目标检测」方法都是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;区域选择&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;提取特征（颜色，纹理等）&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;分类回归&lt;/code&gt; 三部曲，这样就有两个难以解决的问题；其一是区域选择的策略效果差、时间复杂度高；其二是手工提取的特征鲁棒性较差。&lt;/p&gt;

&lt;p&gt;云计算时代来临后，「目标检测」算法大家族主要划分为两大派系，一个是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-CNN&lt;/code&gt; 系两刀流，另一个则是以 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YOLO&lt;/code&gt; 为代表的一刀流派。下面分别解释一下 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;两刀流&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一刀流&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;两刀流&lt;/strong&gt;
顾名思义，两刀解决问题：&lt;/p&gt;

&lt;p&gt;1、生成可能区域（Region Proposal） &amp;amp; CNN 提取特征
2、放入分类器分类并修正位置&lt;/p&gt;

&lt;p&gt;这一流派的算法都离不开 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Region Proposal&lt;/code&gt; ，即是优点也是缺点，主要代表人物就是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-CNN&lt;/code&gt; 系。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一刀流&lt;/strong&gt;
顾名思义，一刀解决问题，直接对&lt;strong&gt;预测的目标物体进行回归&lt;/strong&gt;。
回归解决问题简单快速，但是太粗暴了，主要代表人物是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YOLO&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSD&lt;/code&gt; 。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;无论 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;两刀流&lt;/code&gt; 还是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一刀流&lt;/code&gt;，他们都是在同一个天平下选取一个平衡点、或者选取一个极端——要么准，要么快。&lt;/p&gt;

&lt;p&gt;两刀流的天平&lt;strong&gt;主要倾向&lt;/strong&gt;准，
一刀流的天平&lt;strong&gt;主要倾向&lt;/strong&gt;快。&lt;/p&gt;

&lt;p&gt;但最后万剑归宗，大家也找到了自己的平衡，平衡点的有略微的不同。&lt;/p&gt;

&lt;p&gt;接下来我们花开两朵各表一支，一朵 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;两刀流&lt;/code&gt; 的前世今生，另一朵 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一刀流&lt;/code&gt; 的发展历史。&lt;/p&gt;

&lt;h2 id=&quot;一两刀流-r-cnn&quot;&gt;一、两刀流 R-CNN&lt;/h2&gt;

&lt;p&gt;R-CNN 其实是一个很大的家族，自从 rbg 大神发表那篇论文，子孙无数、桃李满天下。在此，我们只探讨 R-CNN 直系亲属，他们的发展顺序如下：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R-CNN -&amp;gt; SPP Net -&amp;gt; Fast R-CNN -&amp;gt; Faster R-CNN -&amp;gt; Mask R-CNN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;其实说句良心话，最佩服的并不是 rbg 大神，而是&lt;strong&gt;提出了 SPP Net 的以何恺明为主的作者们&lt;/strong&gt;。
他们在整个家族进化的过程中，一致暗埋了一条主线：&lt;strong&gt;充分榨干 feature maps 的价值&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;11-r-cnn--2013&quot;&gt;1.1 R-CNN / 2013&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1311.2524&quot;&gt;Rich feature hierarchies for accurate object detection and semantic segmentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这篇论文，这个模型，是利用卷积神经网络来做「目标检测」的&lt;strong&gt;开山之作&lt;/strong&gt;，其意义深远不言而喻。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/rcnn.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-2a85903123004110.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;R-CNN&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;111核心贡献&quot;&gt;1.1.1核心贡献&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;一、速度&lt;/strong&gt;
传统的区域选择使用滑窗，每滑一个窗口检测一次，相邻窗口信息重叠高，检测速度慢。R-CNN 使用一个启发式方法（Selective search），&lt;strong&gt;先生成候选区域（使用选择性搜索）再检测，降低信息冗余程度&lt;/strong&gt;，从而提高检测速度。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;二、特征提取&lt;/strong&gt;
传统的手工提取特征鲁棒性差，限于如颜色、纹理等 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;低层次&lt;/code&gt;（Low level）的特征。使用 CNN （卷积神经网络）提取特征，可以提取更高层面的抽象特征，从而提高特征的鲁棒性。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;选择性搜索主要思想&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://www.koen.me/research/pub/uijlings-ijcv2013-draft.pdf&quot;&gt;Selective Search for Object Recognition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;组成目标物体通常有四个要素：变化尺度、颜色、结构（材质）、所占面积。选择性搜索会确定物体在图片中的这些特征，然后基于这些特征突出不同区域。下面是选择搜索的一个简单案例：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;首先将一张图片作为输入：&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-2aeaf966971663fb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;之后，它会生成最初的sub-分割，将图片分成多个区域：&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-83c7214a99d38895.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;查看现有小区域，按照&lt;strong&gt;合并规则&lt;/strong&gt;合并可能性最高的相邻两个区域，重复这种操作：&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-c2851b8ce80f6a6e.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;最后，生成最终的目标物体位置（Region of Interest）。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-1bb5e45aa7fe230c.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;112-基本流程&quot;&gt;1.1.2 基本流程&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;我们首先取一个预训练卷积神经网络CNN。&lt;/li&gt;
  &lt;li&gt;根据需要检测的目标类别数量，训练CNN的最后一层。&lt;/li&gt;
  &lt;li&gt;将以下图片作为输入：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-9c4c5067fbb9d365.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;之后，我们会用上文中的选择性搜索得到感兴趣区域（大约1k~2k个）：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-e88c8fa7c4043b70.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;对这些区域重新改造，以&lt;strong&gt;让其符合CNN的输入尺寸要求&lt;/strong&gt;，将这些区域输入到CNN中，并经过卷积网络：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-3b81e45d18489d6d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;对每个类别，我们都要训练一个二元SVM（判断物体是foreground or background，我们检测的目标是foreground）。CNN为每个区域提取特征，利用SVM将这些区域分成不同类别：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-cccf337d938975f3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;2703090986-5bc5a1ba17ab7.png&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;最后，我们训练一个线性回归模型（bounding box regression），为每个辨识到的物体生成更精确的边界框。：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-c7d0abddb8920529.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bounding box regression原理&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如图9所示绿色框为飞机的Ground Truth(GT)，红色为提取的foreground anchors，即便红色的框被分类器识别为飞机，但是由于红色的框定位不准，这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调，使得foreground anchors和GT更加接近。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-d4a80b9e2a160419.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;对于窗口一般使用四维向量 [x,y,w,h] 表示，分别表示窗口的中心点坐标和宽高。对于下图，红色的框A代表原始的Foreground Anchors，绿色的框G代表目标的GT，我们的目标是寻找一种关系，使得输入原始的anchor A经过映射得到一个跟真实窗口G更接近的回归窗口G’，即：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;给定：anchor$A = (A_x,A_y,A_w,A_h)$ 和\(GT = [G_x,G_y,G_w,G_h]\)&lt;/li&gt;
  &lt;li&gt;寻找一种变换&lt;strong&gt;F&lt;/strong&gt;，使得：$F(A_x,A_y,A_w,A_h)=(G’_x,G’_y,G’_w,G’_h)$，其中$(G’_x,G’_y,G’_w,G’_h)\approx (G_x,G_y,G_w,G_h)$&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-c126455bab332c86.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;那么经过何种变换&lt;strong&gt;F&lt;/strong&gt;才能从图中的anchor A变为G’呢？ 比较简单的思路就是:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;先做平移
\(G&apos;_x = A_w*d_x(A)+A_x\)&lt;/p&gt;

\[G&apos;_y = A_h*d_y(A)+A_y\]
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;再做缩放
\(G&apos;_w = A_w*exp(d_w(A))\)&lt;/p&gt;

\[G&apos;_h = A_h*exp(d_h(A))\]
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;观察上面4个公式发现，需要学习的是 $d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A)$这四个变换。当输入的anchor A与GT相差较小时，可以认为这种变换是一种线性变换， 那么就可以用线性回归来建模对窗口进行微调（注意，只有当anchors A和GT比较接近时，才能使用线性回归模型，否则就是复杂的非线性问题了）。
接下来的问题就是如何通过线性回归获得 $d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A)$ 了。线性回归就是给定输入的特征向量X, 学习一组参数W, 使得经过线性回归后的值跟真实值Y非常接近，即$Y=WX$。对于该问题，输入X是cnn feature map，定义为Φ；同时还有训练传入A与GT之间的变换量，即$(t_{x}, t_{y}, t_{w}, t_{h})$。输出是$d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A)$四个变换。那么目标函数可以表示为：
\(d_*(A)=W_*^T\cdot \phi(A)\)&lt;/p&gt;

&lt;p&gt;其中 $\phi(A)$ 是对应anchor的feature map组成的特征向量， $W_&lt;em&gt;$ 是需要学习的参数， $d_&lt;/em&gt;(A)$是得到的预测值（&lt;em&gt;表示 x，y，w，h，也就是每一个变换对应一个上述目标函数）。为了让预测值$d_&lt;/em&gt;(A)$与真实值$t_*$ 差距最小，设计损失函数：&lt;/p&gt;

\[\text{Loss}=\sum_{i}^{N}{(t_*^i-W_*^T\cdot \phi(A^i))^2}\]

&lt;p&gt;函数优化目标为：&lt;/p&gt;

\[\hat{W}_*=\text{argmin}_{W_*}\sum_{i}^{n}(t_*^i- W_*^T\cdot \phi(A^i))^2+\lambda||W_*||^2\\]

&lt;p&gt;需要说明，只有在GT与需要回归框位置比较接近时，才可近似认为上述线性变换成立。
说完原理，对应于Faster RCNN原文，foreground anchor与ground truth之间的平移量 $(t_x, t_y)$与尺度因子 $(t_w, t_h)$如下：&lt;/p&gt;

\[t_x=(x-x_a)/w_a\ \ \ \  t_y=(x-y_a)/h_a\]

\[t_w=\log(w/w_a)\ \ \ \ t_h=\log(h/h_a)\]

&lt;p&gt;对于训练bouding box regression网络回归分支，输入是cnn feature Φ，监督信号是Anchor与GT的差距 $(t_x, t_y, t_w, t_h)$，即训练目标是：输入 Φ的情况下使网络输出与监督信号尽可能接近。
那么当bouding box regression工作时，再输入Φ时，回归网络分支的输出就是每个Anchor的平移量和变换尺度 $(t_x, t_y, t_w, t_h)$，显然即可用来修正Anchor位置了。&lt;/p&gt;

&lt;p&gt;这就是RCNN检测目标物体的方法。&lt;/p&gt;

&lt;h4 id=&quot;113局限&quot;&gt;1.1.3局限&lt;/h4&gt;

&lt;p&gt;训练一个RCNN模型非常昂贵，并且步骤较多：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;根据选择性搜索，要对每张图片提取2000个单独区域；&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;用CNN提取每个区域的特征。假设我们有N张图片，那么CNN特征就是N*2000；&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;用RCNN进行目标检测的整个过程有三个模型：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;用于特征提取的CNN&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;用于目标物体辨别的线性SVM分类器&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;调整边界框的回归模型。&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些过程合并在一起，会让RCNN的速度变慢，通常每个新图片需要&lt;strong&gt;40—50秒&lt;/strong&gt;的时间进行预测，基本上无法处理大型数据集。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-b5a4e0637c10a232.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;从结果上说，该方法将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PASCAL VOC&lt;/code&gt; 上的检测率从 35.1% 提升到 53.7% ，提高了好几个量级。虽然比传统方法好很多，但是从现在的眼光看，只能是&lt;strong&gt;初窥门径&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;12-spp-net--2014&quot;&gt;1.2 SPP Net / 2014&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1406.4729&quot;&gt;Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-CNN&lt;/code&gt; 提出后的一年，以何恺明、任少卿为首的团队提出了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPP Net&lt;/code&gt; ，这才是真正摸到了卷积神经网络的脉络。也不奇怪，毕竟这些人鼓捣出了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResNet&lt;/code&gt; 残差网络，对神经网络的理解是其他人没法比的。&lt;/p&gt;

&lt;h4 id=&quot;121-核心贡献&quot;&gt;1.2.1 核心贡献&lt;/h4&gt;

&lt;p&gt;解决了R-CNN的两个硬伤：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;算力冗余
先生成候选区域，再对区域进行卷积，这里有两个问题：其一是候选区域会有一定程度的重叠，对相同区域进行重复卷积；其二是每个区域进行新的卷积需要新的存储空间。&lt;/p&gt;

    &lt;p&gt;何恺明等人意识到这个可以优化，于是把&lt;strong&gt;先生成候选区域再卷积&lt;/strong&gt;，变成了&lt;strong&gt;先卷积后生成区域&lt;/strong&gt;。“简单地”改变顺序，不仅减少存储量而且加快了训练速度。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;图片缩放&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-1e9e491c6a5675cd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在R-CNN基本流程步骤5中，对搜索出的感兴趣区域重新改造，以&lt;strong&gt;让其符合CNN的输入尺寸要求&lt;/strong&gt;时，无论是剪裁（Crop）还是缩放（Warp），在很大程度上会丢失图片原有的信息导致训练效果不好，如上图所示。直观的理解，把车剪裁成一个门，人看到这个门也不好判断整体是一辆车；把一座高塔缩放成一个胖胖的塔，人看到也没很大把握直接下结论。人都做不到，机器的难度就可想而知了。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/sppnet_pool_layer.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-5f9d1902e1054113.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;Pool Layer - SPP Net&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROI池化层&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;何恺明等人发现了这个问题，于是思索有什么办法能不对图片进行变形，将图片原汁原味地输入进去学习。&lt;/p&gt;

&lt;p&gt;最后，他们发现问题的根源是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FC Layer&lt;/code&gt;（全连接层）需要确定输入维度，于是他们在输入全连接层前定义一个特殊的池化层，将输入的任意尺度 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature maps&lt;/code&gt; 组合成特定维度的输出，这个组合可以是不同大小的拼凑，如同拼凑七巧板般。这就是ROI池化层。&lt;/p&gt;

&lt;p&gt;具体来说，&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;先将对应的feature map区域水平分为$pooled_w ×pooled_h$  的网格；&lt;/li&gt;
  &lt;li&gt;对网格的每一份都进行max pooling处理。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这样处理后，即使大小不同的proposal输出结果都是 $pooled_w ×pooled_h$ 固定大小，实现了固定长度输出。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-888fca4b0768b3a1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPP Net&lt;/code&gt; 的出现是如同一道惊雷，&lt;strong&gt;不仅减少了计算冗余，更重要的是打破了固定尺寸输入这一束缚&lt;/strong&gt;，让后来者享受到这一缕阳光。&lt;/p&gt;

&lt;h3 id=&quot;13-fast-r-cnn--2015&quot;&gt;1.3 Fast R-CNN / 2015&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1504.08083&quot;&gt;Fast R-CNN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;此时，我们的 rbg 大哥也按耐不住了——自己家的孩子，自己养大——于是憋出了一个大招 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fast R-CNN&lt;/code&gt; 。取这个名字的意思就是“儿子比爸爸强”，相对于原来的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Slow R-CNN&lt;/code&gt;，做了速度上的优化——就是快。&lt;/p&gt;

&lt;p&gt;在这篇论文中，引用了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPP Net&lt;/code&gt; 的工作，并且致谢其第一作者何恺明的慷慨解答。&lt;/p&gt;

&lt;h4 id=&quot;131-核心贡献&quot;&gt;1.3.1 核心贡献&lt;/h4&gt;

&lt;p&gt;想要减少RCNN算法的计算时间，可以用什么方法？我们可不可以在每张图片上只使用一次CNN即可得到全部的重点关注区域呢，而不是运行2000次。&lt;/p&gt;

&lt;p&gt;RCNN的作者提出了一种想法，在每张照片上只运行一次CNN，然后找到一种方法在2000个区域中进行计算。在Fast RCNN中，我们将图片输入到CNN中，会相应地生成传统特征映射。利用这些映射，就能提取出感兴趣区域。之后，我们使用一个Rol池化层将所有提出的区域重新修正到合适的尺寸，以输入到完全连接的网络中。&lt;/p&gt;

&lt;p&gt;简单地说，这一过程含有以下步骤：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;输入图片。&lt;/li&gt;
  &lt;li&gt;输入到卷积网络中，它生成感兴趣区域。&lt;/li&gt;
  &lt;li&gt;利用Rol池化层对这些区域重新调整，将其输入到完全连接网络中。&lt;/li&gt;
  &lt;li&gt;在网络的顶层用softmax层输出类别。同样使用一个线性回归层，输出相对应的边界框。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;所以，和RCNN所需要的三个模型不同，Fast RCNN只用了一个模型就同时实现了区域的特征提取、分类、边界框生成。&lt;/p&gt;

&lt;p&gt;另外，原来的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-CNN&lt;/code&gt; 是先对候选框区域进行分类，判断有没有物体，如果有则对 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bounding Box&lt;/code&gt; 进行精修 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;回归&lt;/code&gt; 。这是一个串联式的任务，那么势必没有并联的快，所以 rbg 就将原有结构改成并行——在分类的同时，对 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bbox&lt;/code&gt; 进行回归。&lt;/p&gt;

&lt;p&gt;这一改变将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bbox&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Clf&lt;/code&gt; 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loss&lt;/code&gt; 结合起来变成一个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Loss&lt;/code&gt; 一起训练，并吸纳了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPP Net&lt;/code&gt; 的优点，最终不仅加快了预测的速度，而且提高了精度。&lt;/p&gt;

&lt;h4 id=&quot;132-基本流程&quot;&gt;1.3.2 基本流程&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;首先，输入图像：&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-ded50fa67626ae3c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;图像被传递到卷积网络中，返回感兴趣区域：
&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-ead4c4c2bb339def.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;之后，在区域上应用Rol池化层，保证每个区域的尺寸相同：&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-69ac47518f8c5c1c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;这些区域被传递到一个完全连接的网络中进行分类，并用softmax和线性回归层同时返回边界框：
&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-2a5553b5d0fc19d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;133-局限&quot;&gt;1.3.3 局限&lt;/h4&gt;

&lt;p&gt;但是即使这样，Fast RCNN也有某些局限性。它同样用的是选择性搜索作为寻找感兴趣区域的，这一过程通常较慢。与RCNN不同的是，Fast RCNN处理一张图片大约需要2秒。但是在大型真实数据集上，这种速度仍然不够理想。&lt;/p&gt;

&lt;h3 id=&quot;14-faster-r-cnn--2015&quot;&gt;1.4 Faster R-CNN / 2015&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1506.01497&quot;&gt;Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;众人拾柴火焰高，原来 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPP Net&lt;/code&gt; 的人马和 rbg 一起研究憋大招，在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rbg&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;何恺明&lt;/code&gt; 绽放完光芒后，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;任少卿&lt;/code&gt; 老哥发出了太阳般的光芒——&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPN&lt;/code&gt; 的概念让人不得不服。&lt;/p&gt;

&lt;h4 id=&quot;141-核心贡献&quot;&gt;1.4.1 核心贡献&lt;/h4&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Faster R-CNN&lt;/code&gt; 前，我们生产候选区域都是用的一系列启发式算法，基于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Low Level&lt;/code&gt; 特征生成区域。这样就有两个问题：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一个问题&lt;/strong&gt; 是生成区域的靠谱程度随缘，而 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;两刀流&lt;/code&gt; 算法正是依靠生成区域的靠谱程度——生成大量无效区域则会造成算力的浪费、少生成区域则会漏检；
&lt;strong&gt;第二个问题&lt;/strong&gt; 是生成候选区域的算法是在 CPU 上运行的，而我们的训练在 GPU 上面，跨结构交互必定会有损效率。&lt;/p&gt;

&lt;p&gt;那么怎么解决这两个问题呢？&lt;/p&gt;

&lt;p&gt;于是乎，任少卿等人提出了一个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Region Proposal Networks&lt;/code&gt; 的概念，利用神经网络自己学习去生成候选区域。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/faster_rcnn.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-5b34433cfcc1ed70.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;Faster R-CNN&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这种生成方法同时解决了上述的两个问题，神经网络可以学到更加高层、语义、抽象的特征，生成的候选区域的可靠程度大大提高；可以从上图看出 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPNs&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoI Pooling&lt;/code&gt; 共用前面的卷积神经网络——将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPNs&lt;/code&gt; 嵌入原有网络，原有网络和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPNs&lt;/code&gt; 一起预测，大大地减少了参数量和预测时间。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/faster_rcnn_anchor.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-980f97e57ba8333d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;Faster R-CNN&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPNs&lt;/code&gt; 中引入了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anchor&lt;/code&gt; 的概念，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature map&lt;/code&gt; 中每个滑窗位置都会生成 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;k&lt;/code&gt; 个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anchors&lt;/code&gt;，然后判断 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anchor&lt;/code&gt;覆盖的图像是&lt;strong&gt;前景&lt;/strong&gt;还是&lt;strong&gt;背景&lt;/strong&gt;，同时回归 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bbox&lt;/code&gt; 的精细位置，预测的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bbox&lt;/code&gt; 更加精确。&lt;/p&gt;

&lt;p&gt;将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;两刀流&lt;/code&gt; 的两刀并入同一个网络，这一操作足够载入史册了。&lt;/p&gt;

&lt;h4 id=&quot;142-基本流程&quot;&gt;1.4.2 基本流程&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-c54baa30d6bc0398.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;Faster RCNN基本结构&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Faster RCNN其实可以分为4个主要内容：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Conv layers&lt;/strong&gt;。作为一种CNN网络目标检测方法，Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Region Proposal Networks&lt;/strong&gt;。RPN网络用于生成region proposals。该层通过softmax判断anchors属于foreground或者background，再利用bounding box regression修正anchors获得精确的proposals。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Roi Pooling&lt;/strong&gt;。该层收集输入的feature maps和proposals，综合这些信息后提取proposal feature maps，送入后续全连接层判定目标类别。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Classification&lt;/strong&gt;。利用proposal feature maps计算proposal的类别，同时再次bounding box regression获得检测框最终的精确位置。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;具体来说可看下图：VGG16模型中的faster_rcnn_test.pt的网络结构&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-ca122c358e291346.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;可以清晰的看到该网络对于一副任意大小PxQ的图像，首先缩放至固定大小MxN，然后将MxN图像送入网络；而Conv layers中包含了13个conv层+13个relu层+4个pooling层；&lt;strong&gt;RPN网络&lt;/strong&gt;首先经过3x3卷积，再分别生成foreground anchors与bounding box regression偏移量，然后计算出proposals；而&lt;strong&gt;Roi Pooling层&lt;/strong&gt;则利用proposals从feature maps中提取proposal feature送入后续全连接和softmax网络作classification（即分类proposal到底是什么object）。&lt;/p&gt;

&lt;h4 id=&quot;conv-layers&quot;&gt;Conv layers&lt;/h4&gt;

&lt;p&gt;Conv layers包含了conv，pooling，relu三种层。如图2，Conv layers部分共有13个conv层，13个relu层，4个pooling层。这里有一个&lt;strong&gt;非常容易被忽略但是又无比重要的信息&lt;/strong&gt;，在Conv layers中：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;所有的conv层都是：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keneral_size = 3,pad = 1,stride = 1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;所有的pooling层都是：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keneral_size = 2,pad = 0 ,stride = 2&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;为何重要？在Faster RCNN Conv layers中对所有的卷积都做了&lt;strong&gt;扩边处理&lt;/strong&gt;（ pad=1，即填充一圈0），导致原图变为 (M+2)x(N+2)大小，再做3x3卷积后输出MxN 。正是这种设置，导致Conv layers中的conv层不改变输入和输出矩阵大小。如图3：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-de1f82e19e961868.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;类似的是，Conv layers中的pooling层kernel_size=2，stride=2。这样每个经过pooling层的MxN矩阵，都会变为(M/2)x(N/2)大小。综上所述，在整个Conv layers中，conv和relu层不改变输入输出大小，只有pooling层使输出长宽都变为输入的1/2。
那么，一个MxN大小的矩阵经过Conv layers固定变为(M/16)x(N/16)！这样Conv layers生成的featuure map中都可以和原图对应起来。&lt;/p&gt;

&lt;h4 id=&quot;region-proposal-networksrpn&quot;&gt;Region Proposal Networks(RPN)&lt;/h4&gt;

&lt;p&gt;经典的检测方法生成检测框都非常耗时，如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框；或如R-CNN使用SS(Selective Search)方法生成检测框。而Faster RCNN则抛弃了传统的滑动窗口和SS方法，直接使用RPN生成检测框，这也是Faster R-CNN的巨大优势，能极大提升检测框的生成速度。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-009912e8a2825723.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;上图4展示了RPN网络的具体结构。可以看到RPN网络实际分为2条线：&lt;/p&gt;

&lt;p&gt;一路用来判断候选框是前景还是背景，它先reshape成一维向量，softmax分类anchors获得foreground和background（检测目标是foreground），然后reshape恢复为二维feature map。故经过这一步之后，我们就可以舍弃背景anchors了。大部分的anchors都是属于背景，故&lt;strong&gt;这一步可以筛选掉很多无用的anchor，从而减少全连接层的计算量&lt;/strong&gt;。对于经过了3x3的卷积后得到的256个feature map，先经过1x1的卷积，变换为18个feature map。然后reshape为一维向量，&lt;strong&gt;经过softmax判断是前景还是背景&lt;/strong&gt;。此处reshape的唯一作用就是让数据可以进行softmax计算。然后输出识别得到的前景anchors。&lt;/p&gt;

&lt;p&gt;下面一路用于计算对于anchors的bounding box regression偏移量，以获得精确的proposal（也就是确定候选框的位置）。&lt;/p&gt;

&lt;p&gt;而最后的Proposal层则负责综合foreground anchors和bounding box regression偏移量获取proposals，同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里，就完成了相当于目标定位的功能。&lt;/p&gt;

&lt;h5 id=&quot;关于1x1卷积&quot;&gt;关于1x1卷积&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-8bfdc4d6a818c904.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如上图，输入有3个通道，同时有2个卷积核。对于每个卷积核，先在输入3个通道分别作卷积，再将3个通道结果加起来得到卷积输出。所以对于某个卷积层，无论输入图像有多少个通道，&lt;strong&gt;输出图像通道数总是等于卷积核数量&lt;/strong&gt;！
对多通道图像做1x1卷积，其实就是将输入图像于每个通道乘以卷积系数后加在一起，即相当于把原图像中本来各个独立的通道“联通”在了一起。&lt;/p&gt;

&lt;h5 id=&quot;候选框anchors&quot;&gt;候选框（anchors）：&lt;/h5&gt;

&lt;p&gt;所谓anchors，实际上就是一组由rpn/generate_anchors.py生成的矩形。直接运行作者demo中的generate_anchors.py可以得到以下输出：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[[ -84.  -40.   99.   55.]
 [-176.  -88.  191.  103.]
 [-360. -184.  375.  199.]
 [ -56.  -56.   71.   71.]
 [-120. -120.  135.  135.]
 [-248. -248.  263.  263.]
 [ -36.  -80.   51.   95.]
 [ -80. -168.   95.  183.]
 [-168. -344.  183.  359.]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;其中每行的4个值$(x_1, y_1, x_2, y_2)$代表矩形左上和右下角点坐标。9个矩形共有3种形状，长宽比为大约为$width:height \in { 1:1,1:2,2:1 }$  三种，如下图。实际上通过anchors就引入了检测中常用到的多尺度方法。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-92e34e254580fa60.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;那么这9个anchors是做什么的呢？借用Faster RCNN论文中的原图，如图7，遍历Conv layers计算获得的feature maps，为每一个点都配备这9种anchors作为初始的检测框。这样做获得检测框很不准确，不用担心，后面还有2次bounding box regression可以修正检测框位置。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-d819a33496a1f9d2.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;假设在conv5 feature map中每个点上有k个anchor（默认k=9），而每个anhcor要分foreground和background，所以每个点由256d feature转化为cls=2k scores；而每个anchor都有(x, y, w, h)对应4个偏移量，所以reg=4k coordinates。&lt;/p&gt;

&lt;p&gt;补充一点，全部anchors拿去训练太多了，训练程序会在合适的anchors中&lt;strong&gt;随机&lt;/strong&gt;选取128个postive anchors+128个negative anchors进行训练。&lt;/p&gt;

&lt;h5 id=&quot;softmax判定foreground与background&quot;&gt;softmax判定foreground与background&lt;/h5&gt;

&lt;p&gt;一副MxN大小的矩阵送入Faster RCNN网络后，到RPN网络变为(M/16)x(N/16)，不妨设 W=M/16，H=N/16。在进入reshape与softmax之前，先做了1x1卷积，如图9：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-8e67942b0d05fb26.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;图9 RPN中判定fg/bg网络结构&lt;/p&gt;

&lt;p&gt;该1x1卷积的caffe prototxt定义如下：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;layer {
  name: &quot;rpn_cls_score&quot;
  type: &quot;Convolution&quot;
  bottom: &quot;rpn/output&quot;
  top: &quot;rpn_cls_score&quot;
  convolution_param {
    num_output: 18   # 2(bg/fg) * 9(anchors)
    kernel_size: 1 pad: 0 stride: 1
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看到其num_output=18，也就是经过该卷积的输出图像为WxHx18大小。这也就刚好对应了feature maps每一个点都有9个anchors，同时每个anchors又有可能是foreground和background，所有这些信息都保存WxHx(9*2)大小的矩阵。为何这样做？后面接softmax分类获得foreground anchors，也就相当于初步提取了检测目标候选区域box（一般认为目标在foreground anchors中）。
那么为何要在softmax前后都接一个reshape layer？其实只是为了便于softmax分类，至于具体原因这就要从caffe的实现形式说起了。在caffe基本数据结构blob中以如下形式保存数据：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;blob=[batch_size, channel，height，width]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;对应至上面的保存bg/fg anchors的矩阵，其在caffe blob中的存储形式为[1, 2x9, H, W]。而在softmax分类时需要进行fg/bg二分类，所以reshape layer会将其变为[1, 2, 9xH, W]大小，即单独“腾空”出来一个维度以便softmax分类，之后再reshape回复原状。贴一段caffe softmax_loss_layer.cpp的reshape函数的解释，非常精辟：&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;Number of labels must match number of predictions; &quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;e.g., if softmax axis == 1 and prediction shape is (N, C, H, W), &quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;label count (number of labels) must be N*H*W, &quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;with integer values in {0, 1, ..., C-1}.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;综上所述，RPN网络中利用anchors和softmax初步提取出foreground anchors作为候选区域。&lt;/p&gt;

&lt;h5 id=&quot;对proposals进行bounding-box-regression&quot;&gt;对proposals进行bounding box regression&lt;/h5&gt;

&lt;p&gt;在了解bounding box regression后，再回头来看RPN网络第二条线路，如图。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-f8ee26093ae0cc79.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;先来看一看上图11中1x1卷积的caffe prototxt定义：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;layer {
  name: &quot;rpn_bbox_pred&quot;
  type: &quot;Convolution&quot;
  bottom: &quot;rpn/output&quot;
  top: &quot;rpn_bbox_pred&quot;
  convolution_param {
    num_output: 36   # 4 * 9(anchors)
    kernel_size: 1 pad: 0 stride: 1
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看到其 num_output=36，即经过该卷积输出图像为WxHx36，在caffe blob存储为[1, 4x9, H, W]，这里相当于feature maps每个点都有9个anchors，每个anchors又都有4个用于回归的$[d_x(A),d_y(A).d_w(A),d_h(A)]$变换量。&lt;/p&gt;

&lt;h5 id=&quot;proposal-layer&quot;&gt;Proposal Layer&lt;/h5&gt;

&lt;p&gt;Proposal Layer负责综合所有$[d_x(A),d_y(A).d_w(A),d_h(A)]$变换量和foreground anchors，计算出精准的proposal，送入后续RoI Pooling Layer。还是先来看看Proposal Layer的caffe prototxt定义：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;layer {
  name: &apos;proposal&apos;
  type: &apos;Python&apos;
  bottom: &apos;rpn_cls_prob_reshape&apos;
  bottom: &apos;rpn_bbox_pred&apos;
  bottom: &apos;im_info&apos;
  top: &apos;rois&apos;
  python_param {
    module: &apos;rpn.proposal_layer&apos;
    layer: &apos;ProposalLayer&apos;
    param_str: &quot;&apos;feat_stride&apos;: 16&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Proposal Layer有3个输入：fg/bg anchors分类器结果rpn_cls_prob_reshape，对应的bbox reg的$[d_x(A),d_y(A).d_w(A),d_h(A)]$变换量rpn_bbox_pred，以及im_info；另外还有参数feat_stride=16，这和图4是对应的。
首先解释im_info。对于一副任意大小PxQ图像，传入Faster RCNN前首先reshape到固定MxN，im_info=[M, N, scale_factor]则保存了此次缩放的所有信息。然后经过Conv Layers，经过4次pooling变为WxH=(M/16)x(N/16)大小，其中feature_stride=16则保存了该信息，用于计算anchor偏移量。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-cd0d2f741514dd8f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;图13&lt;/p&gt;

&lt;p&gt;Proposal Layer forward（caffe layer的前传函数）按照以下顺序依次处理：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;生成anchors，利用$[d_x(A),d_y(A).d_w(A),d_h(A)]$对所有的anchors做bbox regression回归（这里的anchors生成和训练时完全一致）&lt;/li&gt;
  &lt;li&gt;按照输入的foreground softmax scores由大到小排序anchors，提取前pre_nms_topN(e.g. 6000)个anchors，即提取修正位置后的foreground anchors。&lt;/li&gt;
  &lt;li&gt;限定超出图像边界的foreground anchors为图像边界（防止后续roi pooling时proposal超出图像边界）&lt;/li&gt;
  &lt;li&gt;剔除非常小（width&amp;lt;threshold or height&amp;lt;threshold）的foreground anchors&lt;/li&gt;
  &lt;li&gt;进行非极大值抑制 non maximum suppression&lt;/li&gt;
  &lt;li&gt;再次按照nms后的foreground softmax scores由大到小排序fg anchors，提取前post_nms_topN(e.g. 300)结果作为proposal输出。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;之后输出$proposal=[x_1, y_1, x_2, y_2]$，注意，由于在第三步中将anchors映射回原图判断是否超出边界，所以这里输出的proposal是对应MxN输入图像尺度的，这点在后续网络中有用。另外我认为，严格意义上的检测应该到此就结束了，后续部分应该属于识别了~
RPN网络结构就介绍到这里，总结起来就是：
&lt;strong&gt;生成anchors -&amp;gt; softmax分类器提取foreground anchors -&amp;gt; bbox reg回归foreground anchors -&amp;gt; Proposal Layer生成proposals&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;classification&quot;&gt;Classification&lt;/h4&gt;

&lt;p&gt;Classification部分利用已经获得的proposal feature maps，通过full connect层与softmax计算每个proposal具体属于那个类别（如人，车，电视等），输出cls_prob概率向量；同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred，用于回归更加精确的目标检测框。Classification部分网络结构如图16。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-a9f7bee6160a4fb1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;图16 Classification部分网络结构图&lt;/p&gt;

&lt;p&gt;从PoI Pooling获取到7x7=49大小的proposal feature maps后，送入后续网络，可以看到做了如下2件事：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;通过全连接和softmax对proposals进行分类，这实际上已经是识别的范畴了&lt;/li&gt;
  &lt;li&gt;再次对proposals进行bounding box regression，获取更高精度的rect box&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;二一刀流-yolo--ssd&quot;&gt;二、一刀流 YOLO &amp;amp; SSD&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/od_regressor.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-d4bf799261533db6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;R-CNNs Platform&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一刀流的想法就比较暴力，给定一张图像，使用回归的方式输出这个目标的边框和类别。一刀流最核心的还是利用了分类器优秀的分类效果，首先给出一个大致的范围（最开始就是全图）进行分类，然后不断迭代这个范围直到一个精细的位置，如上图从蓝色的框框到红色的框框。&lt;/p&gt;

&lt;p&gt;这就是一刀流回归的思想，这样做的优点就是快，但是会有许多漏检。&lt;/p&gt;

&lt;h3 id=&quot;21-yolo--2015&quot;&gt;2.1 YOLO / 2015&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1506.02640&quot;&gt;YOLO&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;211-核心贡献&quot;&gt;2.1.1 核心贡献&lt;/h4&gt;

&lt;p&gt;YOLO将物体检测作为回归问题求解。基于一个单独的end-to-end网络，完成从原始图像的输入到物体位置和类别的输出。从网络设计上，YOLO与rcnn、fast rcnn及faster rcnn的区别如下：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;YOLO训练和检测均是在一个单独网络中进行。YOLO没有显示地求取region proposal的过程。而rcnn/fast rcnn 采用分离的模块（独立于网络之外的selective search方法）求取候选框（可能会包含物体的矩形区域），训练过程因此也是分成多个模块进行。Faster rcnn使用RPN（region proposal network）卷积网络替代rcnn/fast rcnn的selective
search模块，将RPN集成到fast rcnn检测网络中，得到一个统一的检测网络。尽管RPN与fast rcnn共享卷积层，但是在模型训练过程中，需要反复训练RPN网络和fast rcnn网络（注意这两个网络核心卷积层是参数共享的）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;YOLO将物体检测作为一个回归问题进行求解，输入图像经过一次inference，便能得到图像中所有物体的位置和其所属类别及相应的置信概率。&lt;strong&gt;而rcnn/fast rcnn/faster rcnn将检测结果分为两部分求解：物体类别（分类问题），物体位置即bounding box（回归问题）。&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-3bb48437540d747b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;preview&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;212基本流程&quot;&gt;2.1.2基本流程&lt;/h4&gt;

&lt;p&gt;YOLO检测网络包括24个卷积层和2个全连接层，如下图所示。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-2b9874921b0520ab.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;preview&quot; /&gt;&lt;/p&gt;

&lt;p&gt;其中，卷积层用来提取图像特征，全连接层用来预测图像位置和类别概率值。&lt;/p&gt;

&lt;p&gt;整体来看，Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测，整个系统如下图所示：首先将输入图片resize到448x448，然后送入CNN网络，最后处理网络预测结果得到检测的目标。相比R-CNN算法，其是一个统一的框架，其速度更快，而且Yolo的训练过程也是end-to-end的。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-566b5bd39e108353.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;具体来说，Yolo的CNN网络将输入的图片分割成 S×S 网格，然后每个单元格负责去检测那些中心点落在该格子内的目标，如图所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-e6603a645ae3fd68.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;边界框置信度&quot;&gt;&lt;strong&gt;边界框置信度&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;可以看到狗这个目标的中心落在左下角一个单元格内，那么该单元格负责预测这个狗。每个单元格会预测 $B$个边界框（bounding box）以及边界框的&lt;strong&gt;置信度（confidence score）&lt;/strong&gt;。所谓置信度其实包含两个方面，一是这个&lt;strong&gt;边界框含有目标的可能性大小&lt;/strong&gt;，二是这个&lt;strong&gt;边界框的准确度&lt;/strong&gt;。前者记为 $Pr(object)$ ，当该边界框是背景时（即不包含目标），此时 $Pr(object)=0$ 。而当该边界框包含目标时， $Pr(object)=1$。边界框的准确度可以用预测框与实际框（ground truth）的IOU（intersection over union，交并比）来表征，记为 $\text{IOU}^{truth}_{pred}$。因此置信度可以定义为：
\(Pr(object)*\text{IOU}^{truth}_{pred}\)&lt;/p&gt;

&lt;p&gt;边界框的大小与位置可以用4个值来表征：$ (x, y,w,h)$，其中 $(x,y)$ 是边界框的中心坐标，而 $w$和 $h$是边界框的宽与高。还有一点要注意，中心坐标的预测值 $(x,y)$ 是相对于每个单元格左上角坐标点的偏移值，并且单位是相对于单元格大小的，单元格的坐标定义如图6所示。&lt;strong&gt;而边界框的 $w$ 和 $h$ 预测值是相对于整个图片的宽与高的比例&lt;/strong&gt;，这样就保证了边界框中心点不会超过单元格，但是框的边界可以超过单元格。4个元素的大小应该在 $[0,1]$ 范围。这样，每个边界框的预测值实际上包含5个元素： $(x,y,w,h,c)$，其中前4个表征边界框的大小与位置，而最后一个值是置信度。&lt;/p&gt;

&lt;h5 id=&quot;类别置信度&quot;&gt;&lt;strong&gt;类别置信度&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;还有分类问题，对于每一个单元格其还要给出预测出$N$个类别概率值，其表征的是由该单元格负责预测的边界框其目标属于各个类别的概率。但是这些概率值其实是在各个边界框置信度下的条件概率，即 $Pr(class_{i}|object)$ 。以此计算出各个边界框类别置信度（class-specific confidence scores）: 
\(Pr(class_{i}|object)*Pr(object)*\text{IOU}^{truth}_{pred}=Pr(class_{i})*\text{IOU}^{truth}_{pred}\)&lt;/p&gt;

&lt;p&gt;边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。一般会根据类别置信度来过滤网络的预测框。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-b3fb660d778878bd.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;总结一下，每个单元格需要预测 $B&lt;em&gt;5+N$个值。如果将输入图片划分为 $S\times S$ 网格，那么最终预测值为  $S&lt;/em&gt;S&lt;em&gt;(B&lt;/em&gt;5+N)$ 大小的张量。整个模型的预测值结构如下图所示。对于PASCAL VOC数据，其共有20个类别，如果使用 $S=7,B=2$ ，那么最终的预测结果就是 $7\times 7\times 30$大小的张量。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-4508d39133d31988?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;213网络训练&quot;&gt;2.1.3网络训练&lt;/h4&gt;

&lt;p&gt;在训练之前，先在ImageNet上进行了预训练，其预训练的分类模型采用图8中前20个卷积层，然后添加一个average-pool层和全连接层。预训练之后，在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。整个网络的流程如下图所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-2be4d2e4aa297ada.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;损失函数：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;其中，&lt;em&gt;coordError&lt;/em&gt;、&lt;em&gt;iouError&lt;/em&gt;和&lt;em&gt;classError&lt;/em&gt;分别代表预测数据与标定数据之间的坐标误差、IOU误差和分类误差。&lt;/p&gt;

\[loss=\sum_{i=0}^{S^{2} }{coordError + iouError + classError}\]

&lt;p&gt;YOLO对上式loss的计算进行了如下修正。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;位置相关误差（坐标、IOU）与分类误差对网络loss的贡献值是不同的，因此YOLO在计算loss时，使用!$\lambda _{coord} =5$修正coordError&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;在计算IOU误差时，包含物体的格子与不包含物体的格子，二者的IOU误差对网络loss的贡献值是不同的。若采用相同的权值，那么不包含物体的格子的confidence值近似为0，变相放大了包含物体的格子的confidence误差在计算网络参数梯度时的影响。&lt;/p&gt;

    &lt;p&gt;可以这样理解，整个 YOLO 系统其实最有效的地方就是那些包含了目标中心点的网格它们所预测的 2 个 bbox，所以它们这 2 个 bbox 的位置信息就至关重要，所以它们的坐标就不允许它们变化剧烈，所以就需要添加一个系数放大它们的误差，进而达到惩罚的目的。而没有包含目标的网格，虽然它们也会预测 bbox，也会有 confidence 的预测，但基本等同于无效，所以可以看做它们对于整体的 Loss 而言，没有那么重要，因此要减弱它们对于 Loss 的影响，以防止它去干扰正常的包含了目标的那些 bbox 的 confidence 表现。&lt;/p&gt;

    &lt;p&gt;为解决这个问题，YOLO 使用$\lambda _{noobj} =0.5$修正iouError。（注：此处的&lt;strong&gt;包含&lt;/strong&gt;是指存在一个物体，它的中心坐标落入到格子内）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;对于相等的误差值，大物体误差对检测的影响应小于小物体误差对检测的影响。这是因为，相同的位置偏差占大物体的比例远小于同等偏差占小物体的比例。比如预测一个小的 bbox，groundtruth 的 width 是 4，它预测是 3，那么它的误差是 1，再预测一个大的 bbox，groundtruth 的 width 是 100，预测值是 99，那么误差也是 1。很容易发现，进行小尺寸的 bbox 预测时，误差更敏感，所以 sum-sqaured error 手段需要改良。&lt;/p&gt;

    &lt;p&gt;YOLO将物体大小的信息项（w和h）进行求平方根来改进这个问题。还是用刚才的例子，小的 bbox width prediction = 3,groundtruth = 4，误差为 0.067。大的 bbox width prediction = 99,groundtruth = 100，误差为 0.0025。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;综上，YOLO在训练过程中Loss计算如下式所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-5ea7bd0dbfc56f2f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;其中，$x,y,w,C,p$为网络预测值，$x,y,w,C,\widehat{p}$帽 为标注值。$\Pi _{i}^{obj} $表示物体落入格子i中，$\Pi _{ij}^{obj} $和$\Pi _{ij}^{noobj}$ 分别表示物体落入与未落入格子&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;的第&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;j&lt;/code&gt;个bounding box内。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;注：
YOLO方法模型训练依赖于物体识别标注数据，因此，对于非常规的物体形状或比例，YOLO的检测效果并不理想。
YOLO采用了多个下采样层，网络学到的物体特征并不精细，因此也会影响检测效果。
 YOLO loss函数中，大物体IOU误差和小物体IOU误差对网络训练中loss贡献值接近（虽然采用求平方根方式，但没有根本解决问题）。因此，对于小物体，小的IOU误差也会对网络优化过程造成很大的影响，从而降低了物体检测的定位准确性。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;214局限&quot;&gt;2.1.4局限&lt;/h4&gt;

&lt;p&gt;虽然每个格子可以预测B个bounding box，但是最终只选择只选择IOU最高的bounding box作为物体检测输出，即每个格子最多只预测出一个物体。当物体占画面比例较小，如图像中包含畜群或鸟群时，每个格子包含多个物体，但却只能检测出其中一个。这是Yolo算法的一个缺点，在后来的改进版本中，Yolo9000是把类别概率预测值与边界框是绑定在一起的。&lt;/p&gt;

&lt;h3 id=&quot;22-ssd--2015&quot;&gt;2.2 SSD / 2015&lt;/h3&gt;

&lt;p&gt;论文：&lt;a href=&quot;https://arxiv.org/abs/1512.02325&quot;&gt;SSD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SSD 就在 YOLO 的主意上添加了 Faster R-CNN 的 Anchor 概念，并融合不同卷积层的特征做出预测。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/ssd_anchor.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-3ee4fdbcffecc172.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;SSD Anchor&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我们从上图就可以很明显的看出这是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YOLO 分治网络&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Faster R-CNN Anchor&lt;/code&gt; 的融合，这就大大提高了对小物体的检测。这里作者做实验也提到和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Faster R-CNN&lt;/code&gt; 一样的结果，这个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Anchor&lt;/code&gt; 的数量和形状会对性能造成较大的影响。&lt;/p&gt;

&lt;p&gt;除此之外，由于这个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Anchor&lt;/code&gt; 是规整形状的，但是有些物体的摆放位置是千奇百怪的，所以没有 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;数据增强&lt;/code&gt; 前的效果比增强后的效果差 7 个百分点。直观点理解，做轻微地角度扭曲让 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Anchor&lt;/code&gt; 背后的神经元“看到”更多的信息。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.davex.pw/images/object_detection/ssd_struct.png&quot;&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-bf2bf64e1450a1e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;SSD Structure&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;还有一个重大的进步是结合了不同尺寸大小 Feature Maps 所提取的特征，然后进行预测。这是 FPN 网络提出前的第一次做 Feature Pyramid 的尝试，这个特征图金字塔结合了不同层的信息，从而结合了不同 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;尺寸&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;大小&lt;/code&gt; 的特征信息。&lt;/p&gt;

&lt;p&gt;这个尝试就大大地提高了识别的精度，且高分辨率（尺寸大）的 Feature Map 中含有更多小物体的信息，也是因为这个原因 SSD 能够较好的识别小物体。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;除此之外，和 YOLO 最大的区别是，SSD 没有接 FC 减少了大量的参数量、提高了速度。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;小结--2018&quot;&gt;小结 / 2018&lt;/h3&gt;

&lt;p&gt;回顾过去，从 YOLO 到 SSD ，人们兼收并蓄把不同思想融合起来。&lt;/p&gt;

&lt;p&gt;YOLO 使用了分治思想，将输入图片分为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SxS&lt;/code&gt; 的网格，不同网格用性能优良的分类器去分类。
YOLO v1 也有和当年其它杰出的目标检测系统做对比，但在今天来看，这个并不十分重要，重要的是我们需要理解 YOLO 快的原因。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;YOLO 就是一个撒渔网的捕鱼过程，一次性搞定所有的目标定位。&lt;/li&gt;
  &lt;li&gt;YOLO 快的原因在于比较粗的粒度将输入图片划分网格，然后做预测。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;YOLO 的算法精髓都体现在它的 Loss 设计上及作者如何针对问题改进 Loss，这种思考问题的方式才是最值得我们学习的。&lt;/p&gt;

&lt;p&gt;SSD 将 YOLO 和 Anchor 思想融合起来，并创新使用 Feature Pyramid 结构。&lt;/p&gt;

&lt;p&gt;但是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resize&lt;/code&gt; 输入，必定会损失许多的信息和一定的精度，这也许是一刀流快的原因。&lt;/p&gt;

&lt;p&gt;无论如何，YOLO 和 SSD 这两篇论文都是让人不得不赞叹他们想法的精巧，让人受益良多。&lt;/p&gt;

&lt;h2 id=&quot;三总结-summary&quot;&gt;三、总结 Summary&lt;/h2&gt;

&lt;p&gt;在「目标检测」中有两个指标：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;快（Fast）&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;准（Accurate）&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;一刀流代表的是快，但是最后在快和准中找到了平衡，&lt;strong&gt;第一是快&lt;/strong&gt;，第二是准。
两刀流代表的是准，虽然没有那么快但是也有 6 FPS 可接受的程度，&lt;strong&gt;第一是准&lt;/strong&gt;，第二是快。&lt;/p&gt;

&lt;p&gt;两类算法都有其适用的范围，比如说实时快速动作捕捉，一刀流更胜一筹；复杂、多物体重叠，两刀流当仁不让。没有不好的算法，只有不合适的使用场景。&lt;/p&gt;

&lt;h2 id=&quot;四一些概念&quot;&gt;四、一些概念&lt;/h2&gt;

&lt;h3 id=&quot;1-iou&quot;&gt;1. IOU&lt;/h3&gt;

&lt;p&gt;IoU度量两个框之间的重叠。我们用它来测量我们预测的框与ground truth(真实物体边界)的重叠程度。在一些数据集中，我们预先定义了一个IoU阈值(比如0.5)来分类预测是真阳性还是假阳性。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-92e08afbb8efeb8f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;2-map&quot;&gt;2. mAP&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;相关概念&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;mAP: mean Average Precision, 即各类别AP的平均值&lt;/p&gt;

&lt;p&gt;AP: PR曲线下面积，后文会详细讲解&lt;/p&gt;

&lt;p&gt;PR曲线: Precision-Recall曲线&lt;/p&gt;

&lt;p&gt;Precision: TP / (TP + FP) 在你认为的正样本中， 有多大比例真的是正样本&lt;/p&gt;

&lt;p&gt;Recall: TP / (TP + FN) 在真正的正样本中， 有多少被你找到了&lt;/p&gt;

&lt;p&gt;TP: IoU&amp;gt;0.5的检测框数量（同一Ground Truth只计算一次）&lt;/p&gt;

&lt;p&gt;FP: IoU&amp;lt;=0.5的检测框，或者是检测到同一个GT的多余检测框的数量&lt;/p&gt;

&lt;p&gt;FN: 没有检测到的GT的数量&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;明确问题:&lt;/strong&gt; 大背景是object detection， 我就以正在学的RetinaNet应用背景为例， 识别出来的每一个框都有N+1个score， 对应着N个class和1个background， 我们会选score最高的那个作为最终的判断。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;问题核心:&lt;/strong&gt; 我们需要一个对于score的threshold, 为什么呢? 比如在一个bounding box里， 我识别出来鸭子的score最高， 可是他也只有0.1， 那么他真的是鸭子吗？ 很可能他还是负样本。 所以我们需要一个阈值， 如果识别出了鸭子而且分数大于这个阈值才真的说他是正样本， 否则他是负样本&lt;/p&gt;

&lt;p&gt;那么threshold到底是怎么影响precision和recall的呢？ 我们还是用鸭子的例子&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;如果threshold太高， prediction非常严格， 所以我们认为是鸭子的基本都是鸭子，precision就高了；但也因为筛选太严格， 我们也放过了一些score比较低的鸭子， 所以recall就低了&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;如果threshold太低， 什么都会被当成鸭子， precision就会很低， recall就会很高&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这样我们就明确了threshold确实对鸭子的precision和recall产生影响和变化的趋势， 也就带来了思考， precision不是一个绝对的东西，而是相对threshold而改变的东西， recall同理， 那么单个用precision来作为标准判断， 就不合适。 这是一场precision与recall之间的trade off， 用一组固定值表述不够全面， 因为我们根据不同的threshold， 可以取到不同（也可能相同）的precision recall值。 这样想的话对于每个threshold，我们都有（precision， recall）的pair， 也就有了precision和recall之间的curve关系&lt;/p&gt;

&lt;p&gt;有了这么一条precision-recall curve， 他衡量着两个有价值的判断标准， precision和recall的关系， 那么不如两个一起动态考虑， 就有了鸭子这个class的Average Precision， 即curve下的面积， 他可以充分的表示在这个model中， precision和recall的总体优劣。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-de04a4181da0622b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;最后， 我们计算每个class的Average Precision， 就得到了mean Average Precision&lt;/p&gt;

&lt;h3 id=&quot;非极大值抑制nms&quot;&gt;非极大值抑制（&lt;strong&gt;NMS&lt;/strong&gt;）：&lt;/h3&gt;

&lt;p&gt;RCNN会从一张图片中找出n个可能是物体的矩形框，然后为每个矩形框为做类别分类概率：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1083955-7fbdd7b52b341655.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;就像上面的图片一样，定位一个车辆，最后算法就找出了一堆的方框，我们需要判别哪些矩形框是没用的。非极大值抑制的方法是：先假设有6个矩形框，根据分类器的类别分类概率做排序，假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。&lt;/p&gt;

&lt;p&gt;(1)从最大概率矩形框F开始，分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;&lt;/p&gt;

&lt;p&gt;(2)假设B、D与F的重叠度超过阈值，那么就扔掉B、D；并标记第一个矩形框F，是我们保留下来的。&lt;/p&gt;

&lt;p&gt;(3)从剩下的矩形框A、C、E中，选择概率最大的E，然后判断E与A、C的重叠度，重叠度大于一定的阈值，那么就扔掉；并标记E是我们保留下来的第二个矩形框。&lt;/p&gt;

&lt;p&gt;就这样一直重复，找到所有被保留下来的矩形框。&lt;/p&gt;

&lt;p&gt;非极大值抑制（NMS）顾名思义就是抑制不是极大值的元素，搜索局部的极大值。这个局部代表的是一个邻域，邻域有两个参数可变，一是邻域的维数，二是邻域的大小。这里不讨论通用的NMS算法，而是用于在目标检测中用于提取分数最高的窗口的。例如在行人检测中，滑动窗口经提取特征，经分类器分类识别后，每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高（是行人的概率最大），并且抑制那些分数低的窗口。&lt;/p&gt;

&lt;h2 id=&quot;参考资料-reference&quot;&gt;参考资料 Reference&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1311.2524&quot;&gt;R-CNN “Rich feature hierarchies for accurate object detection and semantic segmentation”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1406.4729&quot;&gt;SPP Net “Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1504.08083&quot;&gt;Fast R-CNN “Fast R-CNN”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1506.01497&quot;&gt;Faster R-CNN “Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1703.06870&quot;&gt;Mask R-CNN “Mask R-CNN”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1506.02640&quot;&gt;YOLO “You Only Look Once: Unified, Real-Time Object Detection”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1512.02325&quot;&gt;SSD “SSD: Single Shot MultiBox Detector”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1612.08242&quot;&gt;YOLO9000 “YOLO9000: Better, Faster, Stronger”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/31426458&quot;&gt;一文读懂Faster RCNN&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/33981103&quot;&gt;基于深度学习的「目标检测」算法综述&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/23006190&quot;&gt;RCNN- 将CNN引入目标检测的开山之作&lt;/a&gt;
12.https://blog.csdn.net/briblue/article/details/84794511&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 11 Jun 2019 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2019/06/11/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B-%E7%AE%97%E6%B3%95%E7%BB%BC%E8%BF%B0/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2019/06/11/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B-%E7%AE%97%E6%B3%95%E7%BB%BC%E8%BF%B0/</guid>
        
        <category>学习笔记</category>
        
        <category>论文综述</category>
        
        
      </item>
    
      <item>
        <title>C/C++结构体排序</title>
        <description>&lt;h1 id=&quot;cc结构体排序&quot;&gt;C/C++结构体排序&lt;/h1&gt;

&lt;p&gt;有时候在开发中我们需要根据自己定义的某个变量对整体进行排序，这时候就需要用到结构体排序的思想：&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;问题描述：定义存放一个学生信息的结构体类型，学生信息包括：姓名，学号，性别，院系，要求在随意输入&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;个学生的相关信息后，按照学号从小到大顺序输出这些学生的信息。&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;输入描述：先输入&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;名学生的信息，按学号顺序排序输出后在输入要统计的院系名称。&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;程序输出：先按学号从小到大的顺序输出学生信息）。&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt;*/&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;student&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//定义一个关于学生的结构体，包括姓名学号性别以及专业&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;major&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;student&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//定义储存学生信息的结构体变量&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;student&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//依次输入各个学生的信息&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;major&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//利用冒泡排序法进行学号的排序&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;stu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 27 May 2019 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2019/05/27/C++%E7%BB%93%E6%9E%84%E4%BD%93%E6%8E%92%E5%BA%8F/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2019/05/27/C++%E7%BB%93%E6%9E%84%E4%BD%93%E6%8E%92%E5%BA%8F/</guid>
        
        <category>C/C++</category>
        
        <category>学习总结</category>
        
        
      </item>
    
      <item>
        <title>tmux自定义配置</title>
        <description>&lt;h1 id=&quot;tmux自定义配置&quot;&gt;tmux自定义配置&lt;/h1&gt;

&lt;p&gt;在已经有自己的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmux.conf&lt;/code&gt;配置文件的条件下，在终端输入&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp tmux.conf ~/.tumx.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;便能自动将当前环境中的tmux配置成自己熟悉的快捷键了。&lt;/p&gt;

&lt;p&gt;以下是我的自定义tumx.conf&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;set -g prefix C-b #
# let be vim
setw -g mode-keys vi # 开启vi风格后，支持vi的C-d、C-u、hjkl等快捷键
bind Escape copy-mode # 绑定esc键为进入复制模式
bind -T copy-mode-vi v send-keys -X begin-selection # 绑定v键为开始选择文本
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel # 绑定y键为复制选中文本

# for MAC
# buffer缓存复制到Mac系统粘贴板
bind C-c run &quot;tmux save-buffer - | reattach-to-user-namespace pbcopy&quot;
# Mac系统粘贴板内容复制到会话
bind C-v run &quot;reattach-to-user-namespace pbpaste | tmux load-buffer - \; paste-buffer -d&quot;

# for Linux need to install xclip
# buffer缓存复制到Linux系统粘贴板
# bind C-c run &quot; tmux save-buffer - | xclip -i -sel clipboard&quot;
# Linux系统粘贴板内容复制到会话
# bind C-v run &quot; tmux set-buffer \&quot;$(xclip -o -sel clipboard)\&quot;; tmux paste-buffer&quot;

# 绑定快捷键为r
bind r source-file ~/.tmux.conf \; display-message &quot;Config reloaded..&quot;

# 垂直方向新增面板，默认进入当前目录
unbind &apos;&quot;&apos;
bind - splitw -v -c &apos;#{pane_current_path}&apos;
# 水平方向新增面板，默认进入当前目录
unbind %
bind | splitw -h -c &apos;#{pane_current_path}&apos;

set-option -g mouse on # 等于启动了鼠标的所有操作

# 绑定hjkl键为面板切换的上下左右键
bind -r k select-pane -U # 绑定k为↑
bind -r j select-pane -D # 绑定j为↓
bind -r h select-pane -L # 绑定h为←
bind -r l select-pane -R # 绑定l为→

bind -r e lastp # 选择最后一个面板
bind -r ^e last # 选择最后一个窗口

bind -r ^u swapp -U # 与前一个面板交换位置
bind -r ^d swapp -D # 与后一个面板交换位置

# 绑定Ctrl+hjkl键为面板上下左右调整边缘的快捷指令
bind -r ^k resizep -U 10 # 绑定Ctrl+k为往↑调整面板边缘10个单元格
bind -r ^j resizep -D 10 # 绑定Ctrl+j为往↓调整面板边缘10个单元格
bind -r ^h resizep -L 10 # 绑定Ctrl+h为往←调整面板边缘10个单元格
bind -r ^l resizep -R 10 # 绑定Ctrl+l为往→调整面板边缘10个单元格

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Thu, 16 May 2019 00:00:00 +0000</pubDate>
        <link>https://wdblink.github.io/2019/05/16/tmux%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AE/</link>
        <guid isPermaLink="true">https://wdblink.github.io/2019/05/16/tmux%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AE/</guid>
        
        <category>一些工具</category>
        
        
      </item>
    
  </channel>
</rss>
