<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://wang-akang.github.io/study/feed.xml" rel="self" type="application/atom+xml" /><link href="https://wang-akang.github.io/study/" rel="alternate" type="text/html" /><updated>2025-06-29T13:51:13+00:00</updated><id>https://wang-akang.github.io/study/feed.xml</id><title type="html">My Blog</title><subtitle>This is my personal study blog.</subtitle><entry><title type="html">学习</title><link href="https://wang-akang.github.io/study/2025/06/29/title.html" rel="alternate" type="text/html" title="学习" /><published>2025-06-29T00:00:00+00:00</published><updated>2025-06-29T00:00:00+00:00</updated><id>https://wang-akang.github.io/study/2025/06/29/title</id><content type="html" xml:base="https://wang-akang.github.io/study/2025/06/29/title.html"><![CDATA[<hr />]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">CLIP 论文逐段精读【论文精读】</title><link href="https://wang-akang.github.io/study/2025/06/18/title.html" rel="alternate" type="text/html" title="CLIP 论文逐段精读【论文精读】" /><published>2025-06-18T00:00:00+00:00</published><updated>2025-06-18T00:00:00+00:00</updated><id>https://wang-akang.github.io/study/2025/06/18/title</id><content type="html" xml:base="https://wang-akang.github.io/study/2025/06/18/title.html"><![CDATA[<hr />

<p>00:06 评价</p>

<p>评价：方法出奇的简单，但效果出奇的好。比如：迁移学习的能力非常好，预训练好的模型能在任意一个视觉分类的数据集上，取得不错的效果；而且还是zero-shot的，就是没有在这些数据集上做训练，也能取得很好的效果。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278662.jpg" alt="" /></p>

<p>01:31 CLIP的模型总览图</p>

<p><strong>CLIP如何做预训练：</strong></p>

<ol>
  <li>输入：图片+文字的配对</li>
  <li>输入encoder，生成特征</li>
  <li>在特征上做对比学习</li>
  <li>特征矩阵里获得正负样本，正样本就是匹配的图文对（矩阵对角线），负样本则是所有不匹配的图文对</li>
</ol>

<p>训练集：4亿个图文对，数据质量高</p>

<p><strong>CLIP如何做zero-shot推理：</strong></p>

<p>一、预训练之后的CLIP只获得了图像和文本的特征，需要分类头才能做推理</p>

<p>引出Prompt template，以ImageNet为例</p>

<p>1、输入：CLIP先把ImageNet的1000个类，用于生成一个object作为替换位的句子，1000个句子</p>

<p>2、预训练好的文本encoder，生成1000个文本特征</p>

<p>为什么要Prompt template？为什么不直接抽取文本特征？</p>

<p>因为预训练的时候使用的是图像文本对，训练的时候为了保持一致，也要让encoder看到的是一个句子</p>

<p>还有另外两种生成句子的方法，Prompt engineering和Prompt ensemble去进一步提高模型的准确率，而不需要重新训练这个模型</p>

<p>二、zero-shot分类</p>

<p>输入：任意图片</p>

<p>图片encoder，生成图片特征</p>

<p>图片特征与所有文本特征做余弦相似性衡量</p>

<p>输出：最相似的文本特征对应的句子，完成分类</p>

<p>06:03 摆脱基础类的限制</p>

<p>CLIP，对于任意的图片和文本，都可以通过算相似度的方式，判断图片中的物体。</p>

<p>换句话说，任意给CLIP一张图片，都可以通过给模型不同的文本句子，从而知道图片中是否有我感兴趣的物体。</p>

<p>标题：利用来自nlp的监督信号去训练一个迁移效果很好的视觉模型。利用NLP的信号摆脱了基础类的限制，使图像和文本建立了强联系。</p>

<p>07:21做到了把视觉和文本的语义建立起了联系，所以学习到的特征语义性非常强，迁移效果非常好。因为和nlp的结合，CLIP学习到的视觉特征和语言所描述的物体产生了强烈的联系。</p>

<p>09:11 基于CLIP的有趣的应用</p>

<p>图像生成、物体检测（摆脱基础类限制体现）、视频检索（可以OCR）</p>

<p>14:13 整体架构</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278663.jpg" alt="" /></p>

<p>16:02 精读开始</p>

<p>标题：利用来自nlp的监督信号去学习一个迁移效果很好的视觉模型</p>

<p>方法：利用nlp的监督信号</p>

<p>目的：迁移性，学习泛化性好的特征</p>

<p>16:59 摘要</p>

<p>目前最先进的视觉系统：固定的提前定义好的物体类别集合，模型通过预测提前定义好的类别完成模型训练。这属于有限制性的监督信号，这也限制了模型本身的泛化性，尤其是要识别新类别物体的时候，就需要新的数据去训练新的模型。</p>

<p>本文：从文本中获得监督信号，也就是只要用语言描述过的物体，就有可能让视觉模型能识别到。</p>

<p>证明：用一个很简单的预训练任务，就能非常高效的、可扩展的去学习最好的图像表征</p>

<p>预训练任务：配对任务，给定一张图片和一些句子，模型需要判断哪个句子和图片是配对的</p>

<p>数据集： 4亿的图文数据集</p>

<p>自监督的训练方式：多模态的对比学习来完成模型训练</p>

<p>预训练完成之后，自然语言就被用来引导视觉模型做物体分类，也就是Prompt，而且Prompt不局限于学到的视觉概念，还能扩展到新的类别，从而，学到的这个模型可以直接用在下游任务上去做zero-shot推理</p>

<p>20:52 引言</p>

<p><strong>NLP效果非常好的框架：文本进文本出+利用自监督信号训练整个模型+原始数据</strong></p>

<p>直接从原始的文本数据中去预训练一个模型已经在过去几年里在nlp领域取得了革命性的成功（bert gpt t5等模型）</p>

<p>不论是完形填空还是自回归预测的方式，都是一种自监督的预训练方式，所以目标函数是与下游任务无关的，只是想通过预训练得到非常好非常能泛化的特征。</p>

<p>随着计算资源、模型变大、数据增多，模型的能力也会稳健的提升。这就是一套文字进文字出，并不是在做什么特殊的分类任务。模型架构也是和下游任务无关的，那么在直接用在下游任务上的时候，就不用费尽心思去研究针对任务的输出头或者针对数据集的特殊处理了。这里面最厉害的就是OpenAI自己的gpt3模型了，什么任务都能做，而且不需要特定数据或者只需要一点点数据做微调就可以和之前精心设计的模型取得差不多的结果</p>

<p>这些鼓舞人心的结果证实了，这种文本进文本出，利用自监督的信号去训练整个模型的框架下，这种大规模没有标注的数据是要比那些手工标注质量非常高的数据集，反而是要更好用的。但是在视觉领域，大家一般还是在imagenet这种数据集上去预训练一个模型，这就会让预训练好的模型有诸多的限制。</p>

<p><strong>NLP这套效果非常好的框架能不能用在视觉里？根据过去的工作看，是没问题的</strong></p>

<p>方式：zero-shot的迁移学习</p>

<p>局限：模型和数据上都没有很大的规模，所以效果没有非常拔群</p>

<ul>
  <li>virtex：用自回归的预测方式做模型的预训练</li>
  <li>ICMLM：用完形填空的方式做预训练</li>
  <li>Convirt：只在医疗图像上做了实验</li>
</ul>

<p>为什么利用自然语言那边的监督信号是一个很有前途的方向，那为什么在视觉里这一系列的工作那么少呢</p>

<ol>
  <li>没有大的数据集</li>
  <li>没有大模型</li>
  <li>没有大算力</li>
  <li>没有这么好的自监督训练方式</li>
</ol>

<p>所以效果没有那么好。</p>

<p>很好的标注数据预训练出来的模型有局限性；原始文字预训练出来的模型性能太低；所以用文本带来的弱监督信号去帮助有监督的模型取得更好的效果，但是虽然这种折中方法效果很好，但还是有很大局限性：之前的工作需要精心设计，而且监督信号只有1000个或者18000个类，并不能做到真正的随心所欲的去检测到任何想检测到的类，而且Mahajan et al. (2018) and Kolesnikov et al.(2019)这两种方式都是固定用一个softmax分类头去做分类的，所以输出都是固定的，对于新类别无能为力，也就是没有灵活的做zero-shot的能力。</p>

<p>如Mahajan et al. (2018) and Kolesnikov et al.(2019)等，之前的弱监督方法和如VirTex, ICMLM借助自然语言处理去学习图像表征的方法，他们最大区别在规模上（数据上和模型上）</p>

<p><strong>CLIP解决了规模问题：超大的图文对数据集，超大的模型</strong></p>

<p>作者发现，<strong>迁移学习的效果和模型大小正相关</strong></p>

<p><strong>如何证明迁移效果：刷更多的榜。</strong></p>

<p><strong>CLIP能和有监督训练的数据集打成平手，甚至效果更好</strong></p>

<p><strong>用linear probe证明CLIP学到的特征的有效性。</strong></p>

<p><strong>CLIP比imagenet训练出来的模型效果更好，计算上也更加高效</strong></p>

<p><strong>zero-shot的clip模型更加稳健：当效果和之前有监督imagenet上训练好的模型效果持平的时候，泛化性能却远远好于imagenet上有监督训练好的模型</strong></p>

<p><strong>CLIP：想法简单，实现高效，性能在各个数据集上都非常好，而且泛化和稳健性都不错，全面碾压之前的方法。</strong></p>

<p>33:37 方法</p>

<p><strong>CLIP怎么预训练的？</strong></p>

<p>利用自然语言的监督信号，去训练一个比较好的视觉模型</p>

<p><strong>总结（统一）之前的工作+把规模做大看看效果</strong></p>

<p>之前的工作：想用文本做监督信号。为什么以前做不好呢？因为NLP那边的模型也不是很好学，Topic models和n-gram的形式都很复杂，不好做跨模态的训练，但是随着transformer和自监督的训练方式兴起，NLP那边彻底革命了：deep contextual representation，就是具有上下文语义环境的学习方式，比如bert用的完形填空。</p>

<p>在自监督的学习范式下，现在nlp模型终于可以用这种取之不尽用之不竭的文本监督信号了，所以训练出来的模型又大又好，不仅简单而且泛化的也好，这就为多模态的训练铺平了道路。</p>

<p>我们为什么非要用这种自然语言的监督信号来训练一个视觉模型呢？</p>

<p>因为好处实在是太多了，其中两个最重要的：</p>

<ol>
  <li>不用再标注数据了，很容易提高数据的规模，而且因为现在的监督信号是一个文本，而不是文中说的n选1的标签了，那模型的输入输出自由度就大了很多</li>
  <li>因为在训练的时候把文字和图片绑定在了一起，那么学到的特征就不再单单是一个视觉特征了，而是一个多模态的特征，当和语言联系在一起以后，就很容易去做zero-shot的迁移学习了。如果只是做单模态的自监督学习的话，无论是用单模态的对比学习（MOCO），还是单模态的掩码学习（MAE）都只能学到视觉特征，而无法和自然语言联系到一起，那还是很难去做zero-shot的迁移</li>
</ol>

<p>结论：用文本的监督信号帮助去训练一个视觉模型是很有潜力的。</p>

<p><strong>1、要做图片和文本配对的学习，就需要有一个足够大的数据集，里面有很多很多图片文本对。</strong></p>

<p>过去的数据集都不够大，质量不够好，所以自己造一个数据集wit，4亿个图文对</p>

<p><strong>2、预训练的方法，以及如何选择预训练的方法</strong>39:19</p>

<p>视觉这边的模型都非常大，训练起来都非常贵。过去的方法只是训练区预测仅仅1000个类，就已经需要训练数年。</p>

<p>现在数据集更大，任务更难（从自然语言处理里直接去学open set of visual concepts，要去学开放世界里所有的视觉概念）</p>

<p>训练效率对于多模态预训练的成功至关重要，作者做了一些尝试：图像CNN，文本transformer，从头开始训练，任务是给定图片 要预测图片所对应的文本。</p>

<p><strong>为什么要用对比学习？</strong></p>

<p>如果给定一张图片，要去预测它对应的文本，是需要逐字逐句去预测文本的，这个任务就太难了。因为对于一张图片来说，可以有很多很多不同的描述，文本之间的差距是非常巨大的，如果用预测型的任务去预训练模型的话，就有太多的可能性了，模型训练的就非常慢。作者发现，如果把训练任务变成一个对比的任务，也就是说，只需要判断这个图片和这个文本是不是一个配对，这个任务听起来就简单了很多，因为不再需要逐字逐句的去预测文本了，只需要图片和文本是配对的就行，这个约束一下就放宽了很多。这个监督信号其实也更合理。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278664.jpg" alt="" /></p>

<p>如图2，仅仅把预测型的对比函数换成对比型的目标函数（黄线→绿线），训练效率一下就提高了四倍；训练效率随着约束逐渐放宽在成倍的提高，也就说明<strong>基于对比学习的训练方法，训练效率是非常高的。</strong></p>

<ul>
  <li>蓝线：基于transformer做预测型的任务</li>
  <li>黄线：词袋预测，不再逐字逐句的预测文本，文本已经全局化的抽成了一些特征，所以相应的约束被放宽了</li>
  <li>绿线：对比学习，进一步放宽约束，不再预测单词，只需要判断是不是图文匹配对</li>
</ul>

<p><strong>3、伪代码认识CLIP方法</strong>43:39 伪代码</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278665.jpg" alt="" /></p>

<p>CLIP的伪代码真的很简单，和之前的对比学习没有什么区别，无非就是把单模态的正样本换成了多模态的正样本。</p>

<p>46:23 一些有意思的细节</p>

<ol>
  <li>因为收集的数据集太大了，所以模型的训练不太会有overfitting的问题，所以实现起来就比之前的工作简单很多。比如训练CLIP的时候，对应的文本编码器和图片编码器都是不需要提前进行预训练的</li>
  <li>在做最后的投射的时候，没有用非线性的投射层，而是用了一个线性的投射层。SImCLR moco这一系列论文的时候，证明非线性的投射层会比用线性的投射层，带来将近10个点的性能提升。但是作者在本文中说，在他们多模态的预训练过程中，他们发现线性非线性没什么大关系，他们怀疑：这种非线性的投射层non-linear projections只是适配纯图片的单模态学习的</li>
  <li>因为数据集太大了，所以也不需要做太多的数据增强，本文中唯一做了的数据增强就是随机裁剪</li>
  <li>因为模型实在是太大了，数据集也实在是太大了，训练起来太耗时，所以不太好去做调参的工作，所以在算对比学习的超参数的时候，温度这个超参数（非常重要，稍微调一调最后的性能就会有很大的改变）但本文作者实在是不想调，于是就设置成了一个可以学习的标量，所以这个参数直接在模型训练过程中就被优化了，而不需要当做一个超参数，最后再去调参</li>
</ol>

<p><strong>怎么训练这些模型</strong>48:35 训练</p>

<p>视觉这边：训练了5个resnet，3个vit</p>

<p>ResNet-50, a ResNet-101, and then 3 more which follow EfficientNet-style model scaling and use approximately 4x, 16x, and 64x the compute of a ResNet-50</p>

<p>ViT-B/32, a ViT-B/16, and a ViT-L/14</p>

<p><strong>第二章总结：</strong></p>

<ol>
  <li>CLIP模型是如何预训练的</li>
  <li>作者为什么用对比学习来预训练CLIP</li>
</ol>

<p><strong>实验</strong>52:21 实验</p>

<p><strong>1、什么是zero-shot transfer</strong></p>

<p>动机：</p>

<p>之前的自监督或者无监督的方法，主要研究的是特征学习的能力，目标是去学一种泛化性比较好的特征。但即使学到了很好的特征，如果想应用到下游任务上，还是需要有标签的数据做微调，所以还牵扯各种各样的问题：下游任务不好收集数据，<strong>分布偏移(Distribution shift)</strong> 【分布偏移在监督学习中一般指的是训练分布与测试分布不同，在离线强化学习中指的是训练策略与行为策略不一致。】那么如何能够训练一个模型，接下来就不在训练或者不再微调了呢？</p>

<p>一旦借助文本训练好了这个又大又好的模型，然后就可以用这个文本作为引导，去很灵活的做zero-shot的迁移学习，至少在分类上效果都非常好。</p>

<p><strong>怎么用CLIP做zeroshot的迁移呢？</strong></p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278666.jpg" alt="" /></p>

<ol>
  <li>当CLIP预训练好之后，其实就有两个编码器：图像和文本，都已经训练好了</li>
  <li>这时候任意给一张图片，通过图片编码器，就会得到一个图片特征，</li>
  <li>文本输入：一些感兴趣的标签单词，通过prompt engineering就会得到对应数量的句子，然后通过文本编码器，就会得到相应的文本特征</li>
  <li>所有文本特征和图片特征算余弦相似度，得到的相似度还会通过一层softmax，得到一个概率分布</li>
  <li>哪个概率最大，也就是哪个相似度最高，大概率就是在描述这张照片。此时句子中包含的物体就是图片中的物体了</li>
</ol>

<p>如果给imagenet里所有的图片去做zeroshot的推理，去测试模型的效果如何，那么1000个类应该生成1000个句子，如此去与图像特征算相似度，得到结果。当然，这个过程是可以分批次进行的，所以CLIP的推理还是非常高效的，不会非常慢。</p>

<p><strong>对比结果</strong>55:57</p>

<p>57:09 提示工程</p>

<p>基于prompt的学习最近非常火，无论是在CV还是NLP都非常火</p>

<p>主要是在做微调或者直接做推理的时候用的一种方法，而不是在预训练阶段，所以不需要那么多的计算资源，而且效果好，所以影响力非常大。</p>

<p>在这里，prompt指的是文本的引导作用。</p>

<p><strong>为什么要做prompt engineering和prompt ensembling？</strong></p>

<ol>
  <li>polysemy歧义性：一个单词可以同时有很多含义。在做图文匹配的时候，如果每次只用一个单词（标签对应的一个单词）去做文本的特征抽取，就可能会面临这种问题。比如在imagenet数据集里同时包含两个类：construction cranes and cranes that fly，在不同的语境下crane的含义是不同的，建筑环境中指的是起重机，作为一个动物指的是鹤。这个时候就会出现歧义了，算得很有可能就是错的。别的数据集也可能有这种问题。</li>
  <li>distribution gap：做预训练的时候，匹配的文本一般都是一个句子，很少是一个单词。可是在推理的时候，如果每次都进来的是一个单词，那么可能就会存在distribution gap的问题，抽出来的特征可能就不会很好。</li>
</ol>

<p>基于上面两个问题，作者就想了一个很简单的方式：做了一个提示模板prompt template “A photo of a {label}.”把标签变成一个句子。已经是个句子了就不会出现distribution gap的问题。因为这个模板的含义是：这是一个什么的图片，所以这个标签多指的是名词，就能解决歧义性的问题了。</p>

<p>作者发现用了这个提示模板之后，准确度提高了1.3%。</p>

<p><strong>prompt engineering不光可以做提示模版，还可以做很多事情：如果提前知道一些信息，这对zeroshot的推理是非常有帮助的。</strong>For example on Oxford-IIIT Pets, using “A photo of a flabelg, a type of pet.” to help provide context worked well. Likewise, on Food101 specifying a type of food and on FGVC Aircraft a type of aircraft helped too. For OCR datasets, we found that putting quotes around the text or number to be recognized improved performance. Finally, we found that on satellite image classification datasets it helped to specify that the images were of this form and we use variants of “a satellite photo of a flabelg.”.</p>

<p><strong>prompt ensembling，多用一些提示的模板，做多次推理然后把结果综合起来，ensemble一般都会得到更好的结果。论文中显示用了80个提示模板做ensemble。</strong></p>

<p>方法部分总结：</p>

<ol>
  <li>数据集</li>
  <li>怎么选择模型</li>
  <li>怎么做预训练</li>
  <li>怎么做zeroshot推理</li>
</ol>

<p>到这里，结果已经很好了，加上点讨论，加上个结论就是个八页的中规中矩的论文投稿，但是作者又做了十页的效果展示：</p>

<p>在27个数据集上，衡量了CLIP做zeroshot的迁移的效果，如图所示：</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278675.jpg" alt="" /></p>

<p>Zero-Shot CLIP</p>

<p>Linear Probe on ResNet50作为基线：冻住预训练好的模型的主干，只用它抽特征，就训练最后一层的FC分类头层去做有监督的分类任务。这里的res50是用有监督的方式训练好的一个模型，从中去特征，然后在这些下游任务上去添加新的分类头，然后在这个新的分类头上去做linear probe的微调</p>

<p>绿色的都是相比于基线的提升</p>

<p>蓝色的是相比于基线的性能降低</p>

<ul>
  <li>证实了zeroshot的这种迁移，也是有效的，是可以广泛进行应用的，而不是光在imagenet或者某些数据集上有用</li>
  <li>对于普通的给物体进行分类的数据集来说，CLIP一般都表现的比较好。因为图片中有可以描述的物体，那么对应的文本中应该也有这个物体的描述，所以图文就会匹配的非常好，CLIP模型也会对这些物体非常敏感。但是对于更难的一些任务，更难的一些数据集，比如DTD这种对纹理进行分类的数据集对于CLIP来说就非常难，非常抽象了，所以CLIP的表现就不好，因为对于难的任务来说，如果不给任何标签信息，这也有点强人所难了。文中讲到，对于特别难的任务，如果只做zeroshot的迁移，可能不太合理，有可能做fewshot的迁移会更合理，难任务比如给肿瘤分类，这种需要特定领域知识的任务，即使是对于人来说，如果没有先验知识，人类也是没法分类正确的。</li>
</ul>

<p><strong>证明对于更难的数据集，fewshot会比zeroshot的衡量更合理</strong>01:06:25 few shot</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305278676.jpg" alt="" /></p>

<ul>
  <li>横坐标表示每个类别里用了多少训练样本</li>
  <li>纵坐标是平均的分类准确度（27个数据集的其中20个数据集上的平均）</li>
</ul>

<p>zeroshotCLIP：0个训练样本，别的方法因为没有和NLP结合所以没法做zeroshot，所以最低也得从oneshot开始</p>

<p>fewshotCLIP：预训练之后冻住模型参数，只从里面抽特征做这种linear probe，训练最后的分类头，所以需要下游数据集里有这种有标签的数据</p>

<p>1、linear probe CLIP：把CLIP的图片编码器冻住做linear probe</p>

<p>2、之前的方法：BiT-M、SImCLR、resnet50。</p>

<p>观察到的几个有趣的结论：</p>

<ol>
  <li>蓝色曲线：BiT是为迁移学习量身定做的，算是迁移学习或者说fewshot迁移学习里，表现最好的工作之一，也是在很大的数据集imagenet21k上做的预训练，是一个很强大的baseline。但是我们可以看到zeroshotCLIP，不用任何训练样本，直接和最好的bit达成平手，可见利用自然语言的威力。</li>
  <li>紫色曲线：对CLIP的图片编码器，做fewshot的linear probe。我们可以发现，当训练样本只有1、2、4的时候，这种用了训练样本的fewshot方式还不如直接zeroshot的CLIP。也再次证明了用文本做引导的多模态学习是多么的强大。</li>
  <li>随着训练样本的增加，fewshot学习的CLIP模型效果最好。不仅超过了之前的方法，验证了CLIP模型的强大，同时还超越了zeroshotCLIP，验证了作者的说法：对于难的数据集来说，有一些训练样本还是非常有必要的。</li>
</ol>

<p><strong>下游任务用全部的数据，CLIP的效果会如何？</strong>01:09:49</p>

<p>3.2节做了这个实验，之所以命名为表征学习，因为之前不论是无监督还是自监督的表征学习，都是先预训练一个模型，然后在下游任务上用全部的数据去做微调的。所以如果这里用上了全部的数据，那么就可以和之前特征学习的方式去做公平对比了。</p>

<p>如果下游任务用全部数据，那就用很多方式去衡量模型学到的特征好不好，最常见的两种方式：</p>

<ol>
  <li>linear probe：把预训练好的模型冻住，在上面再训练一个分类头，</li>
  <li>finetune：把整个网络都放开，去做端到端的学习。微调一般是更灵活的，而且在下游任务数据集比较大的时候，微调往往是比linear probe的效果好很多的</li>
</ol>

<p>在本文中，作者选用了linear probe而不是微调，原因如下：</p>

<ol>
  <li>CLIP这种工作就是为了研究和数据集无关的预训练方式的，如果下游数据集足够大，整个网络放开在这个数据集上做微调的话，很有可能预训练的模型并不好，但是在微调的过程中经过不断地优化，最后的效果也很好，这样就不能判断预训练的模型到底好不好了。而linear probe的方式就不太灵活，整个网络大部分是冻住的，只有最后一层fc可以训练，可学习的空间就比较小，所以如果预训练的模型没有训练好，即使在下游任务上训练的再久，也很难优化到一个特别好的结果</li>
  <li>因为linear probe不太需要调参，CLIP这篇论文做了大量的实验，涉及了大量的数据集，如果做端到端的微调，就会有太多可以调的超参和设计方案了。比如如果下游数据集特别大，而且数据标注质量也比较高的话，就会希望学习率大一点，因为想要这个预训练模型尽可能的去拟合下游的数据集；如果下游任务的数据集特别小，可能就需要特别特别小的学习率，因为可能稍一学习模型就过拟合了。总之就是要为每个数据集量身定做，得在各个数据集上去搜集超参数，才能在各个数据集上表现好一点。如果是linear probe因为模型主体已经冻住了，只是抽特征，唯一要学习的就是最后的分类层，所以可以调的参数非常少，所以不论是什么数据集什么任务，只要是分类，整个测试的流程就是一个正规化的流程。</li>
</ol>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">对比学习论文综述【论文精读】</title><link href="https://wang-akang.github.io/study/2025/06/17/title.html" rel="alternate" type="text/html" title="对比学习论文综述【论文精读】" /><published>2025-06-17T00:00:00+00:00</published><updated>2025-06-17T00:00:00+00:00</updated><id>https://wang-akang.github.io/study/2025/06/17/title</id><content type="html" xml:base="https://wang-akang.github.io/study/2025/06/17/title.html"><![CDATA[<hr />

<p>对比学习在计算机视觉领域的发展历程，4个阶段：</p>

<ol>
  <li>百花齐放：方法、模型、目标函数、代理任务都还没有统一。</li>
  <li>CV双雄：MOCOv1、SimCLRv1、MOCOv2、SimCLRv2、CPC和CMC的延伸工作、SwaV，这个阶段发展非常迅速，以上这些工作间隔时间都很短，ImageNet上的最好成绩，基本上每个月都在被刷新。</li>
  <li>不用负样本：BYOL及其后续改进，SimSima把所有方法都归纳总结，融入到SimSima框架之中，算是卷积神经网络做对比学习的总结性工作。</li>
  <li>transformer：MOCOv3、DINO，用vision transformer开展工作。</li>
</ol>

<p>阶段一：百花齐放 18年-19年中</p>

<p>01:51instdisc：提出了代理任务：个体判别任务。</p>

<p>就是MOCO中反复提到的文献61，如果MOCO是一篇里程碑式的工作，那么InstDisc就是巨人的肩膀，就是MOCO提到的memory bank方法的论文。</p>

<p>创新点：用个体判别+NCEloss，做对比学习，取得了不错的无监督表征学习的结果。同时它还提出了用别的数据结构，去存大量的负样本。以及如何对特征进行动量的更新。</p>

<p>对后来的对比学习的工作气到了至关重要的推进作用。</p>

<p><strong>图1，动机</strong> 受到有监督学习结果的启发：让相似图片聚集在一起的原因并不是他们有相似的语义标签，而是图片确实长得太像了。基于此提出了个体判别任务，这种无监督学习方式，就是把按类别走的有监督信号推到了极致，就是把每个instance（图片）都看成一个类别，目标是能学一种特征，让我们能把每一张图片都区分开。</p>

<p><strong>图2，方法</strong> 简单来说就是想通过一个CNN把图片都编码成一个特征，希望这个特征能在最后的特征空间中尽可能的分开（每个图片都是自己的类）；训练CNN：对比学习，正样本是图片本身，负样本是数据集中所有其他的图片（用memory bank存放大量的负样本）</p>

<p><strong>前向过程：</strong></p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508753.jpg" alt="" /></p>

<p>bs：256（256个图片输入，也是正样本）</p>

<p>编码器：res50（生成2048维度的特征）</p>

<p>降维：128维（每个图片的特征大小）</p>

<p>负样本：从memory bank中随机抽（文中抽了4096个负样本）</p>

<p>用NCEloss去算对比学习的目标函数，一旦更新完网络，就用这个minibatch中的数据样本所对应的特征，去更换原来memory bank中的特征，这样memory bank就得到了更新。反复这个过程，不停的更新memory bank，让最后学到的特征尽可能的有区分性。</p>

<p>3.3. Proximal Regularization</p>

<p>给模型训练加了一个约束，让memory bank中的特征进行动量式的更新</p>

<p>4.2 实验超参数的设定</p>

<p>算loss的时候，温度设置是0.07，选了4000个负样本，训练200个epoch，bs是256，起始的lr是0.03（MOCO延续了这些超参数的设定）</p>

<p>07:05InvaSpread：可以看做SimCLR的前身，没有使用额外的数据结构去存储大量的负样本，正负样本来自同一个minibatch，而且只用一个编码器进行端到端的学习。</p>

<p>端到端学习、一个编码器、不需要外部数据结构去存储大量的负样本、正负样本来自同一个minibatch。</p>

<p>没有TPU，所以bs设置为256，负样本数量只有（256-1）×2个；缺少SimCLR强大的数据增广；SimCLR提出的mlp projector；所以效果不如SimCLR。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508750.jpg" alt="" /></p>

<p>对比学习的思想：同样的图片通过编码器，特征应该很类似，不同的图片特征应该不类似。</p>

<p>Invariant：相似的图片，特征应该保持不变性</p>

<p>Spreading：不相似的图片和物体，特征应该尽可能的分散开</p>

<p>具体做法：</p>

<ul>
  <li>代理任务：个体判别</li>
  <li>正负样本的选取：</li>
</ul>

<p>根据前向过程：</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508778.jpg" alt="" /></p>

<ol>
  <li>256张图片经过数据增强，又得到了256张图片。正样本是当前图片数据增强后对应的图片，其余所有图片都是负样本（包括原始图片和经过数据增强后的图片）对于一个batch来说，正样本：256，负样本：（256-1）×2。【和InstDisc不同，InstDisc正样本256，但负样本是从一个memory bank中抽出来的，负样本是4096，甚至可以更大】为了能用一个编码器做端到端的训练，本文从同一个minibatch中选正负样本。【这就是MOCO中讲到的端到端的学习方式】</li>
  <li>编码器+FC（降维），相似的特征在特征空间中尽可能的接近，与其他的特征应该尽可能的拉远。目标函数式NCEloss的变体。</li>
</ol>

<p>10:33CPC：contrastive predivtive coding，一个可以处理音频、图片、文字还可以使用在强化学习中的通用模型。用预测的代理任务做对比学习。</p>

<p>【机器学习：判别式模型和生成式模型】</p>

<p>个体判别任务：前两个工作都是判别式的代理任务</p>

<p>预测型的任务：最常见的生成式的代理任务</p>

<p>输入：音频信号</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508751.jpg" alt="" /></p>

<p>大概想法：有一个持续的序列，把之前时刻的输入给编码器，得到一些特征，把这些特征喂给一个自回归的模型（auto regression，常见的自回归模型就是RNN、LSTM），得到红色的方块（context representation一个代表上下文的特征表示），如果这个上下文的特征表示足够好，就是它真的包含了当前和之前所有的信息的话，那它应该可以做出一些合理的预测，用它来预测未来时刻的特征输出。对比学习体现在：正样本是未来时刻的特征输出，预测的特征是query，真正未来时刻的输出是由输入决定的。负样本的定义很广泛，比如，可以任选输入，通过编码器得到输出，那预测应该是不相似的。这套思想是很普适的，输入可以换成句子，用前面的单词去预测后面的单词的特征的输出；可以换成一系列的图片patch，左上到右下，可以用上半部分的图片特征预测下半部分的图片特征。</p>

<p>13:05 CMCccontrastive multiview coding</p>

<p>本文定义正样本的方式很广泛，一个物体的多个视角都可以被当做正样本。</p>

<p>第一个做多视角的对比学习，不仅证明了对比学习的灵活性，也证明了多视角、多模态的可行性。【接下来OpenAI就出了clip模型：如果有一个图片以及描述它的文本，这就是一个正样本对，用来做多模态的对比学习】</p>

<p>摘要精彩：人类观察世界是通过多个传感器的，眼睛、耳朵都充当不同的传感器，给我们的大脑提供不同的信号，每个视角都是带有噪声而且带有噪声的，但是最重要的那些信息是在所有视角中共享的，比如基础的物理定律、几何形状、语义信息都是共享的。例：狗既可以被看见，也可以被听见和感受到。基于这个现象，作者提出，我们想要学习一个非常强大的特征，它具有视角不变性。CMC的目的就是增大所有视角的互信息。如果能学习到一个特征，能抓住所有视角下的关键因素，这个特征就很好了。</p>

<p>正负样本的定义：</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508919.jpg" alt="" /></p>

<p>数据集：NYU RGBD，有四个视角，原始图像、深度信息（距离观察者的远近）、surface normal（表面法线）、物体的分割图像</p>

<p>正样本：虽然不同的输入来自不同的传感器，或者来自不同的模态，但是所有的输入都对应的一个东西，他们就应该互为正样本，也就是，绿色的点在特征空间中应该非常接近。</p>

<p>负样本：如果随机选择一张图片，不配对的，得到的特征就应该远离。</p>

<p>局限性：在处理不同视角/模态的时候，可能需要不同的编码器，因为不同的输入可能长得很不一样，这样计算代价就会高。比如在CLIP中，文本端用的是bert，图像用的是vit。transformer有可能同时处理不同模态的数据【MA-CLIP: Towards Modality-Agnostic Contrastive Language-Image Pre-training 用一个transformer同时处理两个模态，效果反而更好】不用针对每个数据去做特有的改进。</p>

<p>第一阶段的四篇论文，使用的代理任务不同（个体判别、预测未来、多视角多模态）、目标函数不同（NCE、InfoNCE、NCE的其他变体）、模型不同（InvaSpread仅用一个编码器、InstDisc用一个编码器和memory bank、CPC是一个编码器和一个自回归模型、CMC有两个甚至多个编码器）任务不同（图像、视频、音频、文字、强化学习）</p>

<p>18:12阶段二：CV双雄19年中-20年中</p>

<p>CV双雄指的就是MOCO和SimCLR</p>

<p>18:36 MoCo</p>

<p>主要贡献：把之前的对比学习方法归纳总结成一个字典查询的问题。提出队列和动量更新的编码器构造一个又大又一致的字典，能帮助更好的对比学习。</p>

<p>实现上和InstDisc非常相似，可以说是它的一个改进工作。但是改进简单有效，而且有很大的影响力，这个动量编码器的改进一直沿用到了最新的工作，带来好的效果。</p>

<p>另外moco的写作也很精彩，自顶向下：并没有按照传统简单直白的写作方式，先对比过去的工作，谈局限性，然后提出自己的方法。</p>

<p>而是：引言中，第一段写CV和NLP的区别，以及到底为什么无监督学习在CV这边做的不好；第二段开始讲对比学习，直接把对比学习的方法总结成一个字典查找的问题；然后在CV和NLP大一统、对比学习被看做字典查找也大一统的大框架下，提出了MOCO这个框架，希望能用一个又大又一致的字典，去整体的提高对比学习的性能。</p>

<p>方法部分，没有模型总览图、没有说模型、任务。而是从目标函数入手，说我们用的是InfoNCE，先定义正负样本，然后网络结构，然后实现细节和伪代码。3.1中，为了让MOCO看起来更普适，没有直接定义输入是什么，也没有定义网络结构是什么样</p>

<p>什么样的输入都可以（图片、图片块CPC、上下文的图片块）</p>

<p>网络：query和key的编码器既可以相同（InvaSpread）、部分共享和完全不同的（CMC多个视角所以多个编码器）</p>

<p>23:07 SimCLRsimple contrastive learning ICML</p>

<p>介绍对比学习常用SimCLR当例子，因为它概念上更容易理解，方法也很容易解释，只不过就是bs太大，一般人不好上手。</p>

<p>方法：</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508756.jpg" alt="" /></p>

<ul>
  <li>x：一个minibatch的图片。</li>
  <li>xi和xj：x经过不同的数据增强，他俩就是正样本。正样本个数就是bs，负样本就是剩下的样本以及他们数据增强后的样本2（bs-1）。</li>
  <li>f函数：是编码器，两个编码器共享权重。</li>
  <li>h：编码器得到的特征。</li>
  <li>g函数：projector，就是一个全连接层跟着一个relu的激活函数。（就是这么的一个简单的错做，能让最后学到的特征在imagenet这个分类任务上提10个点）。只有在训练的时候用，做下游任务的时候，只用特征。这个g函数只是为了让模型训练的更好，为了公平对比在下游任务上不使用。</li>
  <li>最后衡量（名为normalized temperature-scaled的交叉熵函数：normalized是指在特征后面做了L2归一化，temperature-scaled：在loss上乘一个τ）正样本之间是否能达到最大一致性。</li>
</ul>

<p>前向过程：图片进入编码器编码，然后projector降维，最后算一个对比学习的loss。</p>

<p>SimCLR和InvaSpread的区别：</p>

<ol>
  <li>SimCLR用了更多的数据增强（<strong>裁剪、改变色彩</strong>、旋转、cutout、高斯噪声、高斯模糊、sobel滤波器）</li>
  <li>加了一个g函数（可学习的非线性变换），就是一个MLP层。</li>
  <li>用了更大的bs，而且训练的时间更久</li>
</ol>

<p>SimCLR框架中几乎所有单独的组件都出现在以前的工作中，尽管具体的实现可能有所不同。但SimCLR的优势不是任何单一设计的选择，而是把所有的技术结合起来得到的结果。我们提供了一个全面的比较，非常详细的消融实验，在附录C。</p>

<p>SimCLR中提出的很多技术，都对后续的工作产生了长远的影响：</p>

<ol>
  <li>在编码器之后加一个MLP层（MOCOv2，BYOL）</li>
  <li>数据增强技术</li>
  <li>用LARS优化器去做大bs的模型训练（BYOL）</li>
</ol>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508752.jpg" alt="" /></p>

<ul>
  <li>Linear：不要relu，只要一个全连接层</li>
  <li>Non-Linear（projection head）：加了relu激活层，把线性函数变成非线性了</li>
  <li>None：就像MOCO和InvaSpread，直接拿编码器出来的特征去做对比学习</li>
</ul>

<p>可以发现：Non-Linear提点效果非常显著；特征维度的大小效果没什么区别，选128就够了。</p>

<p>31:03MOCOv2 CV的会议</p>

<p>因为moco和SimCLR的效果实在太好，2020年就掀起了对比学习的狂潮。直到2020年底，vision transformer出来以后才逐渐消退。</p>

<p>发现SimCLR的效果很好，技术都是即插即用型。就在MOCO上做很简单的改动：把MLP projection head和更多的数据增强用起来，就刷新了imagenet上的最好成绩，比过了SimCLR。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508758.jpg" alt="" /></p>

<p>具体改进如表1：加了MLP层、更多数据增强、训练的时候用了cosine learning rate schedule、训练更长的epoch</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508755.jpg" alt="" /></p>

<p>MOCO非常省内存只需要5个G，而且训练只需要53个小时（imagenet这种规模的数据集上，两天多已经算很快了）</p>

<p>端到端（InvaSpread、SimCLR）：SimCLR在小bs的时候效果远不如MOCOv2（因为字典不够大，负样本不够多，导致对比学习的对比不是很有效，而且不仅效果低内存占用也明显高，训练时长也长了十几个小时，端到端要性能差不多bs就要4096，这对硬件要求太高了）</p>

<p>36:20 SimCLRv2 Neural IPS</p>

<p>Big Self-Supervised Models are Strong Semi-Supervised Learners</p>

<p>非常大的自监督模型非常适合去做半监督学习</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508781.jpg" alt="" /></p>

<ol>
  <li>第一部分：SimCLRv2，怎样自监督或自监督的对比学习，去训练一个大的模型出来。</li>
  <li>第二部分：一旦有了一个很好的模型，只需要一小部分有标签的数据，去做一下有监督的微调。</li>
  <li>第三部分：微调结束了就相当于有了一个teacher模型，就可以用这个teacher模型去生成很多伪标签，这样就可以在更多的无标签数据上做自学习了。</li>
</ol>

<p>我们要看的是第一部分，看作者怎么把SimCLR改进了。</p>

<ol>
  <li>用更大的模型，无监督训练就会训练的更好。（152层的残差网络，selective kernels网络，骨干网络变得非常强）。</li>
  <li>SimCLR证明了projection head很有用（fc relu），那么变深可能会更有用，经过验证发现两层就够了（fc relu fc relu）。</li>
  <li>动量编码器在SimCLR就提升了一个点，可能是因为它本身已经有很大的bs了（4096或8192），负样本已经相当多了。</li>
</ol>

<p>40:30SwAV</p>

<p>Unsupervised Learning of Visual Features by Contrasting Cluster Assignments</p>

<p>给定同一张图片，如果去生成不同视角的话，希望可以用一个视角得到的特征去预测另一个视角得到的特征，因为所有视角得到的特征应该都是非常接近的。</p>

<p>本文方法：对比学习+聚类。</p>

<p>聚类也是一种无监督表征方式，希望相似的物体都聚集在某一个聚类中心，不相似的物体尽量推开到别的聚类中心，所以和对比学习的方法也比较接近。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508913.jpg" alt="" /></p>

<ol>
  <li>左边是过去的对比学习方法：图片经过不同的数据增强，通过编码器得到特征，然后对特征做一个对比学习的loss。</li>
  <li>右边是SwAV：认为特征和特征作对比，有点费资源，因为每个图片都是自己的类，那么剩下的都是负样本，负样本太大只能取近似，能不能不做近似？能不能借助一些先验信息，不去和大量的负样本比，而去跟一些更简洁的东西比呢？</li>
</ol>

<p>去跟聚类中心比，就是右图中的 prototypes C（矩阵，维度是D×K，D是特征的维度，K聚类中心的个数）</p>

<p>前向过程：一个minibatch的图片，做两次数据增强，分别通过编码器得到两个特征，让特征和prototype C去生成一个目标，也就是Q1和Q2（相当于ground truth）。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508748.jpg" alt="" /></p>

<p>Swapped prediction：按道理x1和x2是同一张图片，他们是一对正样本，那么生成的特征应该很相似，Z1·C可以预测Q2，点乘的结果就是预测；ground truth就是聚类分类得到的Q1和Q2。通过换位预测的方法，SwAV可以对模型进行训练。</p>

<p>用聚类的好处是什么？</p>

<ol>
  <li>如果要和很多的负样本作类比，可能就需要成千上万的负样本，即使如此，也只是个近似。而现在如果只是和聚类中心对比，用几百甚至3000个聚类中心就足以表示了，因为其实也并没有那么多类，imagenet也就1000类，COCO才80类，所以3000个聚类中心就足够用了，这相当于几万个负样本来说，是小了很多的。</li>
  <li>这些聚类中心是有明确的语义含义的，之前只是随机抽样负样本做对比的话，可能类别不均衡甚至可能是个正样本的，所以不如使用聚类中心有效。</li>
</ol>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508780.jpg" alt="" /></p>

<p>不仅比之前讲过的方法效果好，还要比接下来要讲的BYOL和SimSiam效果都要好。算是卷积神经网络里，用res50分刷的最高的一篇工作了。</p>

<p>对比做的是imagenet上的Linear classification，就是提前预训练好的模型，冻住主干网络，只训练最后的分类头（MLP层）。前六个不是对比学习的方法，结果都比较低。有了对比学习开始，MOCO就开始上60了。</p>

<p>SwAV是把主干网络冻住情况下做的，都已经非常逼近从头到尾都在imagenet上训练的有监督基线模型。</p>

<p>右图是只把res50变宽，SwAV的结果还能不停的涨。当用5倍的模型的时候，SwAV的结果已经和有监督的模型差距非常小。</p>

<p>SwAV的性能这么好的原因：</p>

<ol>
  <li>和聚类的方法融合。</li>
  <li>multi-crop：一个trick。之前的对比学习方法用的是两个crop，就是一个正样本对就是两个图片x1和x2，如图所示，图片先resize到256<em>256，然后随机crop两个224</em>224的图片当成x1和x2，因为两张图片都非常大，所以重叠的区域也非常多，他们代表一个正样本，总之就是两个crop。这么大的crop抓住的是整个场景的特征，如果想学习局部物体的特征该怎么办？</li>
</ol>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508749.jpg" alt="" /></p>

<p>所以最好能多个crop，就能关注到局部的物体了。但是增加crop（文中的view）模型的计算复杂度一下就提高了，相当于使用了更多的正样本，如何能使用更多的正样本，而又不增加更多的计算成本？</p>

<p>方法：把crop变小，取两个较大的crop争取学到全局特征，然后为了增加正样本的数量，为了学习局部特征，再去随机选4个小一点的crop。正样本数量增多了，但是通过取舍，整体的计算代价是差不多的。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508779.jpg" alt="" /></p>

<p>这个multi-crop技术很有用，而且不仅对SwAV有效。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508782.jpg" alt="" /></p>

<p>如图，基线模型就是2*224，用了multi-crop技术的效果。</p>

<ul>
  <li>SimCLR涨了2.4个点。</li>
  <li>聚类的方法用了这个技术，提点效果更显著。</li>
</ul>

<p>如果不用multi-crop这个技术，SwAV的效果和mocov2是差不多的，也就是说一个纯聚类的方法，或者聚类和对比学习结合的方法，其实并没有什么优势，真正提点的是multi-crop这个技术，而且这个技术非常普适，思想也很简单，就是全局和局部的特征都要关注。所以接下来的很多工作借鉴的都是multi-crop这个技术，而不是SwAV这篇工作本身。</p>

<p>50:03</p>

<ul>
  <li>CPCv2：用了更大的模型、用了更大的图像块、做了更多方向上的预测任务、把BN换成了LN、使用了更多的数据增强</li>
  <li>infoMin：What Makes for Good Views for Contrastive Learning，到底选择什么样的视角才能对对比学习更好。infomin原则：最小化互信息，以前都是最大化互信息，都是想要两个视角之间的互信息达到最大，本文是想要恰好合适的互信息，如果最后互信息比你所需要的互信息要多，那也是一种浪费，而且有可能泛化做的不好。如果互信息比需要的少，可能就达不到最优的性能。所以作者的意思就是，不能一味的最大化互信息，而是要不多不少刚刚好，按照infomin的原则，去选择合适的数据增强，然后拿到合适的对比学习视角，作者发现对于很多的方法都有提升。</li>
</ul>

<p>第二阶段，很多细节已经趋于统一了</p>

<ul>
  <li>目标函数都是infoNCE或者其变体</li>
  <li>模型都是用一个编码器后面加一个projection head</li>
  <li>更强的数据增强</li>
  <li>动量编码器</li>
  <li>训练的更久</li>
  <li>准确度逐渐逼近有监督的基线模型</li>
</ul>

<p>52:07第三阶段：transformer，不用负样本的对比学习。</p>

<p>第二阶段讲的SwAV已经有这个趋势了，算是承上启下的工作，因为他也没有用负样本，用的是聚类中心，但还是有一个明确的对比的对象的。但这个阶段的工作，已经没有负样本或者聚类中心了，就是正样本自己在玩。</p>

<p>52:34BYOL：自己跟自己学</p>

<p>Bootstrap Your Own Latent</p>

<p>A New Approach to Self-Supervised Learning</p>

<ul>
  <li>Bootstrap：在一定基础上改造</li>
  <li>Latent/hidden/feature/embedding：特征</li>
</ul>

<p>为什么不用负样本这么新奇？</p>

<p>因为在对比学习中负样本是一个约束，在算目标函数的时候，只有正样本，那么目标只有一个：让所有相似的物体的特征也尽可能的相似，这时候就有一个很明显的捷径解，就是说如果一个模型，不论什么样的输入，都会返回相同的输出，那么出来的所有特征都是一模一样的，那这个去算对比学习的loss就都是0，意思就是模型直接躺平了根本不用学，直接用这个捷径解trivial solution，就能完美解决你的问题。只有加上负样本这个约束，不光相似的物体要有相似的特征，不相似的物体要有不相似的特征，这样模型才有动力继续学，因为如果输出的所有特征都一样，那么负样本这边loss就无穷大，所以模型必须想办法让正样本和负样本的loss都往下降，达到一个最优解。所以负样本在对比学习里是个必须的东西，能防止模型学到这个捷径解（model collapse或learning collapse）。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508912.jpg" alt="" /></p>

<p>前向过程：</p>

<ul>
  <li>一个minibatch的输入x</li>
  <li>经过两次的数据增强后得到了v和v’</li>
  <li>通过编码器得到特征，两个编码器使用同样的架构，但是参数不同，上侧的参数随梯度更新而更新，下侧编码器用动量更新的方式更新参数</li>
  <li>projection head，通过g函数来降维，网络结构相同参数不同，下侧动量更新。得到两个特征。</li>
  <li>BYOL在上侧加了一个层（MLP）得到一个新的特征。让这个新的特征和下侧特征尽可能一致，把一个匹配问题变成了一个预测问题。（和SwAV有点像，就是换成预测问题，但是借助了聚类中心去帮助做预测任务）相当于用一个视角的特征去预测另一个视角的特征。通过这种预测性的任务去完成模型的训练。</li>
</ul>

<p>代理任务是对比学习为了预训练模型所定义的任务，为了训练模型。</p>

<ul>
  <li>个体判别任务：自成一类，让两个特征尽可能接近。</li>
  <li>预测型的任务：预测对比</li>
</ul>

<p>和其他工作同样的，训练完成之后只留下编码器，用上侧一次编码的特征yθ去做下游任务</p>

<p>目标函数：MSE loss，让预测的特征和下侧的特征尽可能的接近。</p>

<p>58:23博客复现BYOL，因为BN的一个细节复现不出来</p>

<p>SimCLR的projection head的细节：fc bn relu fc bn第一个全连接层2048<em>2048，第二个全连接层2048</em>128就把维度降下去了，这个128的特征就是最后用来做对比学习的那个特征。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508754.jpg" alt="" /></p>

<p>MOCOv2的projection head细节：fc relu fc 2048<em>2048→2048</em>128</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508746.jpg" alt="" /></p>

<p>BYOL的projection head细节：fc BN relu fc 2048<em>2048→2048</em>128</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508757.jpg" alt="" /></p>

<p>这篇博客复现借鉴了写的非常漂亮的MOCOv2代码，MLP中少了一个BN，模型的学习就坍塌了</p>

<p>projection MLP norm：projector中是否用BN，还是其他归一化方式</p>

<p>prediction MLP norm：训练中是否用BN，还是其他归一化方式</p>

<p>Loss function：目标函数</p>

<p>contrastive：对比</p>

<ul>
  <li>random：随机初始化的残差网络，用这个残差网络抽特征，在特征上训练一个全连接层，最后的结果是28.8。随机结果（没有学习）</li>
  <li>BYOL：如果做的是正确的BYOL，就是在projection head和prediction head中都用了BN，结果是57.7最高。</li>
  <li>no normalization：这是他们做错了的，在projection head和prediction head中都没有用BN，结果只有28.3，就是模型坍塌了什么都没学到</li>
  <li>仅在projection head中用BN，和仅在prediction head中用BN，效果都还可以，说明模型没有坍塌，有在学习。</li>
  <li>如果把projection head和prediction head中的BN换成LN，效果又不行了</li>
</ul>

<p>作者就知道BYOL模型没有坍塌肯定和BN有关系：</p>

<p>注：BN是什么，就是把一个batch里所有样本的特征拿来算均值和方差（running mean和running variance）。然后用这个整个batch算来的均值和方差去做归一化，在算某个样本的loss的时候，其实也看到了其他样本的特征，这里面是有泄露的。MOCO中就做了一个shuffle BN，为了防止信息泄露。</p>

<p>作者说因为BN中有信息泄露，所以你可以把batch里的其他样本想成一种隐式的负样本。换句话说，当你有了bn的时候，BYOL其实并不是只是正样本在自己和自己学，其实也在做对比，BYOL做的对比任务就是：当前正样本的图片，和BN产生的平均图片的差别（这和SwAV的不用负样本而是聚类中心去对比是相似的，就是一种聚类中心的意思）</p>

<p>BYOL的作者就急了，因为如果这么解释的话，BYOL就是还是没有逃脱对比学习的范畴，于是BYOL就做了其他实验证明为什么模型没有坍塌。</p>

<p>01:05:32BYOL works even without batch statistics：BYOL即使没有BN也可以工作，想说明BYOL的成功不是因为BN</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508775.jpg" alt="" /></p>

<p>BYOL是基于SimCLR上做的，这个详细的消融实验，</p>

<ol>
  <li>BN确实比较关键，没有BN的BYOL确实就不学了，但SimCLR还在学</li>
  <li>有一组实验：Projector有BN，BYOL还是训练失败了，这就不能说明BN关键了。因为如果BN能提供隐式负样本的话，这里训练就不应该失败。</li>
  <li>当编码器和Projector都没有BN的时候，SimCLR也失败了，因为SimCLR没有predictor所以无所谓的。说明没有归一化的时候，不光BYOL，SimCLR也不行了，即使用了负样本也训练不出来。这就说明BN不是提供了一个隐式负样本，因为SimCLR提供了显式的负样本也训练不出来。</li>
</ol>

<p>于是BYOL作者和博客作者达成一致：BN跟它原来的设计初衷一样，主要的作用是帮助模型稳定训练，提高模型训练的稳健性，让模型不会坍塌。</p>

<p>BYOL在本文的3.3中给出解释：如果一开始就能让模型初始化的比较好，那么后面的训练即使离开了BN也没问题。</p>

<p>weight standardization ：一种模型初始化的方式</p>

<p>group norm：一种归一化的方式</p>

<p>这两个方法是VIT的原班作者在它们之前的论文BEIT中提出来的，Resnet v2就是用这种方式做训练。</p>

<p>BYOL(+GN+wS) achieves 73.9%：BYOL换上GN和WS之后也能达到用BN的结果，而这两个方法都没有计算batch统计量。所以这个BYOL是没有跟minibatch中的其他样本做对比的，也就是没有隐式对比。说明BYOL还是一个全新的方式，能自己跟自己学就能学的很好。</p>

<p>01:09:35Exploring Simple Siamese Representation Learning，SimSiam对对比学习进行分析，化繁为简</p>

<p>SimSiam</p>

<ol>
  <li>不用负样本，基本上和BYOL很相似</li>
  <li>不需要大的bs</li>
  <li>不需要动量编码器</li>
</ol>

<p>不仅不会模型坍塌，而且效果还很好。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508783.jpg" alt="" /></p>

<p>为什么叫孪生网络：两个编码器网络结构相同且共享参数，整体架构和BYOL非常像，不同只在于SimSiam没有用动量编码器。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508916.jpg" alt="" /></p>

<p>前向过程：得到两个视角之后先过编码器得到特征，然后通过predictor去得到预测，两边都预测，所以是一个对称性的loss：既可以做p1预测z2，也可以做p2预测z1的任务，但因为加了两次，所以要除以2</p>

<p>然后就是梯度回传更新网络</p>

<p>D函数表示loss的计算：MSEloss</p>

<p>结论：之所以SimSiam可以训练，不会模型坍塌，主要就是因为有stop gradient这个操作</p>

<p>做了一个假设：因为有了stop gradient这个操作，所以可以把SimSiam想象成一个expectation-maximization算法。因为有了stop gradient这个操作，这一个训练过程或者说这一套模型参数其实就被人为的劈成了两份，相当于在解决两个子问题，模型的更新也是在交替进行的。</p>

<p>可以理解成一个k-means的聚类问题，Kmeans就是分两步走的，每次先要把所有的点分配给一些聚类中心，分配好了以后再去更新聚类中心，再重复做这个操作。从这个角度说，SimSiam和SwAV就有关系了。如图归纳总结了所有孪生网络的做法</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508928.jpg" alt="" /></p>

<ol>
  <li>SimCLR两边都有梯度回传，做的是一个对比任务</li>
  <li>SwAV也是做对比任务，但并没有跟负样本比，而是和聚类中心比，聚类中心是通过SK算法得到的</li>
  <li>BYOL不是对比任务，加了predictor变成一个预测任务，用左边去预测右边，同时他们还使用了动量编码器</li>
  <li>SimSiam的整个左边和BYOL一模一样，不同的是右边没有用动量编码器而是共享参数了</li>
</ol>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508914.jpg" alt="" /></p>

<p>在imagenet上的Linear classification</p>

<ul>
  <li>只用MOCOv2和SimSiam能用256的bs，其他的工作都要用更大的bs</li>
  <li>SimCLR和MOCOv2都要用负样本，BYOL完全没用，SwAV用的聚类中心</li>
  <li>100epoch的时候SimSiam学的最好，说明学的很快，但是随着训练推进涨幅就小了，动量编码器很好用，很好提点。但是本文主要是把这些trick都拿掉，证明没有这些trick也能训练。</li>
</ul>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508920.jpg" alt="" /></p>

<p>下游任务上，前三个是物体检测，最后一个实例分割（CV人必做的两个下游任务）</p>

<ul>
  <li>针对下游任务的迁移来说，MOCOv2和SimSiam是表现最好的。如果想尝试一些对比学习的工作，会用MOCOv2作为基线模型，因为训练快训练稳而且下游任务迁移的好。</li>
</ul>

<p>01:17:14第四阶段：transformer怎么和对比学习有机结合起来</p>

<p>01:17:23 mocov3An Empirical Study of Training Self-Supervised Vision Transformers 自监督的vision transformer，mocov3只是一种架构，卷积神经网络也可以用vision transformer也可以用。</p>

<p>贡献：做了一个很直接、很小的改动，让自监督的vit训练变得更稳定了</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508917.jpg" alt="" /></p>

<p>mocov3其实相当于mocov2和SimSiam的合体</p>

<p>整体框架：query编码器（backbone+projection head+prediction head，就是BYOL/SimSiam）和key编码器（动量编码器）</p>

<p>目标函数：对称的，既算q2到k1，也算q1到k2，对比学习的loss</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508915.jpg" alt="" /></p>

<p>因为vision transformer的出现，作者就很想把卷积神经网络换成vit，看看自监督学习+vit就能取得NLP那边的成功呢？</p>

<p>实验：把骨干网络从Resnet换成vit，如图是vit自监督训练的训练曲线，作者发现：</p>

<ul>
  <li>当bs比较小的时候，曲线比较平滑，效果也还行</li>
  <li>当bs变大之后，准确度会突然掉下来又恢复，但是就不如原来的高了，最后的准确度也会差很多。按道理说大bs应该会有更好的结果，但是这里大bs的结果却只有69.7</li>
</ul>

<p>如果能解决这个问题，有可能就能使用更大的bs去训练一个更大的vit，从而得到更好的结果。</p>

<p>4.2 针对这个普遍出现的问题，提出一个小trick，非常普适</p>

<p>如何想到的这个解决方式：观察训练的时候每一层的回传梯度的情况（一般网络训练的不好，不知道为什么的时候，一般首先就是要去查梯度）。作者发现每次loss有大幅的震动，导致准确度大幅下降的时候，梯度也会有一个波峰，这个波峰发生在第一层，就是做patch Projection的时候（patch Projection就是vit论文中的第一步，属于tokenization的阶段，就是如何把一个图片打成patch，然后给它一个特征，做法就是：一个可以训练的全连接层）这个可以训练的全连接层，每次梯度都不正常，那还不如不训练。所以作者就尝试把这个MLP冻住，看结果。（就是随机初始化了patch Projection层，然后就冻住，整个训练过程都不变）问题就解决了。</p>

<p>这个trick不仅对mocov3有用，对BYOL也有用（用BYOL的框架，把残差网络换成vit），把patch Projection层冻住也能获得更平滑的训练曲线，获得更好的训练结果。</p>

<p>因为transformer简单扩展性又好，不改它就只能改开始的tokenization阶段，和结尾的目标函数</p>

<p>01:23:12 dinoEmerging Properties in Self-Supervised Vision Transformers</p>

<p>也是自监督训练vit的方式，但是主要卖点在于vit在自监督训练的情况下出现的有趣特性</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508918.jpg" alt="" /></p>

<ul>
  <li>一个完全不用标签信息训练出来的vit，如果把自注意力图拿出来进行可视化的话，会发现它能非常准确的抓住每个物体的轮廓，效果甚至能媲美直接对物体做分割</li>
</ul>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508922.jpg" alt="" /></p>

<p>dino具体做法：延续了BYOL</p>

<p>self-distillation：和BYOL一样自己和自己学</p>

<p>用student去预测teacher</p>

<p>centering：减掉batch样本的均值。为了避免模型坍塌，把整个batch里的样本算一个均值，减掉这个均值。</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508921.jpg" alt="" /></p>

<p>和MOCOv3非常像，前向过程一模一样，目标函数多了一个centering操作防止模型坍塌。</p>

<p>第四阶段，01:25:42c从方法和模型角度上讲，和第三阶段一模一样，主要是融合了transformer</p>

<p>01:26:01 整体过一遍</p>

<p><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750305508760.jpg" alt="" /></p>

<p>第一阶段：</p>

<ul>
  <li>InstDisc提出了个体判别任务，提出用一个memory bank的外部数据结构去存储负样本，从而得到一个又大又一致的字典去做对比学习</li>
  <li>InvaSpread不用外部结构的另一条路，端到端学习。只用一个编码器，从而可以端到端学习，但因为受限于bs太小，所以性能不够好。</li>
  <li>CPCv1提出了infoNCEloss，CPCv1是一个预测型的代理任务，不仅可以做图像，还可以做音频、视频、文字和强化学习，是一个非常全能的结构。</li>
  <li>CMC把两个视角的任务扩展到了多个视角，给接下来的多视角或者多模态的对比学习打下了铺垫。</li>
  <li>deep cluster是基于聚类学习的，当时还没有对比学习</li>
</ul>

<p>第二阶段：</p>

<ul>
  <li>MOCOv1是InstDisc的延伸工作，把memory bank变成一个队列，把动量更新特征变成了动量更新编码器，从而能预训练一个很好的模型。moco也是第一个在很多视觉的下游任务上，让一个无监督预训练的模型比有监督预训练模型表现好的方法。属于使用外部数据结构的。</li>
  <li>SimCLRv1是端到端的延伸性工作，和InvaSpread很像，但是用了很多的技术：加大bs、用了更多数据增强、加了一个Projection head、训练更长时间。所有的技术堆起来，让SimCLR在imagenet上取得了非常好的结果。</li>
  <li>CPCv2，也把这些技术用了一遍，直接比CPCv1在imagenet上的结果高了三十几个点。</li>
  <li>
    <p>CMC把这些都分析了一下，提出了一个infomin的原则：两个视角之间的互信息要不多不少才是最好的</p>
  </li>
  <li>MOCOv2发现这些即插即用的技术效果很好，就拿来用。</li>
  <li>SimCLRv2主要做半监督学习。</li>
  <li>SwAV把聚类学习和对比学习结合起来的一个工作，取得了不错的效果，这个不错的结果主要来自于它提出的multicrop的技术，如果没有这个技术就和mocov2或者SimCLR结果差不多。</li>
</ul>

<p>第三阶段：</p>

<ul>
  <li>BYOL提出处理负样本太麻烦，不要负样本了，不用负样本做对比了。把对比任务变成预测任务，自己跟自己学就行了。目标函数也很简单就是MSEloss就训练出来了</li>
  <li>BN BLOG：说BYOL能工作是因为用BN，BN提供了隐式负样本，所以BYOL才能正常训练而不会模型坍塌。</li>
  <li>BYOLv2：说BN只是帮助了模型训练，如果用另一种方式能提供更好的模型初始化，BYOL不需要BN提供的batch的统计量也可以工作。</li>
  <li>SimSiam总结了之前的工作，因为之前的工作一直在堆技术，堆多了不好分析，领域就不好推进了。所以SimSiam化繁为简提出来一个很简单的孪生网络的学习方法，既不需要大的bs，也不需要动量编码器，也不需要负样本，照样能取得不错的结果。SImSiam提出的假设就是，stop gradient这个操作至关重要，因为有这个操作的存在，SImSiam可以看作是一种EM算法，通过逐步更新的方式避免模型坍塌。</li>
  <li>barlos twins更换了一个目标函数，把之前大家做的对比和预测变成了两个矩阵之间比相似性。但因为是21年3月提出的，很快就淹没在vit的洪流之中。</li>
</ul>

<p>第四阶段：这两个工作都是把骨干网络换成了vit。但是换成vit之后训练不稳定或者不好训练。他们提出了各自的解决方法。两种方法都能有效的提高模型训练的稳健性，防止模型坍塌，让vit用自监督的方式也能训练的很好。</p>

<ul>
  <li>MOCOv3：把patch Projection layer冻住</li>
  <li>DINO：把teacher网络的输出先做一下归一化（centering）</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">李宏毅《机器学习/深度学习》2021课程</title><link href="https://wang-akang.github.io/study/2025/06/11/title.html" rel="alternate" type="text/html" title="李宏毅《机器学习/深度学习》2021课程" /><published>2025-06-11T00:00:00+00:00</published><updated>2025-06-11T00:00:00+00:00</updated><id>https://wang-akang.github.io/study/2025/06/11/title</id><content type="html" xml:base="https://wang-akang.github.io/study/2025/06/11/title.html"><![CDATA[<hr />

<meta charset="utf-8" />

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<style type="text/css">
#wmd-preview{
  max-width: 210mm;
  margin: 0 auto;
}
/* normal start */
body {
  font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, 'Hiragino Sans GB', STHeiti, "Microsoft YaHei", "微软雅黑", 'WenQuanYi Micro Hei', STXihei, "华文细黑", Heiti, "黑体", SimSun, "宋体", Song, sans-serif;
  font-size: 16px;
  line-height: 1.8;
  font-weight: normal;
  color: #2f2f2f;
  word-wrap: break-word;
  word-break: break-word;
}


/* link start */
a:focus {
  outline: thin dotted #333;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

a:hover,
a:active {
  outline: 0;
}
a {
  color: #0088cc;
  text-decoration: none;
}

a:hover {
  color: #005580;
  text-decoration: underline;
}
/* link end */


/* head start */
h1,h2,h3,h4,h5,h6 {
  font-weight: bold;
  text-rendering: optimizelegibility;
}

h1 {
  font-size: 2rem;;
  margin: .8em 0 .6em 0;
}

h2 {
  font-size: 1.5rem;
  margin: .7em 0 .5em 0;
}

h3 {
  font-size: 1.17rem;
  margin: .6em 0 .4em 0;
}

h4 {
  margin: .5em 0 .3em 0;
}

video {
  max-width: 100%;
}

h5 {
  font-size: 0.83rem;
  margin: .5em 0 .3em 0;
}

h6 {
  font-size: 0.67rem;
  margin: .5em 0 .3em 0;
}
/* head end */

.xsj_hr {
    margin: 20px 0;
    border: 0;
    border-top: 1px dashed #2f2f2f;
    border-left: 90px solid transparent;
    border-right: 90px solid transparent;
}

p {
    margin: 1.1em 0 1.6em;
}

pre{
    line-height: initial !important;
    word-wrap: break-word;
    word-break: break-all;
    tab-size: 4;
    white-space: pre-wrap;
    font-family: monospace;
}

kbd{
    display: inline-block;
    padding: 3px 5px;
    font-size: 11px;
    line-height: 10px;
    color: #2f2f2f;
    vertical-align: middle;
    background: #fcfcfc;
    border: solid 1px #2f2f2f;
    border-bottom-color: #2f2f2f;
    border-radius: 3px;
    box-shadow: inset 0 -1px 0 #2f2f2f;
}

address {
  display: block;
  margin-bottom: 20px;
  font-style: normal;
  line-height: 20px;
}


small {
  font-size: 85%;
}

strong {
  font-weight: bold;
}

em {
  font-style: italic;
}

cite {
  font-style: normal;
}


/* list start */
ul,ol {
  padding: 0;
  margin: 1.1em 0 1.1em 3em;
}

ul ul,
ul ol,
ol ol,
ol ul {
  margin-top: 0;
  margin-bottom: 0;
  margin-left: 1em;
}
/* list end */

dl {
  margin-bottom: 20px;
}

dt,
dd {
  line-height: 20px;
}

dt {
  font-weight: bold;
  line-height: 1.35em;
}

dd {
  margin-left: 10px;
  line-height: 1.35em;
}
abbr[title],
abbr[data-original-title] {
  cursor: help;
  border-bottom: 1px dotted #999999;
}

/* normal end */


/* blockquote start */
blockquote {
  padding: 20px 20px;
  margin: 20px 0 20px;
  border-left: 5px solid rgba(153, 153, 153, 0.2);
  background: rgba(204, 204, 204, 0.2);
}

blockquote p {
    margin: 1.1em 0 1.1em;
}

blockquote>ol.markdown_ol, blockquote>ul.markdown_ul{
  margin-left: 1.1em;
}

blockquote>*:first-child {
  margin-top: 0;
}

blockquote>*:last-child {
  margin-bottom: 0;
}

blockquote small {
  display: block;
  line-height: 20px;
  color: #999999;
}

blockquote small:before {
  content: '\2014 \00A0';
}

blockquote footer{
    margin: 1em 0;
    font-style: italic;
}

blockquote footer cite {
    margin: 0 1em;
}

/* blockquote end */

/**
 * Treeview syntax highlighting based on highlight.js
 * Copyright (c) 2014-2015, Asciidocfx Team, (MIT Licensed)
 * https://github.com/asciidocfx/highlight-treeview.js
 */
.language-treeview.hljs{
  position: relative;
}
.hljs-folder,
.hljs-hiddenfile,
.hljs-file {
    position: relative;
    vertical-align: top;
    display: inline-block;
    height: 16px;
}
.hljs-folder:before,
.hljs-file:before,
.hljs-hiddenfile:before {
    top: 0;
    content: '';
    width: 14px;
    height: 12px;
    margin-top: 0px;
    margin-right: 3px;
    position: relative;
    display: inline-block;
    background-size: 14px;
    background-repeat: no-repeat;
}
.hljs-file:before,
.hljs-hiddenfile:before {
    height: 14px;
    margin-left: 1px;
}
.hljs-hiddenfile {
    opacity: 0.6;
}
.hljs-file.photo:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c5";
}
.hljs-file.plain:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f016";
}
.hljs-file.source:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c9";
}
.hljs-file.archive:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c6";
}
.hljs-file.audio:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c7";
}
.hljs-file.video:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c8";
}
.hljs-file.pdf:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c1";
}
.hljs-file.xls:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c3";
}
.hljs-file.doc:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c2";
}
.hljs-file.ppt:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f1c4";
}
.hljs-folder:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f114";
}
.hljs-hiddenfile:before {
    font: normal normal normal 14px/1 FontAwesome;
    content: "\f016";
}
.hljs-tvline {
    margin-left: 6px;
    position: absolute;
    text-indent: -99em;
    padding-bottom: 8px;
    vertical-align: top;
    display: inline-block;
    border-left-width: 1px;
    border-left-style: solid;
    border-left-color: rgb(94, 144, 117);
}
.hljs-folder-branch {
    width: 8px;
    height: 8px;
    margin-top: -1px;
    margin-left: 6px;
    text-indent: -99em;
    position: relative;
    vertical-align: top;
    display: inline-block;
    border-bottom-width: 1px;
    border-bottom-style: solid;
    border-bottom-color: rgb(94, 144, 117);
}
.hljs-folder-branch.win {
    width: 14px;
    margin-right: 2px;
}
.hljs-folder-last-branch {
    height: 7px;
    width: 7px;
    margin-left: 6px;
    text-indent: -99em;
    position: relative;
    vertical-align: top;
    display: inline-block;
    border-bottom-width: 1px;
    border-bottom-style: solid;
    border-bottom-color: rgb(94, 144, 117);
    border-left-width: 1px;
    border-left-style: solid;
    border-left-color: rgb(94, 144, 117);
}
.hljs-folder-last-branch.win {
    width: 13px;
    margin-right: 2px;
}


/**
 * Treeview syntax highlighting based on highlight.js
 */

/*wavedrom start*/

.wavedrom_svg text, .wavedrom_svg_defs text {
    font-size:11pt;
    font-style:normal;
    font-variant:normal;
    font-weight:normal;
    font-stretch:normal;
    text-align:center;
    fill-opacity:1;
    font-family:Helvetica
}
.wavedrom_svg .muted, .wavedrom_svg_defs .muted {
    fill:#aaa
}
.wavedrom_svg .warning, .wavedrom_svg_defs .warning {
    fill:#f6b900
}
.wavedrom_svg .error, .wavedrom_svg_defs .error {
    fill:#f60000
}
.wavedrom_svg .info, .wavedrom_svg_defs .info {
    fill:#0041c4
}
.wavedrom_svg .success, .wavedrom_svg_defs .success {
    fill:#00ab00
}
.wavedrom_svg .h1, .wavedrom_svg_defs .h1 {
    font-size:33pt;
    font-weight:bold
}
.wavedrom_svg .h2, .wavedrom_svg_defs .h2 {
    font-size:27pt;
    font-weight:bold
}
.wavedrom_svg .h3, .wavedrom_svg_defs .h3 {
    font-size:20pt;
    font-weight:bold
}
.wavedrom_svg .h4, .wavedrom_svg_defs .h4 {
    font-size:14pt;
    font-weight:bold
}
.wavedrom_svg .h5, .wavedrom_svg_defs .h5 {
    font-size:11pt;
    font-weight:bold
}
.wavedrom_svg .h6, .wavedrom_svg_defs .h6 {
    font-size:8pt;
    font-weight:bold
}
.wavedrom_svg_defs .s1 {
    fill:none;
    stroke:#000;
    stroke-width:1;
    stroke-linecap:round;
    stroke-linejoin:miter;
    stroke-miterlimit:4;
    stroke-opacity:1;
    stroke-dasharray:none
}
.wavedrom_svg_defs .s2 {
    fill:none;
    stroke:#000;
    stroke-width:0.5;
    stroke-linecap:round;
    stroke-linejoin:miter;
    stroke-miterlimit:4;
    stroke-opacity:1;
    stroke-dasharray:none
}
.wavedrom_svg_defs .s3 {
    color:#000;
    fill:none;
    stroke:#000;
    stroke-width:1;
    stroke-linecap:round;
    stroke-linejoin:miter;
    stroke-miterlimit:4;
    stroke-opacity:1;
    stroke-dasharray:1,3;
    stroke-dashoffset:0;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
.wavedrom_svg_defs .s4 {
    color:#000;
    fill:none;
    stroke:#000;
    stroke-width:1;
    stroke-linecap:round;
    stroke-linejoin:miter;
    stroke-miterlimit:4;
    stroke-opacity:1;
    stroke-dasharray:none;
    stroke-dashoffset:0;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible
}
.wavedrom_svg_defs .s5 {
    fill:#fff;
    stroke:none
}
.wavedrom_svg_defs .s6 {
    color:#000;
    fill:#ffffb4;
    fill-opacity:1;
    fill-rule:nonzero;
    stroke:none;
    stroke-width:1px;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
.wavedrom_svg_defs .s7 {
    color:#000;
    fill:#ffe0b9;
    fill-opacity:1;
    fill-rule:nonzero;
    stroke:none;
    stroke-width:1px;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
.wavedrom_svg_defs .s8 {
    color:#000;
    fill:#b9e0ff;
    fill-opacity:1;
    fill-rule:nonzero;
    stroke:none;
    stroke-width:1px;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
.wavedrom_svg_defs .s9 {
    fill:#000;
    fill-opacity:1;
    stroke:none
}
.wavedrom_svg_defs .s10 {
    color:#000;
    fill:#fff;
    fill-opacity:1;
    fill-rule:nonzero;
    stroke:none;
    stroke-width:1px;
    marker:none;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
.wavedrom_svg_defs .s11 {
    fill:#0041c4;
    fill-opacity:1;
    stroke:none
}
.wavedrom_svg_defs .s12 {
    fill:none;
    stroke:#0041c4;
    stroke-width:1;
    stroke-linecap:round;
    stroke-linejoin:miter;
    stroke-miterlimit:4;
    stroke-opacity:1;
    stroke-dasharray:none
}

/*wavedrom stop*/


/* fontawesome */

/*!
 * Font Awesome Free 5.7.1 by @fontawesome - https://fontawesome.com
 * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
 */
svg:not(:root).svg-inline--fa {
  overflow: visible; }

.svg-inline--fa {
  display: inline-block;
  font-size: inherit;
  height: 1em;
  overflow: visible;
  vertical-align: -.125em; }
  .svg-inline--fa.fa-lg {
    vertical-align: -.225em; }
  .svg-inline--fa.fa-w-1 {
    width: 0.0625em; }
  .svg-inline--fa.fa-w-2 {
    width: 0.125em; }
  .svg-inline--fa.fa-w-3 {
    width: 0.1875em; }
  .svg-inline--fa.fa-w-4 {
    width: 0.25em; }
  .svg-inline--fa.fa-w-5 {
    width: 0.3125em; }
  .svg-inline--fa.fa-w-6 {
    width: 0.375em; }
  .svg-inline--fa.fa-w-7 {
    width: 0.4375em; }
  .svg-inline--fa.fa-w-8 {
    width: 0.5em; }
  .svg-inline--fa.fa-w-9 {
    width: 0.5625em; }
  .svg-inline--fa.fa-w-10 {
    width: 0.625em; }
  .svg-inline--fa.fa-w-11 {
    width: 0.6875em; }
  .svg-inline--fa.fa-w-12 {
    width: 0.75em; }
  .svg-inline--fa.fa-w-13 {
    width: 0.8125em; }
  .svg-inline--fa.fa-w-14 {
    width: 0.875em; }
  .svg-inline--fa.fa-w-15 {
    width: 0.9375em; }
  .svg-inline--fa.fa-w-16 {
    width: 1em; }
  .svg-inline--fa.fa-w-17 {
    width: 1.0625em; }
  .svg-inline--fa.fa-w-18 {
    width: 1.125em; }
  .svg-inline--fa.fa-w-19 {
    width: 1.1875em; }
  .svg-inline--fa.fa-w-20 {
    width: 1.25em; }
  .svg-inline--fa.fa-pull-left {
    margin-right: .3em;
    width: auto; }
  .svg-inline--fa.fa-pull-right {
    margin-left: .3em;
    width: auto; }
  .svg-inline--fa.fa-border {
    height: 1.5em; }
  .svg-inline--fa.fa-li {
    width: 2em; }
  .svg-inline--fa.fa-fw {
    width: 1.25em; }

.fa-layers svg.svg-inline--fa {
  bottom: 0;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 0; }

.fa-layers {
  display: inline-block;
  height: 1em;
  position: relative;
  text-align: center;
  vertical-align: -.125em;
  width: 1em; }
  .fa-layers svg.svg-inline--fa {
    -webkit-transform-origin: center center;
            transform-origin: center center; }

.fa-layers-text, .fa-layers-counter {
  display: inline-block;
  position: absolute;
  text-align: center; }

.fa-layers-text {
  left: 50%;
  top: 50%;
  -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
  -webkit-transform-origin: center center;
          transform-origin: center center; }

.fa-layers-counter {
  background-color: #ff253a;
  border-radius: 1em;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  color: #fff;
  height: 1.5em;
  line-height: 1;
  max-width: 5em;
  min-width: 1.5em;
  overflow: hidden;
  padding: .25em;
  right: 0;
  text-overflow: ellipsis;
  top: 0;
  -webkit-transform: scale(0.25);
          transform: scale(0.25);
  -webkit-transform-origin: top right;
          transform-origin: top right; }

.fa-layers-bottom-right {
  bottom: 0;
  right: 0;
  top: auto;
  -webkit-transform: scale(0.25);
          transform: scale(0.25);
  -webkit-transform-origin: bottom right;
          transform-origin: bottom right; }

.fa-layers-bottom-left {
  bottom: 0;
  left: 0;
  right: auto;
  top: auto;
  -webkit-transform: scale(0.25);
          transform: scale(0.25);
  -webkit-transform-origin: bottom left;
          transform-origin: bottom left; }

.fa-layers-top-right {
  right: 0;
  top: 0;
  -webkit-transform: scale(0.25);
          transform: scale(0.25);
  -webkit-transform-origin: top right;
          transform-origin: top right; }

.fa-layers-top-left {
  left: 0;
  right: auto;
  top: 0;
  -webkit-transform: scale(0.25);
          transform: scale(0.25);
  -webkit-transform-origin: top left;
          transform-origin: top left; }

.fa-lg {
  font-size: 1.33333em;
  line-height: 0.75em;
  vertical-align: -.0667em; }

.fa-xs {
  font-size: .75em; }

.fa-sm {
  font-size: .875em; }

.fa-1x {
  font-size: 1em; }

.fa-2x {
  font-size: 2em; }

.fa-3x {
  font-size: 3em; }

.fa-4x {
  font-size: 4em; }

.fa-5x {
  font-size: 5em; }

.fa-6x {
  font-size: 6em; }

.fa-7x {
  font-size: 7em; }

.fa-8x {
  font-size: 8em; }

.fa-9x {
  font-size: 9em; }

.fa-10x {
  font-size: 10em; }

.fa-fw {
  text-align: center;
  width: 1.25em; }

.fa-ul {
  list-style-type: none;
  margin-left: 2.5em;
  padding-left: 0; }
  .fa-ul > li {
    position: relative; }

.fa-li {
  left: -2em;
  position: absolute;
  text-align: center;
  width: 2em;
  line-height: inherit; }

.fa-border {
  border: solid 0.08em #eee;
  border-radius: .1em;
  padding: .2em .25em .15em; }

.fa-pull-left {
  float: left; }

.fa-pull-right {
  float: right; }

.far,.fa {
  margin: 0 .3em;
}
.fa.fa-pull-left,
.fas.fa-pull-left,
.far.fa-pull-left,
.fal.fa-pull-left,
.fab.fa-pull-left {
  margin-right: .3em; }

.fa.fa-pull-right,
.fas.fa-pull-right,
.far.fa-pull-right,
.fal.fa-pull-right,
.fab.fa-pull-right {
  margin-left: .3em; }

.fa-spin {
  -webkit-animation: fa-spin 2s infinite linear;
          animation: fa-spin 2s infinite linear; }

.fa-pulse {
  -webkit-animation: fa-spin 1s infinite steps(8);
          animation: fa-spin 1s infinite steps(8); }

@-webkit-keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
            transform: rotate(0deg); }
  100% {
    -webkit-transform: rotate(360deg);
            transform: rotate(360deg); } }

@keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
            transform: rotate(0deg); }
  100% {
    -webkit-transform: rotate(360deg);
            transform: rotate(360deg); } }

.fa-rotate-90 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
  -webkit-transform: rotate(90deg);
          transform: rotate(90deg); }

.fa-rotate-180 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
  -webkit-transform: rotate(180deg);
          transform: rotate(180deg); }

.fa-rotate-270 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
  -webkit-transform: rotate(270deg);
          transform: rotate(270deg); }

.fa-flip-horizontal {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
  -webkit-transform: scale(-1, 1);
          transform: scale(-1, 1); }

.fa-flip-vertical {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
  -webkit-transform: scale(1, -1);
          transform: scale(1, -1); }

.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
  -webkit-transform: scale(-1, -1);
          transform: scale(-1, -1); }

:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical,
:root .fa-flip-both {
  -webkit-filter: none;
          filter: none; }

.fa-stack {
  display: inline-block;
  height: 2em;
  position: relative;
  width: 2.5em; }

.fa-stack-1x,
.fa-stack-2x {
  bottom: 0;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 0; }

.svg-inline--fa.fa-stack-1x {
  height: 1em;
  width: 1.25em; }

.svg-inline--fa.fa-stack-2x {
  height: 2em;
  width: 2.5em; }

.fa-inverse {
  color: #fff; }

.sr-only {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px; }

.sr-only-focusable:active, .sr-only-focusable:focus {
  clip: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  position: static;
  width: auto; }

/* fontawesome end*/

/* xsj patch start */

.xsj_anchor{
  overflow: hidden;
  float: right;
}

.blank_anchor_id {
    float: right;
    width: 1px;
    height: 0px;
}
.blank_anchor_id {
    visibility: hidden;
}
.blank_anchor_id:before {
    content: 'a';
}
.xsj_foreignObject{
  width: 100%!important;
  height: 100%!important;
  text-align: initial;
  word-spacing: normal;
}
.xsj_foreignObject hr{
    margin: inherit;
}
.xsj_foreignObject.xsj_drawio_foreignObject *{
  font-size: inherit;
}
.xsj_export_pdf .xsj_foreignObject.xsj_drawio_foreignObject *{
  font-size: 85%;
}

.xsj_export_pdf ins .mathjax .MathJax_SVG {
    border-bottom: 2px solid;
}

.xsj_foreignObject.xsj_drawio_foreignObject h1{
  font-size: 2em;
  margin-block-start: 0.67em;
  margin-block-end: 0.67em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}
.xsj_foreignObject.xsj_drawio_foreignObject h2{
  font-size: 1.5em;
  margin-block-start: 0.83em;
  margin-block-end: 0.83em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}
.xsj_foreignObject.xsj_drawio_foreignObject h3{
  font-size: 1.17em;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}
.xsj_foreignObject.xsj_drawio_foreignObject h4{
  font-size: 1em;
  margin-block-start: 1.33em;
  margin-block-end: 1.33em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}
.xsj_foreignObject.xsj_drawio_foreignObject h5{
  font-size: .83em;
  margin-block-start: 1.67em;
  margin-block-end: 1.67em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}
.xsj_foreignObject.xsj_drawio_foreignObject h6{
  font-size: .67em;
  margin-block-start: 2.33em;
  margin-block-end: 2.33em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
}

/* xsj patch end */


/* title start */
h1.story_title {
    font-size: 2.1rem;
    margin: 0.7em 0;
}
/* title end */

/* tag start */
.story_tags {
    margin: 0 0 1.2em;
}
.tag.label{
    display: inline-block;
    vertical-align: baseline;
    line-height: 1;
    margin: 0 0.5em 0.5em 0;
    background: #e2e2e2;
    border-color: #e2e2e2;
    background-image: none;
    padding: 0.6em 0.8em;
    font-weight: bold;
    border-radius: 0.2857rem;
    box-sizing: border-box;
    font-size: 12px;
}
/* tag end */

/* emoji */
img.emoji {
    width: 1em;
    line-height: 1em;
    vertical-align: baseline;
    margin-bottom: 0;
}
/* emoji */

/* align grammar start*/

.story_align_left, .story_align_left .story_image_container {
    text-align: left;
}
.story_align_right, .story_align_right .story_image_container {
    text-align: right;
}
.story_align_center, .story_align_center .story_image_container {
    text-align: center;
}
.story_align_justify, .story_align_justify .story_image_container {
    text-align: justify;
}

/* align grammar end*/

/*mindmap start*/
.mindmap_container {
  text-align: center;
}

.xsj_mindmap_caption{
   border-bottom: 1px solid #d9d9d9;
  display: inline-block;
  color: #999;
  padding: 10px;
}
/*mindmap end*/



/* table start*/

table {
  max-width: 100%;
  background-color: transparent;
  border-collapse: collapse;
  border-spacing: 0;
  word-break: break-word;
  border: 1px solid #d9d9da;
}
.table {
  width: 100%;
  margin-bottom: 20px;
  margin-right: auto;
  margin-left: auto;
}

.table th,
.table td {
  padding: 8px;
  line-height: 20px;
  text-align: left;
  vertical-align: top;
  border-top: 1px solid #d9d9da;
}

.table th {
  font-weight: bold;
}

.table thead th {
  vertical-align: bottom;
}

.table tbody + tbody {
  border-top: 2px solid #d9d9da;
}

.table .table {
  background-color: #ffffff;
}


.table-striped tbody > tr:nth-child(odd) > td,
.table-striped tbody > tr:nth-child(odd) > th {
  background-color: #f9f9f9;
}

.table-celled.table tr td,.table-celled.table tr th {
    border-left: 1px solid #d9d9da;
}

/* table end*/

/*code start*/

code {
    background-color: #F0F0F0;
    border-radius: 4px;
    padding: 2px 4px;
    margin: 0 .225em;
    color: #880000;
}
body code{
    border: 0;
    border-radius: 4px;
    font-size: .9em;
}

.hljs, .hljs * {
  overflow: visible !important;
} 

body .xiaoshujiang_code {
    border: 0;
    border-radius: 4px;
    font-size: .9em;
}
.xiaoshujiang_code ol{
    margin-top: 0px;
    margin-bottom: 0px;
}

.xiaoshujiang_pre {
    line-height: initial !important;
    word-wrap: break-word;
    word-break: break-all;
    tab-size: 4;
    white-space: pre-wrap;
    font-family: monospace;
}
.xiaoshujiang_code_container pre{
    margin: 0px;
}
.xiaoshujiang_code_container.xiaoshujiang_code_chunk{
    box-shadow: 0 0 0 1px #A3C293 inset,0 0 0 0 transparent;
    margin: 1em 0;
    padding: 1em;
}
.xiaoshujiang_code_container.xiaoshujiang_code_chunk_hide_code{
    box-shadow: initial;
    padding: initial;
    padding-bottom: 2em;
}
.xiaoshujiang_code_container .out_put{
    box-shadow: 0 0 0 1px #A3C293 inset,0 0 0 0 transparent;
    margin: 1em 0;
    background-color: #FCFFF5;
    color: #2C662D;
    padding: 1em;
}
.xiaoshujiang_code_container .out_put_error{
    background-color: #FFF6F6;
    color: #9F3A38;
    margin: 1em 0;
    box-shadow: 0 0 0 1px #E0B4B4 inset,0 0 0 0 transparent;
    padding: 1em;
}

/*code end*/

/* code line nums start*/

code.hljs.code_linenums, .xiaoshujiang_code.hljs.code_linenums{
    position: relative;
}
.ol_linenums{
    padding: 0px;
    margin-left: 2em;
    border-left: 1px solid #e0e0e0;
}
.li_linenum{
    position:relative;
    margin-left: 0.5em;
    list-style: none;
    counter-increment: lines 1;
}
.li_linenum.li_list_style{
    list-style: inherit;
    margin-left: 5px;
}
.li_linenum:before, .li_linenum_before_span{
    content: counter(lines, decimal);
  position: absolute;
  left: -3em;
  text-align: center;
  width: 2.5em;
  vertical-align: top;
}
.li_linenum_before_span_hide{
    display: none;
}
.xiaoshujiang_code .code_line_break_hack{
    margin:0;
    border:0;
    border-top:0;
    border-bottom:0;
}
.component_attachment, .code_line_break_hack{
  display: none;
  visibility: collapse!important;
  height: 0!important;
}

/* code line nums end*/

/* block code start */
.xiaoshujiang_code_container {
    margin: 1em 0px 2em;
    position: relative;
}


.xiaoshujiang_code_title_container{
    font-size: 50%;
}
.xiaoshujiang_code_title_container>.xiaoshujiang_code_infos{
    float: right;
}
/* block code end */


/*mark start*/

.mark{
  border: 0;
  background-color: rgba(221, 243, 231, 0.4);
  color: #105012;
  padding: 2px 4px;
}

.mark_color_000000{
  color: transparent!important;
  background: initial!important;
  border-bottom: 2px solid #3a4c42;
  transition: color .6s;
}

.mark_color_000000:hover{
  color: black!important;
}

.li_linenum.line_mark:before, .line_mark .li_linenum_before_span {
    background: rgba(65, 174, 60, 0.6);
}
.line_mark{
  background: rgba(65, 174, 60, 0.3);
}



.li_linenum.line_mark_warn:before, .line_mark_warn .li_linenum_before_span {
    background: rgba(252, 121, 48, .6);
}
.line_mark_warn{
  background: rgba(252, 121, 48, .3);
}

.li_linenum.line_mark_info:before, .line_mark_info .li_linenum_before_span {
    background: rgba(97, 154, 195, .6);
}
.line_mark_info{
  background: rgba(97, 154, 195, .3);
}

.li_linenum.line_mark_error:before, .line_mark_error .li_linenum_before_span {
    background: rgba(210, 118, 118, 0.6);
}
.line_mark_error{
  background: rgba(210, 174, 174, 0.3);
}

.line_mark_del{
  text-decoration: line-through;
  text-decoration: 2px line-through;
}
.line_mark_ins{
  text-decoration: underline;
  text-decoration: 2px underline;
}

code .mark, .xiaoshujiang_code .mark{
    border-radius: 0px;
    font-size: initial;
    padding: initial;
}
/*mark end*/


.xsj_code_strong{
  -webkit-text-emphasis: triangle;
  -webkit-text-emphasis-position: under;
}

/* attachment start */
a.attachment{
    background: #ecf0f3;
    border: 1px solid #bec6cb;
    display: inline-block;
    padding: 0.6em;
    margin: 0.5em 0.5em;
    min-width: 250px;
}
a.attachment i.fa{
    font-size: 3em;
  float: left;
  margin-right: 0.2em;
}
a.attachment .filename{
    vertical-align: top;
  text-align: left;
  font-weight: bold;
}
a.attachment .filesize{
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  opacity: .6;
  font-size: 80%;
  white-space: nowrap;
}
/* attachment end */


/*code chunk video, slideshare start*/
.video_container{
    width: 100%;
    display: table;
    text-align: center;
    position: relative;
    padding-bottom: 56.25%!important;
}

.video_container iframe{
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    vertical-align: middle;
}

.slideshare_container .inner{
    position: relative;
    width: 100%;
}

.slideshare_container .inner iframe{
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

/*code chunk video, slideshare start*/



/*mermaid start*/

.mermaid {
    text-align: center;
}

.mermaid_svg{
    font-family: monospace;
    text-align: initial;
}
.mermaid_svg foreignObject{
  overflow: visible;
}
.mermaid_svg foreignObject i.fa{
  min-width: 16px;
}
.mermaid_svg .svg-inline--fa,.mermaid_svg .svg-inline--fa path {
    fill: initial!important;
    stroke: initial!important;
}

.mermaid_svg .grid path {
  stroke: transparent;
}
/*mermaid stop*/


/* patch evernote start*/
.toc ul {
    list-style-type: none;
}
/* patch evernote end*/


/* image start*/
img {
    height: auto;
    max-width: 100%;
    vertical-align: middle;
    border: 0;
}

.story_image_container{
    text-align: center;
}
.story_image_container>.story_image{
    display: inline-block;
    position: relative;
    max-width: 100%;
}
.story_image_caption, .xsj_remote_html_caption {
    border-bottom: 1px solid #d9d9d9;
    display: inline-block;
    color: #999;
    padding: 10px;
}
.story_image_blank_caption, .xsj_remote_html_blank_caption{
    display: none;
}
.story_image>img{
    border-radius: 0.3125em;
    box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);
}

.story_inline_image{
  display: inline-block;
}
.story_inline_image>img{
    vertical-align: bottom;
}
/* image end*/

.story_remote_resource_block{
    text-align: center;
}

/* task list start */
.task-list-item{
    list-style: none;
}
.task-list-item.li_list_style{
    list-style:inherit;
}
.task-list-item > p {
  margin: 0;
}

/* task list end */

/* other start */
em.cjk_emphasis{
    font-style: normal;
    font-family: Georgia,"Times New Roman",Times,"楷体","AR PL UKai CN", "NSimSun","Songti SC","SimSun",serif!important;
}

.flow-chart, .sequence-diagram{
    text-align: center;
}
.plot, .plot-image{
    text-align: center;
    min-height: 200px;
    min-width: 200px;
}

ins .mathjax .MathJax_SVG {
    border-bottom: 1px solid;
    padding-bottom: 2px;
    margin-bottom: 2px;
}

.mathjax-container{
    text-align: center;
    margin: 0 auto;
}
div.mathjax{
    max-width: 100%;
    margin: 0 auto;
    font-size: 14px;
}

.mathjax-container .math_equation_table{
  border: 0;
  width: 100%;
}
.mathjax-container .math_equation_table td{
  text-align: center;
  vertical-align: top;
}

.xsj_export_pdf .fa-border {
  border: none;
  border-radius: initial;
  padding: initial;
  margin: 0 .25em;
  outline-offset: .2em;
  outline: 1px solid #eee;
}
.preview.html_preview{
  max-width: 100%;
}

.xsj_export_pdf.preview.html_preview{
  max-width: initial;
  border: initial;
  margin: initial;
  padding: initial;
  border-radius: initial;
  box-shadow: initial;
}
/* other end */




/* blockquote start*/
/** only icon **/
.html_preview>.markdown_blockquote{
    position: relative;
}
.html_preview>.markdown_blockquote.markdown_blockquote_icon{
    margin-left: 10px;
}
.html_preview>.markdown_blockquote>.xsj_paragraph:first-child>i:first-child{
    background-color: #dedede;
    border-radius: 100%;
    left: -18px;
    line-height: 30px;
    position: absolute;
    height: 30px;
    width: 30px;
    text-align: center;
    font-size: 16px!important;
    padding: 0;
    border: 0px;

}

.html_preview>.markdown_blockquote>.xsj_paragraph:first-child>.svg-image:first-child,
.html_preview>.markdown_blockquote>.xsj_paragraph:first-child>svg.svg-inline--fa:first-child {
    background-color: #dedede;
    border-radius: 100%;
    left: -15px;
    line-height: 30px;
    position: absolute;
    height: 20px;
    width: 20px;
    text-align: center;
    box-shadow: 0 0 0px 5px #dedede;
    font-size: 16px!important;
    padding: 0;
    border: 0px;
    outline: 0;
    margin: 0;
}
/** only icon **/
/** heading **/
.html_preview > .markdown_blockquote.markdown_blockquote_heading {
    margin-top: 40px;
    page-break-inside: auto;
}
.html_preview>.markdown_blockquote_heading>.xsj_heading:first-child {
    display: block;
    font-size: 1.4em;
    background-color: #dedede;
    padding: 0 15px;
    margin: -20px;
    position: relative;
}
.html_preview>.markdown_blockquote_heading>.xsj_heading:first-child .xsj_heading_content>i:first-child {
    background-color: #dedede;
    border-radius: 100%;
    left: -16px;
    top: .25em;
    line-height: 30px;
    position: absolute;
    height: 30px;
    width: 30px;
    text-align: center;
    font-size: 16px !important;
    padding: 0;
    border: 0px;
}

.html_preview>.markdown_blockquote_heading>.xsj_heading:first-child .xsj_heading_content>.svg-image:first-child,
.html_preview>.markdown_blockquote_heading>.xsj_heading:first-child .xsj_heading_content>svg.svg-inline--fa:first-child {
    background-color: #dedede;
    border-radius: 100%;
    left: -15px;
    top: .25em;
    line-height: 30px;
    position: absolute;
    height: 20px;
    width: 20px;
    text-align: center;
    box-shadow: 0 0 0px 5px #dedede;
    font-size: 16px!important;
    padding: 0;
    border: 0px;
    outline: 0;
    margin: 0;
}

/** heading **/
/* blockquote end*/


@media print{
  body{
    font-size: 18px;
    word-wrap: break-word;
    word-break: break-word;
    background: initial!important;
    font-kerning: normal;
    text-rendering: geometricPrecision;
  }
  .preview.html_preview{
    max-width: initial;
    border: initial;
    margin: initial;
    padding: initial;
    border-radius: initial;
    box-shadow: initial;
  }
  .xiaoshujiang_element.xsj_anchor{
    position: absolute;
  }
  tr { page-break-inside: avoid; }
  .story_image_container{
     page-break-inside: avoid;
  }
  blockquote{
    page-break-inside: avoid;
  }

  .xsj_underline{
      page-break-after: always;
      visibility: hidden;
  }
}

body{color:#2f2f2f}.xsj_hr{border-top:1px dashed #2f2f2f}kbd{color:#2f2f2f;border:solid 1px #2f2f2f;border-bottom-color:#2f2f2f;box-shadow:inset 0 -1px 0 #2f2f2f}table{border:1px solid rgba(34,36,38,.15)}.table td,.table th{border-top:1px solid #ddd}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background:#fff}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background:#f9f9f9}.table-celled.table tr td,.table-celled.table tr th{border-left:1px solid rgba(34,36,38,.1)}.xiaoshujiang_code .mark,code .mark{background:rgba(160,234,194,.7)}.markdown_vertical>*,.markdown_vertical>:first-child{margin-top:.8em}.markdown_vertical{font-family:YRDZST,"Noto Serif CJK SC",FandolKai,"Adobe Kaiti Std","Adobe 楷体 Std",FZKai-Z03S,"方正楷体简体","AR PL UKai CN","楷体",NSimSun,SimSun,serif;font-size:1.2em;writing-mode:vertical-rl;border:initial;border-left:initial;background:initial;margin-left:auto!important;margin-right:0}.markdown_vertical em{-webkit-text-emphasis:circle}.markdown_vertical strong{border-left:2px solid}.html_preview>.markdown_blockquote_heading.markdown_vertical>.xsj_heading:first-child{position:initial;background:initial;border:initial;background-color:initial;border-top:initial}.html_preview>.markdown_blockquote.markdown_vertical>.xsj_paragraph:first-child>i:first-child,.html_preview>.markdown_blockquote_heading.markdown_vertical>.xsj_heading:first-child .xsj_heading_content>i:first-child{position:initial;background-color:initial}@media print{.markdown_vertical{writing-mode:initial}.markdown_vertical strong{border-left:0;border-bottom:2px solid}}
/*

Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>

*/

.hljs {
  display: block;
  overflow-x: auto;
  padding: 0.5em;
  background: #F0F0F0;
}


/* Base color: saturation 0; */

.hljs,
.hljs-subst {
  color: #444;
}

.hljs-comment {
  color: #888888;
}

.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta .hljs-keyword,
.hljs-doctag,
.hljs-name {
  font-weight: bold;
}


/* User color: hue: 0 */

.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
  color: #880000;
}

.hljs-title,
.hljs-section {
  color: #880000;
  font-weight: bold;
}

.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
  color: #BC6060;
}


/* Language color: hue: 90; */

.hljs-literal {
  color: #78A960;
}

.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
  color: #397300;
}


/* Meta color: hue: 200 */

.hljs-meta {
  color: #1f7199;
}

.hljs-meta .hljs--string {
  color: #4d99bf;
}


/* Misc effects */

.hljs-emphasis {
  font-style: italic;
}

.hljs-strong {
  font-weight: bold;
}

</style>

<body>
<div><div class="preview" id="wmd-preview">

	<div class="preview html_preview xsj_export_html"><div style="overflow: hidden; position: absolute; top: 0px; height: 1px; width: auto; padding: 0px; border: 0px; margin: 0px; text-align: left; text-indent: 0px; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal;"><svg><defs id="MathJax_SVG_glyphs"></defs></svg></div><h1 class="story_title">《深度学习》2021</h1><div class="story_tags"><span class="tag blue label">李宏毅</span></div><hr class="xsj_hr xsj_minus" />
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="120e9a284e6b58be69cace9a291e98193e8a782e79c8be4babae695b0_1"><div class="xiaoshujiang_element xsj_anchor">
  <a name="120e9a284e6b58be69cace9a291e98193e8a782e79c8be4babae695b0_1" class="blank_anchor_name"></a><a id="120e9a284e6b58be69cace9a291e98193e8a782e79c8be4babae695b0_1" class="blank_anchor_id"></a><a name="1-预测本频道观看人数" class="blank_anchor_name"></a><a id="1-预测本频道观看人数" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">1. 预测本频道观看人数</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178020.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178020.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178023.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178023.png" loading="lazy" /></span><p></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178025.png" data-vdom-skip="true" data-vdom-cache="true" alt="改变不同wbc结果" title="改变不同wbc结果" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178025.png" loading="lazy" /><br /><div class="story_image_caption ">改变不同wbc结果</div></div></div><br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178027.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178027.png" loading="lazy" /></span><p></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178028.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178028.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178030.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178030.png" loading="lazy" /></span><p></p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="220e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_2"><div class="xiaoshujiang_element xsj_anchor">
  <a name="220e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_2" class="blank_anchor_name"></a><a id="220e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_2" class="blank_anchor_id"></a><a name="2-机器学习任务攻略" class="blank_anchor_name"></a><a id="2-机器学习任务攻略" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">2. 机器学习任务攻略</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178031.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178031.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><p></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="overfitting20e8a7a3e586b3e58a9ee6b395efbc9a_3"><div class="xiaoshujiang_element xsj_anchor">
  <a name="overfitting20e8a7a3e586b3e58a9ee6b395efbc9a_3" class="blank_anchor_name"></a><a id="overfitting20e8a7a3e586b3e58a9ee6b395efbc9a_3" class="blank_anchor_id"></a><a name="overfitting-解决办法" class="blank_anchor_name"></a><a id="overfitting-解决办法" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">overfitting 解决办法：</span></h4>
<ol class="markdown_ol">
<li><span class="xsj_placeholder_span"></span>增加训练集</li>
<li><span class="xsj_placeholder_span"></span>不让模型有太大弹性，限制模型（）<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178033.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178033.png" loading="lazy" /></span><br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178034.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178034.png" loading="lazy" /></span></li>
</ol>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="320e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_4"><div class="xiaoshujiang_element xsj_anchor">
  <a name="320e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_4" class="blank_anchor_name"></a><a id="320e69cbae599a8e5ada6e4b9a0e4bbbbe58aa1e694bbe795a5_4" class="blank_anchor_id"></a><a name="3-机器学习任务攻略" class="blank_anchor_name"></a><a id="3-机器学习任务攻略" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">3. 机器学习任务攻略</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0">optimization issue 不是过拟合<br />
过拟合——&gt;train loss min 但是 test loss max<br />
overfitting 模型弹性大<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178035.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178035.png" loading="lazy" /></span></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="data20augmentationefbc9aefbc88e5a29ee58aa0e695b0e68daee99b86efbc8ce981bfe5858de8bf87e68b9fe59088efbc89_5"><div class="xiaoshujiang_element xsj_anchor">
  <a name="data20augmentationefbc9aefbc88e5a29ee58aa0e695b0e68daee99b86efbc8ce981bfe5858de8bf87e68b9fe59088efbc89_5" class="blank_anchor_name"></a><a id="data20augmentationefbc9aefbc88e5a29ee58aa0e695b0e68daee99b86efbc8ce981bfe5858de8bf87e68b9fe59088efbc89_5" class="blank_anchor_id"></a><a name="data-augmentation增加数据集避免过拟合" class="blank_anchor_name"></a><a id="data-augmentation增加数据集避免过拟合" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Data augmentation：（增加数据集，避免过拟合）</span></h4>
<ol class="markdown_ol">
<li><span class="xsj_placeholder_span"></span>左右翻转图片，镜像等等；</li>
<li><span class="xsj_placeholder_span"></span>model 写限制 比较小的神经元数目，早结束，丢弃，较少特征。</li>
</ol>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="n-fold20cross20validation_6"><div class="xiaoshujiang_element xsj_anchor">
  <a name="n-fold20cross20validation_6" class="blank_anchor_name"></a><a id="n-fold20cross20validation_6" class="blank_anchor_id"></a><a name="n-fold-cross-validation" class="blank_anchor_name"></a><a id="n-fold-cross-validation" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">N-fold Cross Validation</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">分成不同分，然后做多次，每次tarin与val不一样<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178036.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178036.png" loading="lazy" /></span></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="mismatch_7"><div class="xiaoshujiang_element xsj_anchor">
  <a name="mismatch_7" class="blank_anchor_name"></a><a id="mismatch_7" class="blank_anchor_id"></a><a name="mismatch" class="blank_anchor_name"></a><a id="mismatch" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Mismatch</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">训练资料与测速资料不一样</p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="420e5b180e983a8e69c80e5b08fe580bcloacl20minimae4b88ee99e8de782b9saddle20point_8"><div class="xiaoshujiang_element xsj_anchor">
  <a name="420e5b180e983a8e69c80e5b08fe580bcloacl20minimae4b88ee99e8de782b9saddle20point_8" class="blank_anchor_name"></a><a id="420e5b180e983a8e69c80e5b08fe580bcloacl20minimae4b88ee99e8de782b9saddle20point_8" class="blank_anchor_id"></a><a name="4-局部最小值loacl-minima与鞍点saddle-point" class="blank_anchor_name"></a><a id="4-局部最小值loacl-minima与鞍点saddle-point" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">4. 局部最小值(Loacl Minima)与鞍点(Saddle point)</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0">local minima 是最低，saddle point不是最低，还可以使loss降低</p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178037.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178037.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><p></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178038.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178038.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><br />
critical piont 临界点，一阶导为0，所以只看后面红色部分。<p></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178039.png" data-vdom-skip="true" data-vdom-cache="true" alt="三种情况" title="三种情况" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178039.png" loading="lazy" /><br /><div class="story_image_caption ">三种情况</div></div></div><p></p>
<p class="xsj_paragraph xsj_paragraph_level_0">H是矩阵Haition<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178040.png" data-vdom-skip="true" data-vdom-cache="true" alt="例子" title="例子" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178040.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0">H的特征值 小于零 可以找更低loss点<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178049.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750322178049.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0">二维空间的 local minima 不一定是最低，可以看高纬度，说不定就是saddle point<br />
local minima并没有那么常见，多数还是saddle point</p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="520e689b9e6aca1efbc88batchefbc89e4b88ee58aa8e9878fefbc88momentumefbc89_9"><div class="xiaoshujiang_element xsj_anchor">
  <a name="520e689b9e6aca1efbc88batchefbc89e4b88ee58aa8e9878fefbc88momentumefbc89_9" class="blank_anchor_name"></a><a id="520e689b9e6aca1efbc88batchefbc89e4b88ee58aa8e9878fefbc88momentumefbc89_9" class="blank_anchor_id"></a><a name="5-批次batch与动量momentum" class="blank_anchor_name"></a><a id="5-批次batch与动量momentum" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">5. 批次（batch）与动量（Momentum）</span></h3>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="batch_10"><div class="xiaoshujiang_element xsj_anchor">
  <a name="batch_10" class="blank_anchor_name"></a><a id="batch_10" class="blank_anchor_id"></a><a name="batch" class="blank_anchor_name"></a><a id="batch" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Batch</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0"><span class="mark mark_color mark_color_619AC3" style="color:#619AC3;background-color:rgba(97, 154, 195, 0.1)">epod</span>：计算loss不是所有资料，只会拿一个batch计算，然后再更新，所有batch计算之后叫一个epod<br />
<span class="mark mark_color mark_color_619AC3" style="color:#619AC3;background-color:rgba(97, 154, 195, 0.1)">shuffle</span>：每一个epod的batch不一样<br />
使用batch——&gt; 每一个batch 都会更新数据<br />
不使用batch</p>
<table class="table table-striped table-celled">
<thead>
<tr>
<th>不使用batch</th>
<th>使用batch</th>
</tr>
</thead>
<tbody>
<tr>
<td>蓄力时间长，威力比较大</td>
<td>技能快，比较不准</td>
</tr>
</tbody>
</table>
<p class="xsj_paragraph xsj_paragraph_level_0">平行计算，不使用batch所使用的时间不一定大<br />
<span class="mark mark_color mark_color_EE3F4D" style="color:#EE3F4D;background-color:rgba(238, 63, 77, 0.1)">一个epoch大的batch花的时间反而是比较少的</span><br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750314324330.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750314324330.png" loading="lazy" /></span><br />
<span class="mark mark_color mark_color_EE3F4D" style="color:#EE3F4D;background-color:rgba(238, 63, 77, 0.1)">大的batch size 结果不行，小的batch size 结果反而更好。不是overfitting</span></p>
<blockquote class="markdown_blockquote">
<p class="xsj_paragraph xsj_paragraph_level_1"><span class="xsj_placeholder_span"></span>可能的解释：full batch 没有办法更新参数，但是small batch可以更新参数，每次的loss都是有差异的</p>
</blockquote>
<p class="xsj_paragraph xsj_paragraph_level_0">小的 batch 在testing 结果会更差：small batch 与large batch在training时相同准确率，但是在testing时 small batch准确率反而不好。如果small batch在testing 中效果不好——&gt;<span class="mark mark_color mark_color_619AC3" style="color:#619AC3;background-color:rgba(97, 154, 195, 0.1)">overfitting</span></p>
<blockquote class="markdown_blockquote">
<p class="xsj_paragraph xsj_paragraph_level_1"><span class="xsj_placeholder_span"></span>large batch——&gt;走向小峡谷里面<br />
small batch——&gt;走向大盆地里面，方向多</p>
</blockquote>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750315347911.png" data-vdom-skip="true" data-vdom-cache="true" alt="large and small batch" title="large and small batch" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750315347911.png" loading="lazy" /><br /><div class="story_image_caption ">large and small batch</div></div></div><p></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="momentum_11"><div class="xiaoshujiang_element xsj_anchor">
  <a name="momentum_11" class="blank_anchor_name"></a><a id="momentum_11" class="blank_anchor_id"></a><a name="momentum" class="blank_anchor_name"></a><a id="momentum" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Momentum</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">gradient的方向加上前次移动方向<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750316914444.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750316914444.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750317017555.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750317017555.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><p></p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="620e887aae58aa8e8b083e695b4e5ada6e4b9a0e9809fe78e87efbc88learning20rateefbc89_12"><div class="xiaoshujiang_element xsj_anchor">
  <a name="620e887aae58aa8e8b083e695b4e5ada6e4b9a0e9809fe78e87efbc88learning20rateefbc89_12" class="blank_anchor_name"></a><a id="620e887aae58aa8e8b083e695b4e5ada6e4b9a0e9809fe78e87efbc88learning20rateefbc89_12" class="blank_anchor_id"></a><a name="6-自动调整学习速率learning-rate" class="blank_anchor_name"></a><a id="6-自动调整学习速率learning-rate" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">6. 自动调整学习速率（Learning Rate）</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0">某一个方向上gradient值很小，非常平坦——&gt;learning rate 调大<br />
某一个方向上gradient值很大，非常陡峭——&gt;learning rate 调小</p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="adaptive_13"><div class="xiaoshujiang_element xsj_anchor">
  <a name="adaptive_13" class="blank_anchor_name"></a><a id="adaptive_13" class="blank_anchor_id"></a><a name="adaptive" class="blank_anchor_name"></a><a id="adaptive" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Adaptive</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318367457.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318367457.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><p></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="rmsprop_14"><div class="xiaoshujiang_element xsj_anchor">
  <a name="rmsprop_14" class="blank_anchor_name"></a><a id="rmsprop_14" class="blank_anchor_id"></a><a name="rmsprop" class="blank_anchor_name"></a><a id="rmsprop" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">RMSProp</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318114970.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318114970.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><br />
Adam：RMSProp + Momentum<p></p>
<p class="xsj_paragraph xsj_paragraph_level_0">Adaptive结果：<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318645775.png" data-vdom-skip="true" data-vdom-cache="true" alt="结果与Learing Rate Decaye改进" title="结果与Learing Rate Decaye改进" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318645775.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0">解决办法：</p>
<ol class="markdown_ol">
<li><span class="xsj_placeholder_span"></span>Learing Rate Decay，随着时间不断进行，随着参数不断update，让这个 值越来越小<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318524940.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318524940.png" loading="lazy" /></span></li>
<li><span class="xsj_placeholder_span"></span>Warm Up，先变大参数，后变小<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318761977.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750318761977.png" loading="lazy" /></span></li>
</ol>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="720e68d9fe5a4b1e587bde695b0efbc88lossefbc89_15"><div class="xiaoshujiang_element xsj_anchor">
  <a name="720e68d9fe5a4b1e587bde695b0efbc88lossefbc89_15" class="blank_anchor_name"></a><a id="720e68d9fe5a4b1e587bde695b0efbc88lossefbc89_15" class="blank_anchor_id"></a><a name="7-损失函数loss" class="blank_anchor_name"></a><a id="7-损失函数loss" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">7. 损失函数（Loss）</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321109417.png" data-vdom-skip="true" data-vdom-cache="true" alt="" title="" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321109417.png" loading="lazy" /><br /><div class="story_image_caption story_image_blank_caption"></div></div></div><p></p>
<p class="xsj_paragraph xsj_paragraph_level_0">Loss of Classification<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321320597.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321320597.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0">Minimizing cross-entropy is equivalent to maximizing likelihood<br />
两个是一模一样的东西<br />
<span class="mark mark_color mark_color_619AC3" style="color:#619AC3;background-color:rgba(97, 154, 195, 0.1)">cross-entropy 更加适合用在分类问题（ptorch会自动把soft max加在network的最后一层）</span></p>
<p class="xsj_paragraph xsj_paragraph_level_0"></p><div class="story_image_container story_block_image"><div class="story_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321825893.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750321825893.png" loading="lazy" /><br /><div class="story_image_caption ">enter description here</div></div></div><p></p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="820e689b9e6aca1e6a087e58786e58c96efbc88batch20normalizationefbc89_16"><div class="xiaoshujiang_element xsj_anchor">
  <a name="820e689b9e6aca1e6a087e58786e58c96efbc88batch20normalizationefbc89_16" class="blank_anchor_name"></a><a id="820e689b9e6aca1e6a087e58786e58c96efbc88batch20normalizationefbc89_16" class="blank_anchor_id"></a><a name="8-批次标准化batch-normalization" class="blank_anchor_name"></a><a id="8-批次标准化batch-normalization" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">8. 批次标准化（Batch Normalization）</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0">batch比较大的时候才适合使用batch normalization</p>
<p class="xsj_paragraph xsj_paragraph_level_0">标准化，0到1的数值<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750329930067.png" data-vdom-skip="true" data-vdom-cache="true" alt="" title="" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750329930067.png" loading="lazy" /></span></p>
<p class="xsj_paragraph xsj_paragraph_level_0">在testing时，未知参数，使用平均值<br />
<span class="story_inline_image"><img src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750330715340.png" data-vdom-skip="true" data-vdom-cache="true" alt="enter description here" title="enter description here" name="" data-src="https://raw.githubusercontent.com/wang-akang/study/main/_posts/images/1750330715340.png" loading="lazy" /></span></p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="920e58db7e7a7afe7a59ee7bb8fe7bd91e7bb9cefbc8820convolutional20neural20networksefbc89_17"><div class="xiaoshujiang_element xsj_anchor">
  <a name="920e58db7e7a7afe7a59ee7bb8fe7bd91e7bb9cefbc8820convolutional20neural20networksefbc89_17" class="blank_anchor_name"></a><a id="920e58db7e7a7afe7a59ee7bb8fe7bd91e7bb9cefbc8820convolutional20neural20networksefbc89_17" class="blank_anchor_id"></a><a name="9-卷积神经网络-convolutional-neural-networks" class="blank_anchor_name"></a><a id="9-卷积神经网络-convolutional-neural-networks" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">9. 卷积神经网络（ Convolutional Neural Networks）</span></h3>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="simplification201e28094receptive20filed_18"><div class="xiaoshujiang_element xsj_anchor">
  <a name="simplification201e28094receptive20filed_18" class="blank_anchor_name"></a><a id="simplification201e28094receptive20filed_18" class="blank_anchor_id"></a><a name="simplification-1receptive-filed" class="blank_anchor_name"></a><a id="simplification-1receptive-filed" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Simplification 1—receptive filed</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">设置 receptive file ，每一个neural只关心自己 receptive file 里面发生的事情</p>
<blockquote class="markdown_blockquote">
<p class="xsj_paragraph xsj_paragraph_level_1"><span class="xsj_placeholder_span"></span>receptive file自己定，可以长方形、叠加、只取红色等等。一般3*3且一组neural守备</p>
</blockquote>
<p class="xsj_paragraph xsj_paragraph_level_0">stride：步长。<br />
padding：超出部分补植</p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="simplification202e2809420parameter20sharing_19"><div class="xiaoshujiang_element xsj_anchor">
  <a name="simplification202e2809420parameter20sharing_19" class="blank_anchor_name"></a><a id="simplification202e2809420parameter20sharing_19" class="blank_anchor_id"></a><a name="simplification-2-parameter-sharing" class="blank_anchor_name"></a><a id="simplification-2-parameter-sharing" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Simplification 2— parameter sharing</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">共用一个参数，不同receptive file 的数据使用同一个neural</p>
<p class="xsj_paragraph xsj_paragraph_level_0"><span class="mark mark_color mark_color_EE3F4D" style="color:#EE3F4D;background-color:rgba(238, 63, 77, 0.1)">convolutional layer=receptive filed + parameter sharing</span></p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="pooling_20"><div class="xiaoshujiang_element xsj_anchor">
  <a name="pooling_20" class="blank_anchor_name"></a><a id="pooling_20" class="blank_anchor_id"></a><a name="pooling" class="blank_anchor_name"></a><a id="pooling" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Pooling</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">Max Pooling  选择一个最大的那个，自己决定矩阵大小</p>
<blockquote class="markdown_blockquote">
<p class="xsj_paragraph xsj_paragraph_level_1"><span class="xsj_placeholder_span"></span>相当于减小图像分辨率，Go playing 并没有使用pooling，下围棋，棋盘不适合使用pooling</p>
</blockquote>
<p class="xsj_paragraph xsj_paragraph_level_0">CNN 不适合识别裁剪后的图像，所以要把识别图像剪切放大、旋转让它训练识别</p>
<h3 class="xsj_heading_hash xsj_heading xsj_heading_h3" id="1020e887aae6b3a8e6848fe58a9be69cbae588b620self-attention20e4b88a_21"><div class="xiaoshujiang_element xsj_anchor">
  <a name="1020e887aae6b3a8e6848fe58a9be69cbae588b620self-attention20e4b88a_21" class="blank_anchor_name"></a><a id="1020e887aae6b3a8e6848fe58a9be69cbae588b620self-attention20e4b88a_21" class="blank_anchor_id"></a><a name="10-自注意力机制-self-attention-上" class="blank_anchor_name"></a><a id="10-自注意力机制-self-attention-上" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">10. 自注意力机制 (Self-attention) (上)</span></h3>
<p class="xsj_paragraph xsj_paragraph_level_0">为了解决：输入是一个向量且大小会改变</p>
<h4 class="xsj_heading_hash xsj_heading xsj_heading_h4" id="sequence20labeling_22"><div class="xiaoshujiang_element xsj_anchor">
  <a name="sequence20labeling_22" class="blank_anchor_name"></a><a id="sequence20labeling_22" class="blank_anchor_id"></a><a name="sequence-labeling" class="blank_anchor_name"></a><a id="sequence-labeling" class="blank_anchor_id"></a>
</div>
<span class="xsj_heading_content">Sequence Labeling</span></h4>
<p class="xsj_paragraph xsj_paragraph_level_0">输入与输出是相同</p>
</div>

</div></div>
</body>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry></feed>