{
  "updated_at": "2026-10-20T22:34:39Z",
  "series": [
    {
      "source_excel_row": 132,
      "source_url": "https://nlp.elvissaravia.com/p/ai-agents-weekly",
      "items": [
        {
          "url": "https://nlp.elvissaravia.com/p/ai-agents-weekly",
          "status": "http_404"
        }
      ],
      "updated_at": "2026-10-14T11:43:08Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1602,
      "source_url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/",
      "items": [
        {
          "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/",
          "status": "ok",
          "article_id": "1cc4df7eb2c7",
          "local_path": "series-follow/1602/repair/caf69956cb5cfd00e2de.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/EDA-exp1.png",
              "bytes": 299081,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b1e26be047c763592a3a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen.png",
              "bytes": 178022,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/364dc68a08807b5baf8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen-exp.png",
              "bytes": 979053,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2a8613e8ff2f07c9bbde.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/LAMBADA.png",
              "bytes": 163034,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1e49c821edae4f24f95b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG.png",
              "bytes": 396874,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/773377f93dad7a113410.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG-exp.png",
              "bytes": 103983,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/82e84409bcacc2fc600e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen.png",
              "bytes": 161004,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3800c7c1476957d08f84.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen-exp.png",
              "bytes": 107466,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9ca541330b72888db6f9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/affinity-diversity.png",
              "bytes": 257673,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6945c914870c32780b47.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/noise-adaptation-layer.png",
              "bytes": 193590,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1e20893406355a07939d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GLC.png",
              "bytes": 283685,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6185b7cd92536235d8de.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-backprop.png",
              "bytes": 241069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/67e6e4a22214ef58e33c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-exp.png",
              "bytes": 812915,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7d52e35a3da415faf3df.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/MentorNet.png",
              "bytes": 260104,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e2db6011ba9c735f3718.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/co-teaching.png",
              "bytes": 313297,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cb3814a9fb4722b3289a.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 3: Data Generation",
            "keywords": "数据增强,合成数据,生成",
            "domain": "数据处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/",
            "publish_date": "2022-04",
            "corpus_stage": "数据处理",
            "notes": "数据生成系列综述之三",
            "id": "1cc4df7eb2c7",
            "collected_at": "2026-10-02T14:13:06",
            "title": "Learning with not Enough Data Part 3: Data Generation | Lil'Log",
            "body_markdown": "Here comes the Part 3 on learning with not enough data (Previous:\nPart 1\nand\nPart 2\n). Let’s consider two approaches for generating synthetic data for training.\nAugmented data\n. Given a set of existing training samples, we can apply a variety of augmentation, distortion and transformation to derive new data points without losing the key attributes. We have covered a bunch of augmentation methods on text and images in a\nprevious post\non contrastive learning. For the sake of post completeness, I\nduplicate\nthe section on data augmentation here with some edits.\nNew data\n. Given few or even no data points, we can rely on powerful pretrained models to generate a number of\nnew\ndata points. This is especially true in recent years given the fast progress in large pretrained\nlanguage models (LM)\n. Few shot prompting is shown to be effective for LM to learn within context without extra training.\nData Augmentation\n#\nThe goal of data augmentation is to modify the input format (e.g. text wording, visual appearance) while the semantic meaning stays unchanged.\nImage Augmentation\n#\nBasic Image Processing Operations\n#\nThere are several ways to modify an image while retaining its semantic information. We can use any one of the following augmentation or a composition of multiple operations.\nRandom cropping and then resize back to the original size.\nRandom color distortions\nRandom Gaussian blur\nRandom color jittering\nRandom horizontal flip\nRandom grayscale conversion\nAnd many more. Check\nPIL.ImageOps\nfor inspiration.\nTask-Specific Augmentation Strategies\n#\nIf the downstream task is known, it is possible to learn the optimal augmentation strategies (i.e. what processing operations to use and how to combine them in sequence) to maximize the downstream task performance.\nAutoAugment\n(\nCubuk, et al. 2018\n) is inspired by\nneural architecture search\n, AutoAugment frames the problem of learning best data augmentation operations (i.e. shearing, rotation, invert, etc.) for image classification as an RL problem and looks for the combination that leads to the highest accuracy on the evaluation set. AutoAugment can be executed in adversarial fashion (\nZhang, et al 2019\n).\nRandAugment\n(\nCubuk et al., 2019\n) greatly reduces the search space of AutoAugment by controlling the magnitudes of different transformation operations with a single magnitude parameter.\nPopulation based augmentation\n(PBA;\nHo et al., 2019\n) combines PBT (“population based training”;\nJaderberg et al, 2017\n) with AutoAugment, using the evolutionary algorithm to train a population of children models in parallel to evolve the best augmentation strategies.\nUnsupervised Data Augmentation\n(UDA;\nXie et al., 2019\n), among a set of possible augmentation strategies, selects a subset to minimize the KL divergence between the predicted distribution over an unlabelled example and its unlabelled augmented version.\nImage Mixture\n#\nImage mixture methods can construct new training examples from existing data points.\nMixup\n(\nZhang et al., 2018\n) runs global-level mixture by creating a weighted pixel-wise combination of two existing images $I_1$ and $I_2$: $I_\\text{mixup} \\gets \\alpha I_1 + (1-\\alpha) I_2$ and $\\alpha \\in [0, 1]$.\nCutmix\n(\nYun et al., 2019\n) does region-level mixture by generating a new example by combining a local region of one image with the rest of the other image. $I_\\text{cutmix} \\gets \\mathbf{M}_b \\odot I_1 + (1-\\mathbf{M}_b) \\odot I_2$, where $\\mathbf{M}_b \\in \\{0, 1\\}^I$ is a binary mask and $\\odot$ is element-wise multiplication. It is equivalent to filling the\ncutout\n(\nDeVries & Taylor 2017\n) region with the same region from another image.\nGiven a query $\\mathbf{q}$,\nMoCHi\n(“mixing of contrastive hard negatives”;\nKalantidis et al. 2020\n) maintains a queue of $K$ negative features $Q={\\mathbf{n}_1, \\dots, \\mathbf{n}_K }$ and sorts these negative features by similarity to the query, $\\mathbf{q}^\\top \\mathbf{n}$, in descending order. The first $N$ items in the queue are considered as the hardest negatives, $Q^N$. Then synthetic hard examples can be generated by $\\mathbf{h} = \\tilde{\\mathbf{h}} / |\\tilde{\\mathbf{h}}|_2$ where $\\tilde{\\mathbf{h}} = \\alpha\\mathbf{n}_i + (1-\\alpha) \\mathbf{n}_j$ and $\\alpha \\in (0, 1)$. Even harder examples can be created by mixing with the query feature, $\\mathbf{h}’ = \\tilde{\\mathbf{h}’} / |\\tilde{\\mathbf{h}’}|_2$ where $\\tilde{\\mathbf{h}’} = \\beta\\mathbf{q} + (1-\\beta) \\mathbf{n}_j$ and $\\beta \\in (0, 0.5)$.\nText Augmentation\n#\nLexical Edits\n#\nEasy Data Augmentation\n(EDA;\nWei & Zou 2019\n) defines a set of simple but powerful operations for text augmentation. Given a sentence, EDA randomly chooses and applies one of four simple operations:\nSynonym replacement (SR): Replace $n$ random non-stop words with their synonyms.\nRandom insertion (RI): Place a random synonym of a randomly selected non-stop word in the sentence at a random position.\nRandom swap (RS): Randomly swap two words and repeat $n$ times.\nRandom deletion (RD): Randomly delete each word in the sentence with probability $p$.\nwhere $p=\\alpha$ and $n=\\alpha \\times \\text{sentence_length}$, with the intuition that longer sentences can absorb more noise while maintaining the original label. The hyperparameter $\\alpha$ roughly indicates the percent of words in one sentence that may be changed by one augmentation.\nEDA is shown to improve the classification accuracy on several classification benchmark datasets compared to baseline without EDA. The performance lift is more significant on a\nsmaller\ntraining set. All the four operations in EDA help improve the classification accuracy, but get to optimal at different $\\alpha$’s.\nEDA leads to performance improvement on several classification benchmarks. (Image source:\nWei & Zou 2019\n)\nContextual\nAugmentation (\nKobayashi, 2018\n) replaces word $w_i$ at position $i$ by sampling from a probability distribution learned by a bidirectional LM such as BERT, $p(.\\mid S\\setminus{w_i})$. In this way, the words are substituted by synonyms, or similar words suitable for the context. To guarantee such operations do not alter the labels, the LM is fit to be label-conditioned bidirectional LM. Conditional BERT (CBERT;\nXing Wu et al. 2018\n) extends BERT to predict masked tokens conditioned on the class label and can be used for contextual augmentation prediction.\nBack-translation\n#\nBack-translation\nproduces augmented data by translating text samples to another language and then translating them back. The translation happens in two ways and both directions should have decent enough performance to avoid significant loss of semantic meaning.\nMix-up\n#\nIt is also possible to apply\nMixup\nto text (\nGuo et al. 2019\n) but on the embedding space to obtain some performance gain. The proposed method relies on a specially designed model architecture to operate the prediction on the word or sentence embedding. Adding adversarial noise in the embedding space as a way of data augmentation is shown to improve the generalization of model training (\nZhu et al. 2019\n).\nAudio Augmentation\n#\nHere is a list of several commonly used audio data augmentation methods, operated on raw audio or spectrograms, summarized by\nWang & van den Oord (2021)\n.\nAudio mixup.\nGiven two audio clips $\\mathbf{x}_1$ and $\\mathbf{x}_2$, the mixed-up version $\\hat{\\mathbf{x}} = \\alpha \\mathbf{x}_1 + (1-\\alpha)\\mathbf{x}_2$ should be associated with the label of the more dominant input. The audio mixup augments the data with more realistic noise.\nTime masking.\nA small consecutive chunk of the audio can be masked without losing semantic information.\nFrequency masking.\nA small amount of frequency components on the spectrogram can be dropped off and it should not change the associated label.\nFrequency shift.\nThe spectrogram can be shifted by an integer between $[-F, F]$, where $F$ is the maximum shift size. It is a cheap augmentation to change the pitch of the audio.\nArchitectural Augmentation\n#\nModels with\ndropout\nlayers can create augmented samples by applying different dropout masks on the same input sample. For example, in the contrastive learning model\nSimCSE\n(\nGuo et al. 2021\n), a sample is simply fed into the encoder twice with different dropout masks and these two versions are the positive pair where the other in-batch samples are considered as negative pairs.\nDropout augments data by adding noise onto the internal representation of the model. It can be applied in a more structured way, such as in\ncutoff\n(\nShen et al. (2020)\n), where random chunks of the token embedding matrix are removed.\nData Synthesis\n#\nGiven that generating high-quality, photorealistic images is a lot more difficult than generating human-like natural language text and recent success with large pretrained language models, this section only focuses on text generation. To read more on how to synthesize realistic images, check posts on\nGAN\n,\nVAE\n,\nflow\nand\ndiffusion\nmodels.\nLanguage Model as Noisy Annotator\n#\nWang et al. (2021)\nexplored ways to leverage GPT-3 as a weak annotator via few-shot prompting, achieving 10x cheaper than human labeling. The paper argues that by using data labeled by GPT-3, it essentially performs\nself-training\n: The predictions on unlabeled samples apply entropy regularization on the model to avoid high class overlaps so as to help improve the model performance.\nIllustration of how to use GPT-3 to generate more training data with the human-in-the-loop active learning pipeline to improve the data quality. (Image source:\nWang et al. 2021\n)\nGPT-3-labeled samples selected by\nactive learning\nwith highest uncertainty are sent to human labelers to be re-annotated. The few-shot prompt contains a small number of human labeled examples and thus the labeling cost is restricted. Synthetic samples are ranked by predicted logits of label $y$ and those with the lowest scores go through relabeling.\nGPT-3 labeling achieves better results in the low-cost regime, but has a gap with human labeling when enough money is spent on data collection. This implies the following inequation, although to what extent “a lot” or “noisy” means depends on the task details.\nA lot of high-quality data > A lot of noisy data > A little high quality data\n.\nGPT-3 labeling technique improves the classification performance in the low-cost regime. (Image source:\nWang et al. 2021\n)\nLanguage Model as Data Generator\n#\nIf enough training dataset for text classification tasks are available, we can fine-tune language models to synthesize more training samples conditioned on labels (\nAnaby-Tavor et al. 2019\n,\nKumar et al. 2021\n).\nLanguage-model-based data augmentation\n(\nLAMBADA\n;\nAnaby-Tavor et al. 2019\n) takes such an idea, where the process involves fine-tuning both a classifier and a sample generation model.\nTrain a baseline classifier using the existing training dataset: $h = \\mathcal{A}(\\mathcal{D}_\\text{train})$.\nIndependently of step 1, a LM $\\mathcal{M}$ is fine-tuned on $\\mathcal{D}_{\\text{train}}$ to obtain $\\mathcal{M}_{\\text{tuned}}$.\nSynthesize a labeled dataset $\\mathcal{D}^*$ by generating the continuation of the sequence\ny[SEP]\nuntil\nEOS\nusing $\\mathcal{M}_\\text{tuned}$.\nFilter synthesized dataset by,\n(1) Verifying that the predicted label is correct $h(x)=y$;\n(2) Selecting the top ranked samples when they are ranked by the classifier probability. $\\mathcal{D}_\\text{syn} \\subset \\mathcal{D}^*$. They generate 10x more samples needed for augmentation and only the top 10% synthesized samples with highest confidence scores remain.\nThe final classifier is trained on $\\mathcal{D}_\\text{syn} \\cup \\mathcal{D}_\\text{train}$ . The process can be repeated multiple times, but it is unclear whether the benefit would quickly diminish or the repetitive process would bring in self-bias.\nAccuracy of LAMBADA vs. other generative approaches over all datasets and classifiers. (Image source:\nAnaby-Tavor et al. 2019\n)\nTo simplify LAMBADA,  we can actually remove the dependency of a fine-tuned generation model  and an existing training dataset of a decent size (\nStep 2\nabove).\nUnsupervised data generation\n(\nUDG\n;\nWang et al. 2021\n) relies on few-shot prompting on a large pretrained language model to generate high-quality synthetic data for training. Opposite to the above approach where LM is asked to predict $y$ given $\\mathbf{x}$, UDG instead synthetizes the inputs $\\mathbf{x}$ given labels $y$. Then a task-specific model is trained on this synthetic dataset.\nSchick & Schutze (2021)\nproposed a similar idea but on the NLI task instead of classification, asking PLM to write sentence pairs that are similar or different while the model is prompted with task-specific instructions.\nIllustration of the unsupervised data generation (UDG) framework. (Image source:\nWang et al., 2021\n)\nThe few-shot prompts of UDG contain a small number of unlabeled examples, as well as a task-specific natural language description of the desired label. Because some generated examples are noisy, they implemented\nnoisy label annealing\n(\nNLA\n) techniques to filter potentially misaligned samples out during the training processes. NLA gradually removes noisy training signals in time during training when the model starts to disagree with its pseudo label with high confidence. At each training step $t$, a given example $(\\mathbf{x}_i, \\hat{y}_i)$ is considered noisy and should be removed if:\nThe model predicted probability is higher than a threshold $p(\\bar{y}_i \\vert \\mathbf{x}_i) > \\mu_t$ where $\\bar{y}_i = \\arg\\max_y p(y \\vert \\mathbf{x}_i)$;\nAnd the predicted label is different from the synthetic label, $\\bar{y}_i \\neq \\hat{y}_i$.\nNote that the threshold $\\mu_t$ is time-dependent, initialized as 0.9 and then gradually annealed to $1/\\text{num_of_classes}$ in time.\nAs shown in their experiments, the improvement of UDG over few-shot inference is quit significant, where NLA brings in some extra boost. The results are even comparable with supervised fine-tuning on several cases.\nComparison of accuracy of UDG and other methods on different classification datasets. (Image source:\nWang et al., 2021\n)\nHan et al (2021)\nachieved SOTA results on translation tasks using few-shot data generation, distillation and back-translation. The proposed method contains the following steps, assuming no access to paired translation data:\nZero-shot Generation.\nFirst use the zero-shot translation ability of a pre-trained LM to generate translations for a small set of unlabeled sentences.\nFew-shot Generation.\nThen amplify these zero-shot translations by using them as few-shot demonstrations to gather an even larger synthetic dataset.\nDistillation.\nFine-tune the model on this dataset. The translation task is formulated as a language modeling task\n[L1] <seq1> [[TRANSLATE]] [L2] <seq2>.\ngiven a pair of two sequences\n<seq1, seq2>\nin two different languages. At test-time, the LM is prompted with\n[L1] <seq> [[TRANSLATE]] [L2]\nand a candidate translation\n<sampledSeq>\nis parsed from the sampled completion.\nBack-translation.\nContinue fine-tuning on the back-translation dataset where the order of samples is reversed,\n<sampledSeq, seq>\n.\nStep 1-4 can be repeated.\nAlgorithm of using distillation and back-translation to train a language model on translation tasks. (Image source:\nHan et al. 2021\n)\nThe success of the above method depends on a good pretrained LM to kick off the initial translation dataset. Iterative few-shot generation and distillation with back-translation is an effective way to extract and refine the translation capability out of a pretrained LM and further to distill that into a new model.\nComparison of BLEU scores of the translation models of different training runs using: only distillation, back-translation, both and with more monolingual training data. (Image source:\nHan et al. 2021\n)\nHow to Quantify Generated Data Quality?\n#\nGiven all the generated data, either by data augmentation or data synthesis, how can we quantify data quality in terms of how they improve model generalization?\nGontijo-Lopes et al. (2020)\nintroduced two dimensions to track, affinity and diversity.\nAffinity\nis a model-sensitive metric for\ndistribution shift\n, quantifying how much an augmentation shifts the training data distribution from what a model learned.\nDefinition: The performance difference between the model tested on clean data vs augmented data, while the model is trained on clean data.\nAs a comparison, KL can also measure distribution shift but does not consider the model performance.\nDiversity\nis a measure of\naugmentation complexity\n, measuring the complexity of the augmented data with respect to the model and learning procedure.\nDefinition: The final training loss of a model trained with a given augmentation.\nAnother potential diversity measure is the entropy of the transformed data.\nA third potential diversity measure is the training time needed for a model to reach a given training accuracy threshold.\nAll three metrics above are correlated.\nThe final model performance is dependent on both metrics to be high enough.\n(a) Left: A scatter plot of affinity vs diversity metric, where each point represents a different augmentation method and its color indicates the final test accuracy. (b) Right: The conceptual illustration of the relationship between clean and augmented data in different regions of affinity and diversity metrics. (Image source:\nGontijo-Lopes et al. 2020\n)\nThere are many quantitative metrics on relevancy and diversity, in different formations depending on whether a reference is available, such as perplexity, BLEU for text and inception score for images. I’m skipping the list of concrete quantitative metrics on quality here, given it could be very long.\nTraining with Noisy Data\n#\nIt is convenient to collect a large amount of noisy data via model generation or data augmentation, but it is hard to guarantee that augmented and generated data can be 100% accurate. Knowing that deep neural networks can easily overfit noisy labels and “memotize” corrupted labels, we can apply the techniques for training on noisy labels (\nnoise-robust training\n) when using generated data to stabilize and optimize the performance. Please check this\nsurvey paper (Song et al. 2021)\non learning from noisy labels for a more thorough coverage of related work.\nRegularization and Robust Architecture\n#\nGenerally speaking, mechanisms designed for avoiding overfitting should help improve training robustness when working with moderately noisy data, such as weight decay, dropout, batch normalization. In fact, good data augmentation (i.e. only non-essential attributes are modified) can be considered as a way of regularization as well.\nA different approach is to enhance the network with a dedicated\nnoisy adaptation layer\nto approximate the unknown projection of label corruption (\nSukhbaatar et al. 2015\n,\nGoldberger & Ben-Reuven, 2017\n).\nSukhbaatar et al. (2015)\nintroduced an extra linear layer $Q$ into the network architecture to adapt the predictions to match the noisy label distribution. The noise matrix $Q$ is initially\nfixed\nto the identity function while only the base model parameters is updated. After some time, $Q$ starts to be updated and expected to capture the noise in the data. The noise matrix is trained with regularization to encourage it to match the noise distribution while keeping the base model prediction accurate for true labels.\n(a) Left: A noise matrix $Q$ is added between softmax and the final output for the loss. (b) Right: The noise matrix $Q$ is fixed at the identity function initially and only gets updated with regularization after some training. (Image source:\nSukhbaatar et al. 2015\n)\nHowever, it is hard to guarantee such a noise matrix layer would only capture the noise transition distribution and it is actually non-trivial to learn.\nGoldberger & Ben-Reuven (2017)\n)  proposed to add an additional softmax layer end-to-end with the base model and apply the\nEM algorithm\nby treating the correct labels as latent random variable and the noise processes as a communication channel with unknown parameters.\nRobust Learning Objective\n#\nBesides the most commonly used cross entropy loss, some other choices of learning objectives are shown to be more robust to noisy labels.\nFor example,\nMAE\n(mean absolute error) is more robust to noisy labels than CCE (categorical cross entropy), as it treats every sample equally (\nGhosh et al. 2017\n). Lack of different weighting among training samples of MAE lead to significantly longer training time. Motivated by the tradeoff between MAE and CCE,\nZhang & Sabuncu (2018)\nproposed\ngeneralized cross entropy\n(\nGCE\n), a generalization of CCE loss to be robust to noisy data.\nTo exploit the benefits of both the noise-robustness provided by MAE and the implicit weighting scheme of CCE, GCE adopts the the negative Box-Cox transformation as a loss function:\n$$\n\\mathcal{L}_q(f(\\mathbf{x}_i, y_i = j)) = \\frac{1 - f^{(j)}(\\mathbf{x}_i)^q}{q}\n$$\nwhere $f^{(j)}$ denotes the $j$-th element of $f(.)$ and $q \\in (0, 1]$.\n$\\mathcal{L}_q$ is equivalent to CCE when $q \\to 0$ and becomes MAE when $q=1$. Empirical experiments show that there exists a threshold of $q$ with which overfitting never emerges and the noisier the data the higher such a threshold should be.\nGiven true and predicted labels, $y_i, \\hat{y}_i \\in \\{0, 1\\}$ and let $u_i=y_i \\cdot \\hat{y}_i$, the\nzero-one loss\n, $\\mathcal{L}_{01}(\\mathbf{u}) = \\sum_{i=1}^n \\mathbb{1}[u_i < 0]$, is another learning subjective shown to be robust to noisy data. Minimizing the empirical risk with the zero-one loss is shown to be equivalent to minimizing the empirical adversarial (worse-case) risk (\nHu et al 2018\n). Because the worst-case risk is the upper bound of the classification risk of the clean data distribution, minimizing the worst-case risk can lead to decreased true risk, which makes the zero-one loss especially robust. However, the zero-one loss is non-differentiable and cannot be optimized directly. One solution is to approximate an\nupper bound\nof the zero-one loss and to minimize the upper bound loss instead.\nThe\nhinge loss\n, $\\mathcal{L}_\\text{hinge}(\\mathbf{u}) = \\sum_{i=1}^n \\max(0, 1 - u_i)$, defines a rough upper bound of the zero-one loss.\nLyu & Tsang (2020)\nproposed a\ncurriculum loss\n(\nCL\n), which is a tighter upper bound compared to a conventional surrogate loss like the hinge loss, $\\mathcal{L}_\\text{01}(\\mathbf{u}) \\leq \\mathcal{L}_\\text{CL}(\\mathbf{u}) \\leq \\mathcal{L}_\\text{hinge}(\\mathbf{u})$.\n$$\n\\mathcal{L}_\\text{CL}(\\mathbf{u}) = \\min_{\\mathbf{w}\\in\\{0,1\\}^n}\\max(\\sum_{i=1}^n w_i \\ell(u_i), n - \\sum_{i=1}^n w_i + \\sum_{i=1}^n\\mathbb{1}[u_i < 0])\n$$\nwhere $\\ell(u_i)$ is a base surrogate loss for the zero-one loss (e.g. hinge loss) and the optimal weighting variable $\\mathbf{w}$ is to be learned.\nGiven a label corruption rate $\\rho$, the\nnoise pruned curriculum loss\n(\nNPCL\n) is constructed based on the intuition that an ideal model should correctly classify $n(1-\\rho)$ samples with clean labels but misclassify $n\\rho$ corrupted labels. If $\\rho$ is a known prior, we would know how many samples (with largest losses) to be pruned. Assuming $\\ell(u_1) \\leq \\dots \\leq \\ell(u_n)$, then $u_{n(1-\\rho)+1} = \\dots = u_n =0$ and the following NPCL is the basic CL for only $n(1-\\rho)$ samples:\n$$\n\\text{NPCL}(\\mathbf{u}) = \\min_{\\mathbf{w}\\in\\{0,1\\}^{n(1-\\rho)}} \\max(\\sum_{i=1}^{n(1-\\rho)} w_i \\ell(u_i), n(1-\\rho) - \\sum_{i=1}^{n(1-\\rho)} w_i)\n$$\nWhen experimenting on CIFAR-10, NPCL is comparable with GCE and performs better when the noise rate increases.\nLabel Correction\n#\nSince it is known some labels are incorrect, noise-robust training can explicitly take the label correction into consideration.\nOne approach is to rely on the estimation of a noise transition matrix and use that to correct the forward or backward loss, named\nF-correction\n(\nPatrini et al. 2017\n). Let’s first assume that there are $k$ classes and the noise transition matrix $C \\in [0, 1]^{k\\times k}$ is observable and the label flipping probability does not depend on the sample input but only the label (i.e. known as random classification noise, RCN). Let $\\tilde{y}$ denote a corrupted label. Each entry of $C$ represents the probability of one label flipping to another\n1\n,\n$$\nC_{ij} = p(\\tilde{y}= j \\vert y =i, \\mathbf{x}) \\approx p(\\tilde{y}= j \\vert y =i)\n$$\nThen we can proceed a forward label correction procedure to incorporate the prior knowledge of noisy transition matrix into the prediction.\n$$\n\\begin{aligned}\n\\mathcal{L}(\\hat{p}(\\tilde{y}\\vert\\mathbf{x}), y)\n&= - \\log \\hat{p}(\\tilde{y}=i\\vert\\mathbf{x}) \\\\\n&= - \\log \\sum_{j=1}^k p(\\tilde{y}=i\\vert y=j) \\hat{p}(y=j\\vert\\mathbf{x}) \\\\\n&= - \\log \\sum_{j=1}^k C_{ji} \\hat{p}(y=j\\vert\\mathbf{x})\n\\end{aligned}\n$$\nIn matrix form, we have $\\mathcal{L}(\\hat{p}(y \\vert \\mathbf{x})) = - \\log C^\\top \\hat{p}(y \\vert \\mathbf{x})$. However, such a noise transition matrix is usually\nunknown\n. If we have access to a clean dataset, the noise matrix $C$ can be estimated (\nHendrycks et al. 2018\n) by calculating confusion matrix on the clean data. Let’s denote a clean trusted dataset as $\\mathcal{D}_c$ and a noisy dataset as $\\mathcal{D}_n$ going forward.\n$$\n\\hat{C}_{ij}\n= \\frac{1}{\\vert \\mathcal{A}_i\\vert} \\sum_{\\mathbf{x} \\in \\mathcal{A}_i} \\hat{p}(\\tilde{y}=j \\vert y=i, \\mathbf{x})\n\\approx p(\\tilde{y}=j \\vert y=i)\n$$\nwhere $\\mathcal{A}_i$ is a subset of data points from $\\mathcal{D}_c$ with label $i$.\nLet $f(x) = \\hat{p}(\\tilde{y} \\vert \\mathbf{x}; \\theta)$ and this model should be trained with $\\mathcal{L}(f(\\mathbf{x}), y)$ on clean data $\\mathcal{D}_c$ and with $\\mathcal{L}(\\hat{C}^\\top f(\\mathbf{x}), \\hat{y})$ on noisy data $\\mathcal{D}_n$.\nAlgorithm of gold loss correction (GLC), estimating the noise transition matrix with a trusted dataset. (Image source:\nHendrycks et al. 2018\n)\nIf the trusted training dataset $\\mathcal{D}_c$ gets large, we can train a neural network only on clean data and\ndistill\nits knowledge into the primary model (i.e. the final model to make predictions at test time) using corrected\npseudo labels\n(\nLi et al. 2017\n). The primary model is trained on the entire dataset, $\\mathcal{D} = \\mathcal{D}_c \\cup \\mathcal{D}_n$. Optionally the “side” information of label relations in the knowledge graph, if available, can be incorporated into distillation to help the robustness of the predictions of the network that is trained on limited data.\nThe label correction distillation works as following:\nFirst train an auxiliary model $f_c$ from the small clean dataset $\\mathcal{D}_c$ to provide a soft label for each sample $x_i$, $s_i = \\delta(f_c(\\mathbf{x}_i)/T)$ is the sigmoid activation with temperature $T$.\nBecause the clean dataset is not large, $f_c$ is likely to overfit,\nLi et al. (2017)\nturn to a knowledge graph $\\mathcal{G}$ that defines the relations in the label space and\npropagate\nthe prediction among labels accordingly. The new soft label is donated as $\\hat{s}_i = \\mathcal{G}(s_i)$.\nThe primary model $f$ is trained with predictions from $f_c$ to imitate,\n$$\n\\mathcal{L}(y_i, f(\\mathbf{x}_i)) = \\text{CE}(\\underbrace{\\lambda y_i + (1 - \\lambda) \\hat{s}_i}_\\text{pseudo label}, f(\\mathbf{x}_i))\n$$\nSample Reweighting and Selection\n#\nSome samples may be more likely to have inaccurate labels than others. Such estimation gives us intuition on which samples should be weighted less or more in the loss function. However, considering two types of biases in training data, class imbalance and noisy labels, there is actually a contradictory preference — We would prefer samples with larger loss to balance the label distribution but those with smaller loss for mitigating the potential noise. Some work (\nRen et al. 2018\n) thus argue that in order to learn general forms of training data biases, it is\nnecessary\nto have\na small unbiased validation\nto guide training. The sample reweighting methods presented in this section all assume access to a small trusted set of clean data.\nConsidering a binary classification task with random classification noise, $y, \\hat{y} \\in \\{-1, +1\\}$, the label flipping probabilities, $\\rho_{-1}, \\rho_{+1} \\in [0, 0.5)$, are defined as:\n$$\n\\rho_{-1} = P(\\tilde{y} = +1 \\vert y=-1)\\quad\\rho_{+1} = P(\\tilde{y}=-1 \\vert y =+1)\n$$\nLiu & Tao (2015)\napplies\nimportance reweighting\nto adjust the weighted distribution of observed $\\hat{y}$ to match the distribution of unobservable $y$. Let $\\mathcal{D}$ be the true data distribution and $\\mathcal{D}_\\rho$ be the corrupted version.\n$$\n\\begin{aligned}\n\\mathcal{L}_{\\ell,\\mathcal{D}}(f)\n&= \\mathbb{E}_{(\\mathbf{x},y)\\sim \\mathcal{D}}[\\ell(f(\\mathbf{x}), y)] \\\\\n&= \\mathbb{E}_{(\\mathbf{x},\\tilde{y})\\sim \\mathcal{D}_\\rho} \\Big[ \\frac{P_\\mathcal{D}(\\mathbf{x}, y=\\tilde{y})}{P_{\\mathcal{D}_\\rho}(\\mathbf{x}, \\tilde{y})} \\ell(f(\\mathbf{x}), \\tilde{y}) \\Big] \\\\\n&= \\mathbb{E}_{(\\mathbf{x},\\tilde{y})\\sim \\mathcal{D}_\\rho} \\Big[ \\frac{P_\\mathcal{D}(y=\\tilde{y} \\vert \\mathbf{x})}{P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x})} \\ell(f(\\mathbf{x}), \\tilde{y}) \\Big] & \\text{; because }P_\\mathcal{D}(\\mathbf{x})=P_{\\mathcal{D}_\\rho}(\\mathbf{x}) \\\\\n&= \\mathbb{E}_{(\\mathbf{x},\\tilde{y})\\sim \\mathcal{D}_\\rho} [ w(\\mathbf{x}, \\hat{y})\\ell(f(\\mathbf{x}), \\tilde{y}) ]\n= \\mathcal{L}_{w\\ell,\\mathcal{D}}(f)\n\\end{aligned}\n$$\nBecause,\n$$\n\\begin{aligned}\nP_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x})\n&= P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x}) P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert y=\\tilde{y}) +\nP_\\mathcal{D}(y = - \\tilde{y} \\vert \\mathbf{x}) P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert y = - \\tilde{y}) \\\\\n&= P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x}) (1 - P_{\\mathcal{D}_\\rho}(- \\tilde{y} \\vert y=\\tilde{y})) +\n(1 - P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x})) P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert y = - \\tilde{y}) \\\\\n&= P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x}) (1 - \\rho_{\\tilde{y}}) +\n(1 - P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x})) \\rho_{-\\tilde{y}} \\\\\n&= P_\\mathcal{D}(y = \\tilde{y} \\vert \\mathbf{x})(1 - \\rho_{\\tilde{y}} - \\rho_{-\\tilde{y}}) + \\rho_{-\\tilde{y}}\n\\end{aligned}\n$$\nThus the weight assigned to a noisy sample is,\n$$\nw(x, \\tilde{y})\n= \\frac{P_\\mathcal{D}(y=\\tilde{y} \\vert \\mathbf{x})}{P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x})}\n= \\frac{P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x}) - \\rho_{-\\tilde{y}}}{(1-\\rho_0-\\rho_1) P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x})}\n$$\nwhere $P_{\\mathcal{D}_\\rho}(\\tilde{y} \\vert \\mathbf{x})$ can be estimated using a simple logistic regression, but estimating the note rates is more challenging. Naive cross-validation can work out but is costly as the quality depends on the amount of trusted labels available. The paper approximates the upper bounds for noise rates first, $\\rho_\\tilde{y} \\leq P_{\\mathcal{D}_\\rho}(- \\tilde{y} \\vert \\mathbf{x})$ and then use a mild assumption to efficiently estimate them, $\\hat{\\rho}_{\\tilde{y}} = \\min_{\\mathbf{x} \\in {\\mathbf{x}_1, \\dots, \\mathbf{x}_n}} \\hat{P}_{\\mathcal{D}_\\rho}(- \\tilde{y} \\vert \\mathbf{x})$. In their experiments, the advantage of importance reweighting only varies across datasets and is more beneficial when the noise rates are high in general.\nSample reweighting schemes can be learned by a separate network.\nLearning to reweight\n(\nL2R\n;\nRen et al. 2018\n) is a meta-learning approach to directly optimize the weights in pursuit of best validation performance on a known set of clean data. Each example gets assigned with the weight based on its gradient direction. The weighted loss to minimize $\\theta^*(\\mathbf{w})$ involves a set of training weights $\\{w_i\\}_{i=1}^n$ as unknown hyperparameters. These sample training weights $w_i$ are learned to minimize the loss on this unbiased validate set, $\\mathcal{D}_c = \\{x^\\text{valid}_j\\}_{j=1}^m$.\n$$\n\\begin{aligned}\n\\theta^{*}(\\mathbf{w}) &= \\arg\\min_\\theta \\sum_{i=1}^n w_i f(x_i; \\theta) \\\\\n\\text{where optimal }\\mathbf{w}^{*} &= \\arg\\min_{\\mathbf{w}, \\mathbf{w} \\geq \\mathbf{0}} \\frac{1}{m} \\sum_{j=1}^m f(\\mathbf{x}^\\text{valid}_j; \\theta^{*}(\\mathbf{w}))\n\\end{aligned}\n$$\nThe learning process involves two nested loops of optimization, so pretty expensive, 3x training time.\nIllustration of updates implemented by second order\nautomatic differentiation\n. (Image source:\nRen et al. 2018\n)\nThey ran experiments on (1) two-class MNIST to test the robustness of L2R when the class distribution is imbalanced and (2) CIFAR-10 with noisy labels.  L2R is shown to be better than other baseline methods at the time on both tasks.\nLeft: Imbalanced classes on MNIST (class 4 and 9); Right: Effect of the number of clean samples. Task is on CIFAR-10 with 40% of data flipped to label 3. (Image source:\nRen et al. 2018\n)\nMentorNet\n(\nJiang et al. 2018\n) uses teach-student curriculum learning to weight data. It incorporates two different networks, a mentor and a student. The mentor network provides a data-driven curriculum (i.e. sample training weighting scheme) for the student to focus on learning likely correct labels.\nLet $g_\\psi$ be the MentorNet parameterized by $\\psi$ , $f_\\theta$  be the StudentNet parametrized by $\\theta$ and $G$ be a predefined curriculum parameterized by $\\lambda$. Given the training data $\\mathcal{D} = \\{(\\mathbf{x}_i, y_i)\\}_{i=1}^n$ for a $k$-class classification task, the MentorNet needs to predict a time-varying latent weight variable $\\mathbf{w} \\in [0, 1]^{n \\times k}$ to guide the learning of StudentNet, taking an intermediate feature processed by StudentNet $f$ , $\\mathbf{z}_i = \\phi_{f_\\theta}(\\mathbf{x}_i, y_i)$:\n$$\ng_{\\psi^{*}}(\\mathbf{z}_i) = \\arg\\min_{w_i \\in [0,1]} \\mathcal{L}(\\theta, \\mathbf{w}), \\forall i \\in [1, n]\n$$\nStudentNet learns to minimize the following learning objective,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta, \\mathbf{w})\n&= \\frac{1}{n}\\sum_{i=1}^n \\mathbf{w}_i^\\top \\ell(y_i, f_\\theta(\\mathbf{x}_i)) + G_\\lambda(\\mathbf{w}) + \\alpha |\\theta|^2_2 \\\\\n&= \\frac{1}{n}\\sum_{i=1}^n g_\\psi(\\mathbf{z}_i)^\\top \\ell_i + G_\\lambda(\\mathbf{w}) + \\alpha |\\theta|^2_2 & \\text{; Let }\\ell_i = \\ell(y_i, f_\\theta(\\mathbf{x}_i)) \\\\\n\\end{aligned}\n$$\nThe mentor network $g_\\psi$ is trained with cross entropy on the input $(\\phi_{f_\\theta}(\\mathbf{x}_i, y_i), w^{*}_i)$ , where $v^*_i=1$ if $y_i$ is known to be a correct label, otherwise 0. The architecture of MentorNet does not have to be very complicated. In the paper, they adopted a LSTM layer to capture the prediction variance in time.\nModel architecture of MentorNet and StudentNet which are trained simultaneously, where MentorNet predicts the sample weights for StudentNet to train on. (Image source:\nJiang et al. 2018\n)\nDifferent from MentorNet where one network explicitly learns weighting scheme and curriculum for the other network,\nCo-teaching\n(\nHan et al. 2018\n) trains two neural networks, $f_1$ and $f_2$, simultaneously and lets them teach each other by feeding data to each other selectively. Co-teaching consists of three steps:\nFirst, each network feeds forward the current mini-batch and selects samples with potentially clean labels;\nThen two networks exchange information on which samples in the batch should be used for training.  Small-loss instances are selected as they are more likely to be associated with correct labels. The percentage of the batch to select is determined by a time-dependent function $R(T)$. The value of $R(T)$ decreases in time because the network is more likely to overfit and memorize noisy labels as training progresses and thus we use a smaller sampling percentage to keep the selected data quality high.\nFinally, each network runs back-propagation updates with the data selected by its peer.\nAccording to their experiments, co-teaching performs better than\nF-correction\nwhere the noise rates are high or the corruption transition matrix is not symmetric.\nAlgorithm of co-teaching in which two networks are trained separately in parallel and each selects samples for the other to train on. (Image source:\nHan et al. 2018\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Apr 2022). Learning with not enough data part 3: data generation. Lil’Log. https://lilianweng.github.io/posts/2022-04-15-data-gen/.\nOr\n@article{weng2022datagen,\n  title   = \"Learning with not Enough Data Part 3: Data Generation\",\n  author  = \"Weng, Lilian\",\n  journal = \"Lil'Log\",\n  year    = \"2022\",\n  month   = \"Apr\",\n  url     = \"https://lilianweng.github.io/posts/2022-04-15-data-gen/\"\n}\nReference\n#\n[1] Zhang et al.\n“Adversarial AutoAgument”\nICLR 2020.\n[2] Kumar et al.\n“Data Augmentation using Pre-trained Transformer Models.”\nAACL 2020 Workshop.\n[3] Anaby-Tavor et al.\n“Not enough data? Deep learning to rescue!”\nAAAI 2020.\n[4] Wang et al.\n“Want To Reduce Labeling Cost? GPT-3 Can Help.”\nEMNLP 2021.\n[5] Wang et al.\n“Towards Zero-Label Language Learning.”\narXiv preprint arXiv:2109.09193 (2021).\n[6] Schick & Schutze.\nGenerating Datasets with Pretrained Language Models.\"\nEMNLP 2021.\n[7] Han et al.\n“Unsupervised Neural Machine Translation with Generative Language Models Only.”\narXiv preprint arXiv:2110.05448 (2021).\n[8] Guo et al.\n“Augmenting data with mixup for sentence classification: An empirical study.”\narXiv preprint arXiv:1905.08941 (2019).\n[9] Ekin D. Cubuk et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv preprint arXiv:1805.09501 (2018).\n[10] Daniel Ho et al.\n“Population Based Augmentation: Efficient Learning of Augmentation Policy Schedules.”\nICML 2019.\n[11] Cubuk & Zoph et al.\n“RandAugment: Practical automated data augmentation with a reduced search space.”\narXiv preprint arXiv:1909.13719 (2019).\n[12] Zhang et al.\n“mixup: Beyond Empirical Risk Minimization.”\nICLR 2017.\n[13] Yun et al.\n“CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features.”\nICCV 2019.\n[14] Kalantidis et al.\n“Mixing of Contrastive Hard Negatives”\nNeuriPS 2020.\n[15] Wei & Zou.\n“EDA: Easy data augmentation techniques for boosting performance on text classification tasks.”\nEMNLP-IJCNLP 2019.\n[16] Kobayashi.\n“Contextual Augmentation: Data Augmentation by Words with Paradigmatic Relations.”\nNAACL 2018\n[17] Fang et al.\n“CERT: Contrastive self-supervised learning for language understanding.”\narXiv preprint arXiv:2005.12766 (2020).\n[18] Gao et al.\n“SimCSE: Simple Contrastive Learning of Sentence Embeddings.”\narXiv preprint arXiv:2104.08821 (2020). [\ncode\n]\n[19] Shen et al.\n“A Simple but Tough-to-Beat Data Augmentation Approach for Natural Language Understanding and Generation.”\narXiv preprint arXiv:2009.13818 (2020) [\ncode\n]\n[20] Wang & van den Oord.\n“Multi-Format Contrastive Learning of Audio Representations.”\nNeuriPS Workshop 2020.\n[21] Wu et al.\n“Conditional BERT Contextual Augmentation”\narXiv preprint arXiv:1812.06705 (2018).\n[22 Zhu et al.\n“FreeLB: Enhanced Adversarial Training for Natural Language Understanding.”\nICLR 2020.\n[23] Affinity and Diversity: Quantifying Mechanisms of Data Augmentation\nGontijo-Lopes et al. 2020 (\nhttps://arxiv.org/abs/2002.08973\n)\n[24] Song et al.\n“Learning from Noisy Labels with Deep Neural Networks: A Survey.”\nTNNLS 2020.\n[25] Zhang & Sabuncu.\n“Generalized cross entropy loss for training deep neural networks with noisy labels.”\nNeuriPS 2018.\n[26] Goldberger & Ben-Reuven.\n“Training deep neural-networks using a noise adaptation layer.”\nICLR 2017.\n[27] Sukhbaatar et al.\n“Training convolutional networks with noisy labels.”\nICLR Workshop 2015.\n[28] Patrini et al.\n“Making Deep Neural Networks Robust to Label Noise: a Loss Correction Approach”\nCVPR 2017.\n[29] Hendrycks et al.\n“Using trusted data to train deep networks on labels corrupted by severe noise.”\nNeuriPS 2018.\n[30] Zhang & Sabuncu.\n“Generalized cross entropy loss for training deep neural networks with noisy labels.”\nNeuriPS 2018.\n[31] Lyu & Tsang.\n“Curriculum loss: Robust learning and generalization against label corruption.”\nICLR 2020.\n[32] Han et al.\n“Co-teaching: Robust training of deep neural networks with extremely noisy labels.”\nNeuriPS 2018. (\ncode\n)\n[33] Ren et al.\n“Learning to reweight examples for robust deep learning.”\nICML 2018.\n[34] Jiang et al.\n“MentorNet: Learning data-driven curriculum for very deep neural networks on corrupted labels.”\nICML 2018.\n[35] Li et al.\n“Learning from noisy labels with distillation.”\nICCV 2017.\n[36] Liu & Tao.\n“Classification with noisy labels by importance reweighting.”\nTPAMI 2015.\n[37] Ghosh, et al.\n“Robust loss functions under label noise for deep neural networks.”\nAAAI 2017.\n[38] Hu et al.\n“Does Distributionally Robust Supervised Learning Give Robust Classifiers? “\nICML 2018.\n$y=i$ is not a technically correct way to annotate a label being a certain value, since we usually use one-hot encoding (i.e. $\\mathbf{y} = \\mathbf{e}_i$). We use this form for simplicity.\n↩︎",
            "metadata": {
              "title": "Learning with not Enough Data Part 3: Data Generation | Lil'Log",
              "description": "Here comes the Part 3 on learning with not enough data (Previous: Part 1 and Part 2). Let’s consider two approaches for generating synthetic data for training.\n\nAugmented data. Given a set of existing training samples, we can apply a variety of augmentation, distortion and transformation to derive new data points without losing the key attributes. We have covered a bunch of augmentation methods on text and images in a previous post on contrastive learning. For the sake of post completeness, I duplicate the section on data augmentation here with some edits.\nNew data. Given few or even no data points, we can rely on powerful pretrained models to generate a number of new data points. This is especially true in recent years given the fast progress in large pretrained language models (LM). Few shot prompting is shown to be effective for LM to learn within context without extra training.\n\nData Augmentation\nThe goal of data augmentation is to modify the input format (e.g. text wording, visual appearance) while the semantic meaning stays unchanged.",
              "keywords": "data, data-generation, data-augmentation, data-quality",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 3: Data Generation",
              "og:description": "Here comes the Part 3 on learning with not enough data (Previous: Part 1 and Part 2). Let’s consider two approaches for generating synthetic data for training.\n\nAugmented data. Given a set of existing training samples, we can apply a variety of augmentation, distortion and transformation to derive new data points without losing the key attributes. We have covered a bunch of augmentation methods on text and images in a previous post on contrastive learning. For the sake of post completeness, I duplicate the section on data augmentation here with some edits.\nNew data. Given few or even no data points, we can rely on powerful pretrained models to generate a number of new data points. This is especially true in recent years given the fast progress in large pretrained language models (LM). Few shot prompting is shown to be effective for LM to learn within context without extra training.\n\nData Augmentation\nThe goal of data augmentation is to modify the input format (e.g. text wording, visual appearance) while the semantic meaning stays unchanged.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 3: Data Generation",
              "twitter:description": "Here comes the Part 3 on learning with not enough data (Previous: Part 1 and Part 2). Let’s consider two approaches for generating synthetic data for training.\n\nAugmented data. Given a set of existing training samples, we can apply a variety of augmentation, distortion and transformation to derive new data points without losing the key attributes. We have covered a bunch of augmentation methods on text and images in a previous post on contrastive learning. For the sake of post completeness, I duplicate the section on data augmentation here with some edits.\nNew data. Given few or even no data points, we can rely on powerful pretrained models to generate a number of new data points. This is especially true in recent years given the fast progress in large pretrained language models (LM). Few shot prompting is shown to be effective for LM to learn within context without extra training.\n\nData Augmentation\nThe goal of data augmentation is to modify the input format (e.g. text wording, visual appearance) while the semantic meaning stays unchanged.",
              "article:section": "posts",
              "article:published_time": "2022-04-15T15:10:30-07:00",
              "article:modified_time": "2022-04-15T15:10:30-07:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/1cc4df7eb2c7/code/body-000.txt",
                "chars": 257,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/EDA-exp1.png",
                "bytes": 299081,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-b1e26be047c763592a3a.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/EDA-exp1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen.png",
                "bytes": 178022,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-364dc68a08807b5baf8a.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen-exp.png",
                "bytes": 979053,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-2a8613e8ff2f07c9bbde.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GPT3-data-gen-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/LAMBADA.png",
                "bytes": 163034,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-1e49c821edae4f24f95b.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/LAMBADA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG.png",
                "bytes": 396874,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-773377f93dad7a113410.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG-exp.png",
                "bytes": 103983,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-82e84409bcacc2fc600e.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/UDG-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen.png",
                "bytes": 161004,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-3800c7c1476957d08f84.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen-exp.png",
                "bytes": 107466,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-9ca541330b72888db6f9.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/back-translation-data-gen-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/affinity-diversity.png",
                "bytes": 257673,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-6945c914870c32780b47.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/affinity-diversity.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/noise-adaptation-layer.png",
                "bytes": 193590,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-1e20893406355a07939d.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/noise-adaptation-layer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GLC.png",
                "bytes": 283685,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-6185b7cd92536235d8de.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/GLC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-backprop.png",
                "bytes": 241069,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-67e6e4a22214ef58e33c.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-backprop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-exp.png",
                "bytes": 812915,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-7d52e35a3da415faf3df.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/L2R-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/MentorNet.png",
                "bytes": 260104,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-e2db6011ba9c735f3718.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/MentorNet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/co-teaching.png",
                "bytes": 313297,
                "reused": false,
                "local_path": "attachments/1cc4df7eb2c7/images/body-cb3814a9fb4722b3289a.png",
                "src": "https://lilianweng.github.io/posts/2022-04-15-data-gen/co-teaching.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "previous post",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language models (LM)",
                "type": "a"
              },
              {
                "href": "https://pillow.readthedocs.io/en/stable/reference/ImageOps.html",
                "label": "PIL.ImageOps",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "AutoAugment",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/",
                "label": "neural architecture search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.11188",
                "label": "Zhang, et al 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.05393",
                "label": "Ho et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.04899",
                "label": "Yun et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.04552",
                "label": "DeVries & Taylor 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.01028",
                "label": "Kalantidis et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11196",
                "label": "Wei & Zou 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.06201",
                "label": "Kobayashi, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.06705",
                "label": "Xing Wu et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.08941",
                "label": "Guo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11764",
                "label": "Zhu et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.06508",
                "label": "Wang & van den Oord (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08821",
                "label": "Guo et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.13818",
                "label": "Shen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
                "label": "flow",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/",
                "label": "diffusion",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2108.13487",
                "label": "Wang et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.03118",
                "label": "Anaby-Tavor et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.02245",
                "label": "Kumar et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2109.09193",
                "label": "Wang et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.07540",
                "label": "Schick & Schutze (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2110.05448",
                "label": "Han et al (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08973",
                "label": "Gontijo-Lopes et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.08199",
                "label": "survey paper (Song et al. 2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1406.2080",
                "label": "Sukhbaatar et al. 2015",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=H12GRgcxg",
                "label": "Goldberger & Ben-Reuven, 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Expectation%E2%80%93maximization_algorithm",
                "label": "EM algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.09482",
                "label": "Ghosh et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.07836",
                "label": "Zhang & Sabuncu (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02041",
                "label": "Hu et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hinge_loss",
                "label": "hinge loss",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.10045",
                "label": "Lyu & Tsang (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.03683",
                "label": "Patrini et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05300",
                "label": "Hendrycks et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.02391",
                "label": "Li et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.09050",
                "label": "Ren et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1411.7718",
                "label": "Liu & Tao (2015)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Automatic_differentiation",
                "label": "automatic differentiation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.05055",
                "label": "Jiang et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.06872",
                "label": "Han et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.12766",
                "label": "“CERT: Contrastive self-supervised learning for language understanding.”",
                "type": "a"
              },
              {
                "href": "https://github.com/princeton-nlp/SimCSE",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/dinghanshen/cutoff",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/bhanML/Co-teaching",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:25Z",
            "source_url": "https://lilianweng.github.io/posts/2022-04-15-data-gen/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": false,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.11188",
                "bytes": 759445,
                "reused": false,
                "local_path": "papers/repair/4f4d45c6d87c67d3af9a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": true,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.05393",
                "bytes": 873126,
                "reused": false,
                "local_path": "papers/repair/4634b6280b855d570ac8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": false,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": true,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": true,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.04899",
                "bytes": 1682836,
                "reused": false,
                "local_path": "papers/repair/fec62c4fe8efdeebd877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.04552",
                "bytes": 741919,
                "reused": false,
                "local_path": "papers/repair/c3d681ed19bf88f43a98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.01028",
                "bytes": 970998,
                "reused": false,
                "local_path": "papers/repair/d4d3c2412459021d347a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11196",
                "bytes": 365049,
                "reused": true,
                "local_path": "papers/repair/389e34d78a0045e6d861.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.06201",
                "bytes": 722323,
                "reused": false,
                "local_path": "papers/repair/aebd3f77254c72e012a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.06705",
                "bytes": 431373,
                "reused": false,
                "local_path": "papers/repair/3e737149c9ea8568055b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.08941",
                "bytes": 345640,
                "reused": false,
                "local_path": "papers/repair/646a76cd251b8253359a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11764",
                "bytes": 257462,
                "reused": false,
                "local_path": "papers/repair/f5ea669209a03760ab22.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.06508",
                "bytes": 601155,
                "reused": false,
                "local_path": "papers/repair/a3681dc71a79ffecd499.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08821",
                "bytes": 1672580,
                "reused": false,
                "local_path": "papers/repair/e7a40652bdd04cd4b25f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.13818",
                "bytes": 398629,
                "reused": false,
                "local_path": "papers/repair/40a2d9b786e78e3cf30e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2108.13487",
                "bytes": 5884494,
                "reused": false,
                "local_path": "papers/repair/13a1e2b1cf2e73968c6b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.03118",
                "bytes": 372575,
                "reused": false,
                "local_path": "papers/repair/e8abfe05a235151d6c3e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.02245",
                "bytes": 250909,
                "reused": false,
                "local_path": "papers/repair/ba7634f079f15d2367dd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2109.09193",
                "bytes": 359282,
                "reused": false,
                "local_path": "papers/repair/5b433ceacb396f0baf99.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.07540",
                "bytes": 402533,
                "reused": false,
                "local_path": "papers/repair/ffa07cbf93071d00f1ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2110.05448",
                "bytes": 386252,
                "reused": false,
                "local_path": "papers/repair/62c1d70878370a3a749f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08973",
                "bytes": 1161444,
                "reused": false,
                "local_path": "papers/repair/cfe2f6f56fb90471ae4d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.08199",
                "bytes": 1299522,
                "reused": false,
                "local_path": "papers/repair/e31349c322026bf09dbb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2080",
                "bytes": 1181382,
                "reused": false,
                "local_path": "papers/repair/bd04e7310e34c7124557.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.09482",
                "bytes": 1146169,
                "reused": false,
                "local_path": "papers/repair/c7b83a3603919eb61881.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.07836",
                "bytes": 569770,
                "reused": false,
                "local_path": "papers/repair/1a42ffbbf4e704947ae3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02041",
                "bytes": 687019,
                "reused": false,
                "local_path": "papers/repair/ae376c87ceb11d4ea40f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.10045",
                "bytes": 2142637,
                "reused": false,
                "local_path": "papers/repair/75e3f3f69d9794770568.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.03683",
                "bytes": 763555,
                "reused": false,
                "local_path": "papers/repair/e8309ba701b2977efaca.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05300",
                "bytes": 1049334,
                "reused": false,
                "local_path": "papers/repair/9237191e681f5b67f6cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.02391",
                "bytes": 446285,
                "reused": false,
                "local_path": "papers/repair/e7f30c1dcfc80c923753.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.09050",
                "bytes": 3044218,
                "reused": false,
                "local_path": "papers/repair/40a7062040ed9fa7132b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1411.7718",
                "bytes": 634569,
                "reused": false,
                "local_path": "papers/repair/d8403b69812a8c4b8935.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.05055",
                "bytes": 827072,
                "reused": false,
                "local_path": "papers/repair/9788972c8ad31eb5bbb5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.06872",
                "bytes": 1984230,
                "reused": false,
                "local_path": "papers/repair/ce399494158e733915af.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.12766",
                "bytes": 412104,
                "reused": true,
                "local_path": "papers/repair/bae8e6b74f13390eb0a6.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 40655,
            "expected_body_images": 15,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/1cc4df7eb2c7/pages/source.html",
            "local_html": "attachments/1cc4df7eb2c7/pages/article.html",
            "body_base_path": "attachments/1cc4df7eb2c7/pages/",
            "body_markdown_path": "attachments/1cc4df7eb2c7/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
          "status": "ok",
          "article_id": "76583c4985bd",
          "local_path": "series-follow/1602/repair/74bca82addbb696cd397.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
              "bytes": 77905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/22f8744911da963ff507.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
              "bytes": 83063,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2431b04e51e95d44cbfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
              "bytes": 147122,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3704ca968b8b036dd979.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
              "bytes": 449224,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/264593afb504dba40862.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
              "bytes": 270328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/fe1f57c36a0c6b35ff30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
              "bytes": 299310,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/686784e7314725fbdcc3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
              "bytes": 375554,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/abc3c1e68e088b944f70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
              "bytes": 278212,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/20f5ad7f538bcfcaa51f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
              "bytes": 3492681,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/09be84ee222f7edd8341.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
              "bytes": 340862,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/41918aaaac4a38312f21.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
              "bytes": 373018,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/151ce877219f628d821e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
              "bytes": 130110,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/52dcd8696c072fec5989.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
              "bytes": 519536,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/60ae1da08ae38b4e5477.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
              "bytes": 124124,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1f3e79d5973995850e17.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
              "bytes": 548196,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b8bdf2d20d1fcc25c810.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
              "bytes": 218342,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/015dfefe2091cea2d5d5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
              "bytes": 306334,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/de572b70c4267a43c66a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
              "bytes": 470728,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cf42d45d1104e492f130.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
              "bytes": 176722,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/452ce3c3d7e9a8712c06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
              "bytes": 411449,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9d2b0d8db4abe7b366db.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
            "keywords": "半监督学习,少数据,标注",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "publish_date": "2021-12",
            "corpus_stage": "数据处理",
            "notes": "半监督学习系列综述之一",
            "id": "76583c4985bd",
            "collected_at": "2026-10-02T14:13:01",
            "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
            "body_markdown": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.\nPre-training + fine-tuning\n: Pre-train a powerful task-agnostic model on a large unsupervised data corpus, e.g.\npre-training LMs\non free text, or pre-training vision models on unlabelled images via\nself-supervised learning\n, and then fine-tune it on the downstream task with a small set of labeled samples.\nSemi-supervised learning\n: Learn from the labelled and unlabeled samples together. A lot of research has happened on vision tasks within this approach.\nActive learning\n: Labeling is expensive, but we still want to collect more given a cost budget. Active learning learns to select most valuable unlabeled samples to be collected next and helps us act smartly with a limited budget.\nPre-training + dataset auto-generation\n: Given a capable pre-trained model, we can utilize it to auto-generate a lot more labeled samples. This has been especially popular within the language domain driven by the success of few-shot learning.\nI plan to write a series of posts on the topic of “Learning with not enough data”. Part 1 is on\nSemi-Supervised Learning\n.\nWhat is semi-supervised learning?\n#\nSemi-supervised learning uses both labeled and unlabeled data to train a model.\nInterestingly most existing literature on semi-supervised learning focuses on vision tasks. And instead pre-training + fine-tuning is a more common paradigm for language tasks.\nAll the methods introduced in this post have a loss combining two parts: $\\mathcal{L} = \\mathcal{L}_s +  \\mu(t) \\mathcal{L}_u$. The supervised loss $\\mathcal{L}_s$ is easy to get given all the labeled examples. We will focus on how the unsupervised loss $\\mathcal{L}_u$ is designed. A common choice of the weighting term $\\mu(t)$ is a ramp function increasing the importance of $\\mathcal{L}_u$ in time, where $t$ is the training step.\nDisclaimer\n: The post is not gonna cover semi-supervised methods with focus on model architecture modification. Check\nthis survey\nfor how to use generative models and graph-based methods in semi-supervised learning.\nNotations\n#\nSymbol\nMeaning\n$L$\nNumber of unique labels.\n$(\\mathbf{x}^l, y) \\sim \\mathcal{X}, y \\in \\{0, 1\\}^L$\nLabeled dataset. $y$ is a one-hot representation of the true label.\n$\\mathbf{u} \\sim \\mathcal{U}$\nUnlabeled dataset.\n$\\mathcal{D} = \\mathcal{X} \\cup \\mathcal{U}$\nThe entire dataset, including both labeled and unlabeled examples.\n$\\mathbf{x}$\nAny sample which can be either labeled or unlabeled.\n$\\bar{\\mathbf{x}}$\n$\\mathbf{x}$ with augmentation applied.\n$\\mathbf{x}_i$\nThe $i$-th sample.\n$\\mathcal{L}$, $\\mathcal{L}_s$, $\\mathcal{L}_u$\nLoss, supervised loss, and unsupervised loss.\n$\\mu(t)$\nThe unsupervised loss weight, increasing in time.\n$p(y \\vert \\mathbf{x}), p_\\theta(y \\vert \\mathbf{x})$\nThe conditional probability over the label set given the input.\n$f_\\theta(.)$\nThe implemented neural network with weights $\\theta$, the model that we want to train.\n$\\mathbf{z} = f_\\theta(\\mathbf{x})$\nA vector of logits output by $f$.\n$\\hat{y} = \\text{softmax}(\\mathbf{z})$\nThe predicted label distribution.\n$D[.,.]$\nA distance function between two distributions, such as MSE, cross entropy, KL divergence, etc.\n$\\beta$\nEMA weighting hyperparameter for\nteacher\nmodel weights.\n$\\alpha, \\lambda$\nParameters for MixUp, $\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)$.\n$T$\nTemperature for sharpening the predicted distribution.\n$\\tau$\nA confidence threshold for selecting the qualified prediction.\nHypotheses\n#\nSeveral hypotheses have been discussed in literature to support certain design decisions in semi-supervised learning methods.\nH1:\nSmoothness Assumptions\n: If two data samples are close in a high-density region of the feature space, their labels should be the same or very similar.\nH2:\nCluster Assumptions\n: The feature space has both dense regions and sparse regions. Densely grouped data points naturally form a cluster. Samples in the same cluster are expected to have the same label. This is a small extension of H1.\nH3:\nLow-density Separation Assumptions\n: The decision boundary between classes tends to be located in the sparse, low density regions, because otherwise the decision boundary would cut a high-density cluster into two classes, corresponding to two clusters, which invalidates H1 and H2.\nH4:\nManifold Assumptions\n: The high-dimensional data tends to locate on a low-dimensional manifold. Even though real-world data might be observed in very high dimensions (e.g. such as images of real-world objects/scenes), they actually can be captured by a lower dimensional manifold where certain attributes are captured and similar points are grouped closely (e.g. images of real-world objects/scenes are not drawn from a uniform distribution over all pixel combinations). This enables us to learn a more efficient representation for us to discover and measure similarity between unlabeled data points. This is also the foundation for representation learning. [see\na helpful link\n].\nConsistency Regularization\n#\nConsistency Regularization\n, also known as\nConsistency Training\n, assumes that randomness within the neural network (e.g. with Dropout) or data augmentation transformations should not modify model predictions given the same input. Every method in this section has a consistency regularization loss as $\\mathcal{L}_u$.\nThis idea has been adopted in several\nself-supervised\nlearning\nmethods, such as SimCLR, BYOL, SimCSE, etc. Different augmented versions of the same sample should result in the same representation.\nCross-view training\nin language modeling and multi-view learning in self-supervised learning all share the same motivation.\nΠ-model\n#\nOverview of the Π-model. Two versions of the same input with different stochastic augmentation and dropout masks pass through the network and the outputs are expected to be consistent. (Image source:\nLaine & Aila (2017)\n)\nSajjadi et al. (2016)\nproposed an unsupervised learning loss to minimize the difference between two passes through the network with stochastic transformations (e.g. dropout, random max-pooling) for the same data point. The label is not explicitly used, so the loss can be applied to unlabeled dataset.\nLaine & Aila (2017)\nlater coined the name,\nΠ-Model\n, for such a setup.\n$$\n\\mathcal{L}_u^\\Pi = \\sum_{\\mathbf{x} \\in \\mathcal{D}} \\text{MSE}(f_\\theta(\\mathbf{x}), f'_\\theta(\\mathbf{x}))\n$$\nwhere $f’$ is the same neural network with different stochastic augmentation or dropout masks applied. This loss utilizes the entire dataset.\nTemporal ensembling\n#\nOverview of Temporal Ensembling. The per-sample EMA label prediction is the learning target. (Image source:\nLaine & Aila (2017)\n)\nΠ-model requests the network to run two passes per sample, doubling the computation cost. To reduce the cost,\nTemporal Ensembling\n(\nLaine & Aila 2017\n) maintains an exponential moving average (EMA) of the model prediction in time per training sample $\\tilde{\\mathbf{z}}_i$ as the learning target, which is only evaluated and updated once per epoch. Because the ensemble output $\\tilde{\\mathbf{z}}_i$ is initialized to $\\mathbf{0}$, it is normalized by $(1-\\alpha^t)$ to correct this startup bias. Adam optimizer has such\nbias correction\nterms for the same reason.\n$$\n\\tilde{\\mathbf{z}}^{(t)}_i = \\frac{\\alpha \\tilde{\\mathbf{z}}^{(t-1)}_i + (1-\\alpha) \\mathbf{z}_i}{1-\\alpha^t}\n$$\nwhere $\\tilde{\\mathbf{z}}^{(t)}$ is the ensemble prediction at epoch $t$ and $\\mathbf{z}_i$ is the model prediction in the current round. Note that since $\\tilde{\\mathbf{z}}^{(0)} = \\mathbf{0}$, with correction, $\\tilde{\\mathbf{z}}^{(1)}$ is simply equivalent to $\\mathbf{z}_i$ at epoch 1.\nMean teachers\n#\nOverview of the Mean Teacher framework. (Image source:\nTarvaninen & Valpola, 2017\n)\nTemporal Ensembling keeps track of an EMA of label predictions for each training sample as a learning target. However, this label prediction only changes\nevery epoch\n, making the approach clumsy when the training dataset is large.\nMean Teacher\n(\nTarvaninen & Valpola, 2017\n) is proposed to overcome the slowness of target update by tracking the moving average of model weights instead of model outputs. Let’s call the original model with weights $\\theta$ as the\nstudent\nmodel and the model with moving averaged weights $\\theta’$ across consecutive student models as the\nmean teacher\n: $\\theta’ \\gets \\beta \\theta’ + (1-\\beta)\\theta$\nThe consistency regularization loss is the distance between predictions by the student and teacher and the student-teacher gap should be minimized. The mean teacher is expected to provide more accurate predictions than the student. It got confirmed in the empirical experiments, as shown in\nClassification error on SVHN of Mean Teacher and the Π Model. The mean teacher (in orange) has better performance than the student model (in blue). (Image source:\nTarvaninen & Valpola, 2017\n)\nAccording to their ablation studies,\nInput augmentation (e.g. random flips of input images, Gaussian noise) or student model dropout is necessary for good performance. Dropout is not needed on the teacher model.\nThe performance is sensitive to the EMA decay hyperparameter $\\beta$. A good strategy is to use a small $\\beta=0.99$ during the ramp up stage and a larger $\\beta=0.999$ in the later stage when the student model improvement slows down.\nThey found that MSE as the consistency cost function performs better than other cost functions like KL divergence.\nNoisy samples as learning targets\n#\nSeveral recent consistency training methods learn to minimize prediction difference between the original unlabeled sample and its corresponding augmented version. It is quite similar to the Π-model but the consistency regularization loss is\nonly\napplied to the unlabeled data.\nConsistency training with noisy samples.\nAdversarial Training (\nGoodfellow et al. 2014\n) applies adversarial noise onto the input and trains the model to be robust to such adversarial attack. The setup works in supervised learning,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{adv}(\\mathbf{x}^l, \\theta) &= D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &\\approx \\epsilon \\frac{g}{\\|g\\|_2} \\approx \\epsilon\\text{sign}(g)\\quad\\text{where }g = \\nabla_{r} D[y, p_\\theta(y\\mid \\mathbf{x}^l + r)]\n\\end{aligned}\n$$\nwhere $q(y \\mid \\mathbf{x}^l)$ is the true distribution, approximated by one-hot encoding of the ground truth label, $y$. $p_\\theta(y \\mid \\mathbf{x}^l)$ is the model prediction. $D[.,.]$ is a distance function measuring the divergence between two distributions.\nVirtual Adversarial Training\n(\nVAT\n;\nMiyato et al. 2018\n) extends the idea to work in semi-supervised learning. Because $q(y \\mid \\mathbf{x}^l)$ is unknown, VAT replaces it with the current model prediction for the original input with the current weights $\\hat{\\theta}$.  Note that $\\hat{\\theta}$ is a fixed copy of model weights, so there is no gradient update on $\\hat{\\theta}$.\n$$\n\\begin{aligned}\n\\mathcal{L}_u^\\text{VAT}(\\mathbf{x}, \\theta) &= D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r_\\text{vadv})] \\\\\nr_\\text{vadv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r)]\n\\end{aligned}\n$$\nThe VAT loss applies to both labeled and unlabeled samples. It is a negative smoothness measure of the current model’s prediction manifold at each data point. The optimization of such loss motivates the manifold to be smoother.\nInterpolation Consistency Training\n(\nICT\n;\nVerma et al. 2019\n) enhances the dataset by adding more interpolations of data points and expects the model prediction to be consistent with interpolations of the corresponding labels. MixUp (\nZheng et al. 2018\n) operation mixes two images via a simple weighted sum and combines it with label smoothing. Following the idea of MixUp, ICT expects the prediction model to produce a label on a mixup sample to match the interpolation of predictions of corresponding inputs:\n$$\n\\begin{aligned}\n\\text{mixup}_\\lambda (\\mathbf{x}_i, \\mathbf{x}_j) &= \\lambda \\mathbf{x}_i + (1-\\lambda)\\mathbf{x}_j \\\\\np(\\text{mixup}_\\lambda (y \\mid \\mathbf{x}_i, \\mathbf{x}_j)) &\\approx \\lambda p(y \\mid \\mathbf{x}_i) + (1-\\lambda) p(y \\mid \\mathbf{x}_j)\n\\end{aligned}\n$$\nwhere $\\theta’$ is a moving average of $\\theta$, which is a\nmean teacher\n.\nOverview of Interpolation Consistency Training. MixUp is applied to produce more interpolated samples with interpolated labels as learning targets. (Image source:\nVerma et al. 2019\n)\nBecause the probability of two randomly selected unlabeled samples belonging to different classes is high (e.g. There are 1000 object classes in ImageNet), the interpolation by applying a mixup between two random unlabeled samples is likely to happen around the decision boundary. According to the low-density separation\nassumptions\n, the decision boundary tends to locate in the low density regions.\n$$\n\\mathcal{L}^\\text{ICT}_{u} = \\mathbb{E}_{\\mathbf{u}_i, \\mathbf{u}_j \\sim \\mathcal{U}} \\mathbb{E}_{\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)} D[p_\\theta(y \\mid \\text{mixup}_\\lambda (\\mathbf{u}_i, \\mathbf{u}_j)), \\text{mixup}_\\lambda(p_{\\theta’}(y \\mid \\mathbf{u}_i), p_{\\theta'}(y \\mid \\mathbf{u}_j)]\n$$\nwhere $\\theta’$ is a moving average of $\\theta$.\nSimilar to VAT,\nUnsupervised Data Augmentation\n(\nUDA\n;\nXie et al. 2020\n) learns to predict the same output for an unlabeled example and the augmented one. UDA especially focuses on studying how the\n“quality”\nof noise can impact the semi-supervised learning performance with consistency training. It is crucial to use advanced data augmentation methods for producing meaningful and effective noisy samples. Good data augmentation should produce valid (i.e. does not change the label) and diverse noise, and carry targeted inductive biases.\nFor images, UDA adopts RandAugment (\nCubuk et al. 2019\n) which uniformly samples augmentation operations available in\nPIL\n, no learning or optimization, so it is much cheaper than AutoAugment.\nComparison of various semi-supervised learning methods on CIFAR-10 classification. Fully supervised Wide-ResNet-28-2 and PyramidNet+ShakeDrop have an error rate of **5.4** and **2.7** respectively when trained on 50,000 examples without RandAugment. (Image source:\nXie et al. 2020\n)\nFor language, UDA combines back-translation and TF-IDF based word replacement. Back-translation preserves the high-level meaning but may not retain certain words, while TF-IDF based word replacement drops uninformative words with low TF-IDF scores. In the experiments on language tasks, they found UDA to be complementary to transfer learning and representation learning; For example, BERT fine-tuned (i.e. $\\text{BERT}_\\text{FINETUNE}$ in Fig. 8.) on in-domain unlabeled data can further improve the performance.\nComparison of UDA with different initialization configurations on various text classification tasks. (Image source:\nXie et al. 2020\n)\nWhen calculating $\\mathcal{L}_u$, UDA found two training techniques to help improve the results.\nLow confidence masking\n: Mask out examples with low prediction confidence if lower than a threshold $\\tau$.\nSharpening prediction distribution\n: Use a low temperature $T$ in softmax to sharpen the predicted probability distribution.\nIn-domain data filtration\n: In order to extract more in-domain data from a large out-of-domain dataset, they trained a classifier to predict in-domain labels and then retain samples with high confidence predictions as in-domain candidates.\n$$\n\\begin{aligned}\n&\\mathcal{L}_u^\\text{UDA} = \\mathbb{1}[\\max_{y'} p_{\\hat{\\theta}}(y'\\mid \\mathbf{x}) > \\tau ] \\cdot D[p^\\text{(sharp)}_{\\hat{\\theta}}(y \\mid \\mathbf{x}; T), p_\\theta(y \\mid \\bar{\\mathbf{x}})] \\\\\n&\\text{where } p_{\\hat{\\theta}}^\\text{(sharp)}(y \\mid \\mathbf{x}; T) = \\frac{\\exp(z^{(y)} / T)}{ \\sum_{y'} \\exp(z^{(y')} / T) }\n\\end{aligned}\n$$\nwhere $\\hat{\\theta}$ is a fixed copy of model weights, same as in VAT, so no gradient update, and $\\bar{\\mathbf{x}}$ is the augmented data point. $\\tau$ is the prediction confidence threshold and $T$ is the distribution sharpening temperature.\nPseudo Labeling\n#\nPseudo Labeling\n(\nLee 2013\n) assigns fake labels to unlabeled samples based on the maximum softmax probabilities predicted by the current model and then trains the model on both labeled and unlabeled samples simultaneously in a pure supervised setup.\nWhy could pseudo labels work? Pseudo label is in effect equivalent to\nEntropy Regularization\n(\nGrandvalet & Bengio 2004\n), which minimizes the conditional entropy of class probabilities for unlabeled data to favor low density separation between classes. In other words, the predicted class probabilities is in fact a measure of class overlap, minimizing the entropy is equivalent to reduced class overlap and thus low density separation.\nt-SNE visualization of outputs on MNIST test set by models training (a) without and (b) with pseudo labeling on 60000 unlabeled samples, in addition to 600 labeled data. Pseudo labeling leads to better segregation in the learned embedding space.  (Image source:\nLee 2013\n)\nTraining with pseudo labeling naturally comes as an iterative process. We refer to the model that produces pseudo labels as teacher and the model that learns with pseudo labels as student.\nLabel propagation\n#\nLabel Propagation\n(\nIscen et al. 2019\n) is an idea to construct a similarity graph among samples based on feature embedding. Then the pseudo labels are “diffused” from known samples to unlabeled ones where the propagation weights are proportional to pairwise similarity scores in the graph. Conceptually it is similar to a k-NN classifier and both suffer from the problem of not scaling up well with a large dataset.\nIllustration of how Label Propagation works. (Image source:\nIscen et al. 2019\n)\nSelf-Training\n#\nSelf-Training\nis not a new concept (\nScudder 1965\n,\nNigram & Ghani CIKM 2000\n). It is an iterative algorithm, alternating between the following two steps until every unlabeled sample has a label assigned:\nInitially it builds a classifier on labeled data.\nThen it uses this classifier to predict labels for the unlabeled data and converts the most confident ones into labeled samples.\nXie et al. (2020)\napplied self-training in deep learning and achieved great results. On the ImageNet classification task, they first trained an EfficientNet (\nTan & Le 2019\n) model as teacher to generate pseudo labels for 300M unlabeled images and then trained a larger EfficientNet as student to learn with both true labeled and pseudo labeled images. One critical element in their setup is to have\nnoise\nduring student model training but have no noise for the teacher to produce pseudo labels. Thus their method is called\nNoisy Student\n. They applied stochastic depth (\nHuang et al. 2016\n), dropout and RandAugment to noise the student. Noise is important for the student to perform better than the teacher. The added noise has a compound effect to encourage the model’s decision making frontier to be smooth, on both labeled and unlabeled data.\nA few other important technical configs in noisy student self-training are:\nThe student model should be sufficiently large (i.e. larger than the teacher) to fit more data.\nNoisy student should be paired with data balancing, especially important to balance the number of pseudo labeled images in each class.\nSoft pseudo labels work better than hard ones.\nNoisy student also improves adversarial robustness against an FGSM (Fast Gradient Sign Attack = The attack uses the gradient of the loss w.r.t the input data and adjusts the input data to maximize the loss) attack though the model is not optimized for adversarial robustness.\nSentAugment, proposed by\nDu et al. (2020)\n, aims to solve the problem when there is not enough in-domain unlabeled data for self-training in the language domain. It relies on sentence embedding to find unlabeled in-domain samples from a large corpus and uses the retrieved sentences for self-training.\nReducing confirmation bias\n#\nConfirmation bias is a problem with incorrect pseudo labels provided by an imperfect teacher model. Overfitting to wrong labels may not give us a better student model.\nTo reduce confirmation bias,\nArazo et al. (2019)\nproposed  two techniques. One is to adopt MixUp with soft labels. Given two samples, $(\\mathbf{x}_i, \\mathbf{x}_j)$ and their corresponding true or pseudo labels $(y_i, y_j)$, the interpolated label equation can be translated to a cross entropy loss with softmax outputs:\n$$\n\\begin{aligned}\n&\\bar{\\mathbf{x}} = \\lambda \\mathbf{x}_i + (1-\\lambda) \\mathbf{x}_j \\\\\n&\\bar{y} = \\lambda y_i + (1-\\lambda) y_j \\Leftrightarrow\n\\mathcal{L} = \\lambda [y_i^\\top \\log f_\\theta(\\bar{\\mathbf{x}})] + (1-\\lambda) [y_j^\\top \\log f_\\theta(\\bar{\\mathbf{x}})]\n\\end{aligned}\n$$\nMixup is insufficient if there are too few labeled samples. They further set a minimum number of labeled samples in every mini batch by oversampling the labeled samples. This works better than upweighting labeled samples, because it leads to more frequent updates rather than few updates of larger magnitude which could be less stable. Like consistency regularization, data augmentation and dropout are also important for pseudo labeling to work well.\nMeta Pseudo Labels\n(\nPham et al. 2021\n) adapts the teacher model constantly with the feedback of how well the student performs on the labeled dataset. The teacher and the student are trained in parallel, where the teacher learns to generate better pseudo labels and the student learns from the pseudo labels.\nLet the teacher and student model weights be $\\theta_T$ and $\\theta_S$, respectively. The student model’s loss on the labeled samples is defined as a function $\\theta^\\text{PL}_S(.)$ of $\\theta_T$ and we would like to minimize this loss by optimizing the teacher model accordingly.\n$$\n\\begin{aligned}\n\\min_{\\theta_T} &\\mathcal{L}_s(\\theta^\\text{PL}_S(\\theta_T)) = \\min_{\\theta_T} \\mathbb{E}_{(\\mathbf{x}^l, y) \\in \\mathcal{X}} \\text{CE}[y, f_{\\theta_S}(\\mathbf{x}^l)]  \\\\\n\\text{where } &\\theta^\\text{PL}_S(\\theta_T)\n= \\arg\\min_{\\theta_S} \\mathcal{L}_u (\\theta_T, \\theta_S)\n= \\arg\\min_{\\theta_S} \\mathbb{E}_{\\mathbf{u} \\sim \\mathcal{U}} \\text{CE}[(f_{\\theta_T}(\\mathbf{u}), f_{\\theta_S}(\\mathbf{u}))]\n\\end{aligned}\n$$\nHowever, it is not trivial to optimize the above equation. Borrowing the idea of\nMAML\n, it approximates the multi-step $\\arg\\min_{\\theta_S}$ with the one-step gradient update of $\\theta_S$,\n$$\n\\begin{aligned}\n\\theta^\\text{PL}_S(\\theta_T) &\\approx \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\\\\n\\min_{\\theta_T} \\mathcal{L}_s (\\theta^\\text{PL}_S(\\theta_T)) &\\approx \\min_{\\theta_T} \\mathcal{L}_s \\big( \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\big)\n\\end{aligned}\n$$\nWith soft pseudo labels, the above objective is differentiable. But if using hard pseudo labels, it is not differentiable and thus we need to use RL, e.g. REINFORCE.\nThe optimization procedure is alternative between training two models:\nStudent model update\n: Given a batch of unlabeled samples $\\{ \\mathbf{u} \\}$, we generate pseudo labels by $f_{\\theta_T}(\\mathbf{u})$ and optimize $\\theta_S$ with one step SGD: $\\theta’_S = \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)}$.\nTeacher model update\n: Given a batch of labeled samples $\\{(\\mathbf{x}^l, y)\\}$, we reuse the student’s update to optimize $\\theta_T$: $\\theta’_T = \\theta_T  - \\eta_T \\cdot \\nabla_{\\theta_T} \\mathcal{L}_s ( \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)} )$. In addition, the UDA objective is applied to the teacher model to incorporate consistency regularization.\nComparison of Meta Pseudo Labels with other semi- or self-supervised learning methods on image classification tasks. (Image source:\nPham et al. 2021\n)\nPseudo Labeling with Consistency Regularization\n#\nIt is possible to combine the above two approaches together, running semi-supervised learning with both pseudo labeling and consistency training.\nMixMatch\n#\nMixMatch\n(\nBerthelot et al. 2019\n), as a holistic approach to semi-supervised learning, utilizes unlabeled data by merging the following techniques:\nConsistency regularization\n: Encourage the model to output the same predictions on perturbed unlabeled samples.\nEntropy minimization\n: Encourage the model to output confident predictions on unlabeled data.\nMixUp\naugmentation: Encourage the model to have linear behaviour between samples.\nGiven a batch of labeled data $\\mathcal{X}$ and unlabeled data $\\mathcal{U}$, we create augmented versions of them via $\\text{MixMatch}(.)$, $\\bar{\\mathcal{X}}$ and $\\bar{\\mathcal{U}}$, containing augmented samples and guessed labels for unlabeled examples.\n$$\n\\begin{aligned}\n\\bar{\\mathcal{X}}, \\bar{\\mathcal{U}} &= \\text{MixMatch}(\\mathcal{X}, \\mathcal{U}, T, K, \\alpha) \\\\\n\\mathcal{L}^\\text{MM}_s &= \\frac{1}{\\vert \\bar{\\mathcal{X}} \\vert} \\sum_{(\\bar{\\mathbf{x}}^l, y)\\in \\bar{\\mathcal{X}}} D[y, p_\\theta(y \\mid \\bar{\\mathbf{x}}^l)] \\\\\n\\mathcal{L}^\\text{MM}_u &= \\frac{1}{L\\vert \\bar{\\mathcal{U}} \\vert} \\sum_{(\\bar{\\mathbf{u}}, \\hat{y})\\in \\bar{\\mathcal{U}}} \\| \\hat{y} - p_\\theta(y \\mid \\bar{\\mathbf{u}}) \\|^2_2 \\\\\n\\end{aligned}\n$$\nwhere $T$ is the sharpening temperature to reduce the guessed label overlap; $K$ is the number of augmentations generated per unlabeled example; $\\alpha$ is the parameter in MixUp.\nFor each $\\mathbf{u}$, MixMatch generates $K$ augmentations, $\\bar{\\mathbf{u}}^{(k)} = \\text{Augment}(\\mathbf{u})$ for $k=1, \\dots, K$ and the pseudo label is guessed based on the average: $\\hat{y} = \\frac{1}{K} \\sum_{k=1}^K p_\\theta(y \\mid \\bar{\\mathbf{u}}^{(k)})$.\nThe process of \"label guessing\" in MixMatch: averaging $K$ augmentations, correcting the predicted marginal distribution and finally sharpening the distribution. (Image source:\nBerthelot et al. 2019\n)\nAccording to their ablation studies, it is critical to have MixUp especially on the unlabeled data. Removing temperature sharpening on the pseudo label distribution hurts the performance quite a lot. Average over multiple augmentations for label guessing is also necessary.\nReMixMatch\n(\nBerthelot et al. 2020\n) improves MixMatch by introducing two new mechanisms:\nIllustration of two improvements introduced in ReMixMatch over MixMatch. (Image source:\nBerthelot et al. 2020\n)\nDistribution alignment.\nIt encourages the marginal distribution $p(y)$ to be close to the marginal distribution of the ground truth labels. Let $p(y)$ be the class distribution in the true labels and $\\tilde{p}(\\hat{y})$ be a running average of the predicted class distribution among the unlabeled data. The model prediction on an unlabeled sample $p_\\theta(y \\vert \\mathbf{u})$ is normalized to be $\\text{Normalize}\\big( \\frac{p_\\theta(y \\vert \\mathbf{u}) p(y)}{\\tilde{p}(\\hat{y})} \\big)$ to match the true marginal distribution.\nNote that entropy minimization is not a useful objective if the marginal distribution is not uniform.\nI do feel the assumption that the class distributions on the labeled and unlabeled data should match is too strong and not necessarily to be true in the real-world setting.\nAugmentation anchoring\n. Given an unlabeled sample, it first generates an “anchor” version with weak augmentation and then averages $K$ strongly augmented versions using CTAugment (Control Theory Augment). CTAugment only samples augmentations that keep the model predictions within the network tolerance.\nThe ReMixMatch loss is a combination of several terms,\na supervised loss with data augmentation and MixUp applied;\nan unsupervised loss with data augmentation and MixUp applied, using pseudo labels as targets;\na CE loss on a single heavily-augmented unlabeled image without MixUp;\na\nrotation\nloss as in self-supervised learning.\nDivideMix\n#\nDivideMix\n(\nJunnan Li et al. 2020\n) combines semi-supervised learning with Learning with noisy labels (LNL). It models the per-sample loss distribution via a\nGMM\nto dynamically divide the training data into a labeled set with clean examples and an unlabeled set with noisy ones. Following the idea in\nArazo et al. 2019\n, they fit a two-component GMM on the per-sample cross entropy loss $\\ell_i = y_i^\\top \\log f_\\theta(\\mathbf{x}_i)$. Clean samples are expected to get lower loss faster than noisy samples. The component with smaller mean is the cluster corresponding to clean labels and let’s denote it as $c$. If the GMM posterior probability $w_i = p_\\text{GMM}(c \\mid \\ell_i)$ (i.e. the probability of the sampling belonging to the clean sample set) is larger than the threshold $\\tau$, this sample is considered as a clean sample and otherwise a noisy one.\nThe data clustering step is named\nco-divide\n. To avoid confirmation bias, DivideMix simultaneously trains two diverged networks where each network uses the dataset division from the other network; e.g. thinking about how Double Q Learning works.\nDivideMix trains two networks independently to reduce confirmation bias. They run co-divide, co-refinement, and co-guessing together. (Image source:\nJunnan Li et al. 2020\n)\nCompared to MixMatch, DivideMix has an additional\nco-divide\nstage for handling noisy samples, as well as the following improvements during training:\nLabel co-refinement\n: It linearly combines the ground-truth label $y_i$ with the network’s prediction $\\hat{y}_i$, which is averaged across multiple augmentations of $\\mathbf{x}_i$, guided by the clean set probability $w_i$ produced by the other network.\nLabel co-guessing\n: It averages the predictions from two models for unlabelled data samples.\nThe algorithm of DivideMix. (Image source:\nJunnan Li et al. 2020\n)\nFixMatch\n#\nFixMatch\n(\nSohn et al. 2020\n) generates pseudo labels on unlabeled samples with weak augmentation and only keeps predictions with high confidence. Here both weak augmentation and high confidence filtering help produce high-quality trustworthy pseudo label targets. Then FixMatch learns to predict these pseudo labels given a heavily-augmented sample.\nIllustration of how FixMatch works. (Image source:\nSohn et al. 2020\n)\n$$\n\\begin{aligned}\n\\mathcal{L}_s &= \\frac{1}{B} \\sum^B_{b=1} \\text{CE}[y_b, p_\\theta(y \\mid \\mathcal{A}_\\text{weak}(\\mathbf{x}_b))] \\\\\n\\mathcal{L}_u &= \\frac{1}{\\mu B} \\sum_{b=1}^{\\mu B} \\mathbb{1}[\\max(\\hat{y}_b) \\geq \\tau]\\;\\text{CE}(\\hat{y}_b, p_\\theta(y \\mid \\mathcal{A}_\\text{strong}(\\mathbf{u}_b)))\n\\end{aligned}\n$$\nwhere $\\hat{y}_b$ is the pseudo label for an unlabeled example; $\\mu$ is a hyperparameter that determines the relative sizes of $\\mathcal{X}$ and $\\mathcal{U}$.\nWeak augmentation $\\mathcal{A}_\\text{weak}(.)$: A standard flip-and-shift augmentation\nStrong augmentation $\\mathcal{A}_\\text{strong}(.)$ : AutoAugment, Cutout, RandAugment, CTAugment\nPerformance of FixMatch and several other semi-supervised learning methods on image classification tasks. (Image source:\nSohn et al. 2020\n)\nAccording to the ablation studies of FixMatch,\nSharpening the predicted distribution with a temperature parameter $T$ does not have a significant impact when the threshold $\\tau$ is used.\nCutout and CTAugment as part of strong augmentations are necessary for good performance.\nWhen the weak augmentation for label guessing is replaced with strong augmentation, the model diverges early in training. If discarding weak augmentation completely, the model overfit the guessed labels.\nUsing weak instead of strong augmentation for pseudo label prediction leads to unstable performance. Strong data augmentation is critical.\nCombined with Powerful Pre-Training\n#\nIt is a common paradigm, especially in language tasks, to first pre-train a task-agnostic model on a large unsupervised data corpus via self-supervised learning and then fine-tune it on the downstream task with a small labeled dataset. Research has shown that we can obtain extra gain if combining semi-supervised learning with pretraining.\nZoph et al. (2020)\nstudied to what degree\nself-training\ncan work better than pre-training. Their experiment setup was to use ImageNet for pre-training or self-training to improve COCO. Note that when using ImageNet for self-training, it discards labels and only uses ImageNet samples as unlabeled data points.\nHe et al. (2018)\nhas demonstrated that ImageNet classification pre-training does not work well if the downstream task is very different, such as object detection.\nThe effect of (a) data augment (from weak to strong) and (b) the labeled dataset size on the object detection performance. In the legend: `Rand Init` refers to a model initialized w/ random weights; `ImageNet` is initialized with a pre-trained checkpoint at 84.5% top-1 ImageNet accuracy; `ImageNet++` is initialized with a checkpoint with a higher accuracy 86.9%. (Image source:\nZoph et al. 2020\n)\nTheir experiments demonstrated a series of interesting findings:\nThe effectiveness of pre-training diminishes with more labeled samples available for the downstream task. Pre-training is helpful in the low-data regimes (20%) but neutral or harmful in the high-data regime.\nSelf-training helps in high data/strong augmentation regimes, even when pre-training hurts.\nSelf-training can bring in additive improvement on top of pre-training, even using the same data source.\nSelf-supervised pre-training (e.g. via SimCLR) hurts the performance in a high data regime, similar to how supervised pre-training does.\nJoint-training supervised and self-supervised objectives help resolve the mismatch between the pre-training and downstream tasks. Pre-training, joint-training and self-training are all additive.\nNoisy labels or un-targeted labeling (i.e. pre-training labels are not aligned with downstream task labels) is worse than targeted pseudo labeling.\nSelf-training is computationally more expensive than fine-tuning on a pre-trained model.\nChen et al. (2020)\nproposed a three-step procedure to merge the benefits of self-supervised pretraining, supervised fine-tuning and self-training together:\nUnsupervised or self-supervised pretrain a big model.\nSupervised fine-tune it on a few labeled examples. It is important to use a big (deep and wide) neural network.\nBigger models yield better performance with fewer labeled samples.\nDistillation with unlabeled examples by adopting pseudo labels in self-training.\nIt is possible to distill the knowledge from a large model into a small one because the task-specific use does not require extra capacity of the learned representation.\nThe distillation loss is formatted as the following, where the teacher network is fixed with weights $\\hat{\\theta}_T$.\n$$\n     \\mathcal{L}_\\text{distill} = - (1-\\alpha) \\underbrace{\\sum_{(\\mathbf{x}^l_i, y_i) \\in \\mathcal{X}} \\big[ \\log p_{\\theta_S}(y_i \\mid \\mathbf{x}^l_i) \\big]}_\\text{Supervised loss} - \\alpha \\underbrace{\\sum_{\\mathbf{u}_i \\in \\mathcal{U}} \\Big[ \\sum_{i=1}^L p_{\\hat{\\theta}_T}(y^{(i)} \\mid \\mathbf{u}_i; T) \\log p_{\\theta_S}(y^{(i)} \\mid \\mathbf{u}_i; T) \\Big]}_\\text{Distillation loss using unlabeled data}\n     $$\nA semi-supervised learning framework leverages unlabeled data corpus by (Left) task-agnostic unsupervised pretraining and (Right) task-specific self-training and distillation. (Image source:\nChen et al. 2020\n)\nThey experimented on the ImageNet classification task. The self-supervised pre-training uses SimCLRv2, a directly improved version of\nSimCLR\n. Observations in their empirical studies confirmed several learnings, aligned with\nZoph et al. 2020\n:\nBigger models are more label-efficient;\nBigger/deeper project heads in SimCLR improve representation learning;\nDistillation using unlabeled data improves semi-supervised learning.\nComparison of performance by SimCLRv2 + semi-supervised distillation on ImageNet classification. (Image source:\nChen et al. 2020\n)\n💡 Quick summary of common themes among recent semi-supervised learning methods, many aiming to reduce confirmation bias:\nApply valid and diverse noise to samples by advanced data augmentation methods.\nWhen dealing with images, MixUp is an effective augmentation. Mixup could work on language too, resulting in a small incremental improvement (\nGuo et al. 2019\n).\nSet a threshold and discard pseudo labels with low confidence.\nSet a minimum number of labeled samples per mini-batch.\nSharpen the pseudo label distribution to reduce the class overlap.\nCitation\n#\nCited as:\nWeng, Lilian. (Dec 2021). Learning with not enough data part 1: semi-supervised learning. Lil’Log. https://lilianweng.github.io/posts/2021-12-05-semi-supervised/.\nOr\n@article{weng2021semi,\n  title   = \"Learning with not Enough Data Part 1: Semi-Supervised Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Dec\",\n  url     = \"https://lilianweng.github.io/posts/2021-12-05-semi-supervised/\"\n}\nReferences\n#\n[1] Ouali, Hudelot & Tami.\n“An Overview of Deep Semi-Supervised Learning”\narXiv preprint arXiv:2006.05278 (2020).\n[2] Sajjadi, Javanmardi & Tasdizen\n“Regularization With Stochastic Transformations and Perturbations for Deep Semi-Supervised Learning.”\narXiv preprint arXiv:1606.04586 (2016).\n[3] Pham et al.\n“Meta Pseudo Labels.”\nCVPR 2021.\n[4] Laine & Aila.\n“Temporal Ensembling for Semi-Supervised Learning”\nICLR 2017.\n[5] Tarvaninen & Valpola.\n“Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results.”\nNeuriPS 2017\n[6] Xie et al.\n“Unsupervised Data Augmentation for Consistency Training.”\nNeuriPS 2020.\n[7] Miyato et al.\n“Virtual Adversarial Training: A Regularization Method for Supervised and Semi-Supervised Learning.”\nIEEE transactions on pattern analysis and machine intelligence 41.8 (2018).\n[8] Verma et al.\n“Interpolation consistency training for semi-supervised learning.”\nIJCAI 2019\n[9] Lee.\n“Pseudo-label: The simple and efficient semi-supervised learning method for deep neural networks.”\nICML 2013 Workshop: Challenges in Representation Learning.\n[10] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019.\n[11] Xie et al.\n“Self-training with Noisy Student improves ImageNet classification”\nCVPR 2020.\n[12] Jingfei Du et al.\n“Self-training Improves Pre-training for Natural Language Understanding.”\n2020\n[13] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019\n[14] Arazo et al.\n“Pseudo-labeling and confirmation bias in deep semi-supervised learning.”\nIJCNN 2020.\n[15] Berthelot et al.\n“MixMatch: A holistic approach to semi-supervised learning.”\nNeuriPS 2019\n[16] Berthelot et al.\n“ReMixMatch: Semi-supervised learning with distribution alignment and augmentation anchoring.”\nICLR 2020\n[17] Sohn et al.\n“FixMatch: Simplifying semi-supervised learning with consistency and confidence.”\nCVPR 2020\n[18] Junnan Li et al.\n“DivideMix: Learning with Noisy Labels as Semi-supervised Learning.”\n2020 [\ncode\n]\n[19] Zoph et al.\n“Rethinking pre-training and self-training.”\n2020.\n[20] Chen et al.\n“Big Self-Supervised Models are Strong Semi-Supervised Learners”\n2020",
            "metadata": {
              "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
              "description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "keywords": "data, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "og:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "twitter:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "article:section": "posts",
              "article:published_time": "2021-12-05T00:00:00+00:00",
              "article:modified_time": "2021-12-05T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/76583c4985bd/code/body-000.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "bytes": 77905,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-22f8744911da963ff507.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "bytes": 83063,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-2431b04e51e95d44cbfc.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "bytes": 147122,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-3704ca968b8b036dd979.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "bytes": 449224,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-264593afb504dba40862.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "bytes": 270328,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-fe1f57c36a0c6b35ff30.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "bytes": 299310,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-686784e7314725fbdcc3.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "bytes": 375554,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-abc3c1e68e088b944f70.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "bytes": 278212,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-20f5ad7f538bcfcaa51f.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "bytes": 3492681,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-09be84ee222f7edd8341.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "bytes": 340862,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-41918aaaac4a38312f21.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "bytes": 373018,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-151ce877219f628d821e.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "bytes": 130110,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-52dcd8696c072fec5989.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "bytes": 519536,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-60ae1da08ae38b4e5477.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "bytes": 124124,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-1f3e79d5973995850e17.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "bytes": 548196,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-b8bdf2d20d1fcc25c810.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "bytes": 218342,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-015dfefe2091cea2d5d5.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "bytes": 306334,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-de572b70c4267a43c66a.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "bytes": 470728,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-cf42d45d1104e492f130.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "bytes": 176722,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-452ce3c3d7e9a8712c06.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "bytes": 411449,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-9d2b0d8db4abe7b366db.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "pre-training LMs",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.05278",
                "label": "this survey",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/66939/what-is-the-manifold-assumption-in-semi-supervised-learning",
                "label": "a helpful link",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02242",
                "label": "Laine & Aila (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04586",
                "label": "Sajjadi et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/232741/why-is-it-important-to-include-a-bias-correction-term-for-the-adam-optimizer-for",
                "label": "bias correction",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01780",
                "label": "Tarvaninen & Valpola, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6572",
                "label": "Goodfellow et al. 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03976",
                "label": "Miyato et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1903.03825",
                "label": "Verma et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zheng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al. 2019",
                "type": "a"
              },
              {
                "href": "https://pillow.readthedocs.io/en/stable/",
                "label": "PIL",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.664.3543&rep=rep1&type=pdf",
                "label": "Lee 2013",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2004/hash/96f2b50b5d3613adf9c27049b2a888c7-Abstract.html",
                "label": "Grandvalet & Bengio 2004",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04717",
                "label": "Iscen et al. 2019",
                "type": "a"
              },
              {
                "href": "https://ieeexplore.ieee.org/document/1053799",
                "label": "Scudder 1965",
                "type": "a"
              },
              {
                "href": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "label": "Nigram & Ghani CIKM 2000",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.04252",
                "label": "Xie et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.11946",
                "label": "Tan & Le 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09382",
                "label": "Huang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.02194",
                "label": "Du et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.02983",
                "label": "Arazo et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10580",
                "label": "Pham et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.02249",
                "label": "Berthelot et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.09785",
                "label": "Berthelot et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.07394",
                "label": "Junnan Li et al. 2020",
                "type": "a"
              },
              {
                "href": "https://scikit-learn.org/stable/modules/mixture.html",
                "label": "GMM",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11238",
                "label": "Arazo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.07685",
                "label": "Sohn et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.06882",
                "label": "Zoph et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "He et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10029",
                "label": "Chen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.08941",
                "label": "Guo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/LiJunnan1992/DivideMix",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:21Z",
            "source_url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.05278",
                "bytes": 3172260,
                "reused": false,
                "local_path": "papers/repair/85bc9fdf7b6d2f5c5ff6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02242",
                "bytes": 322144,
                "reused": false,
                "local_path": "papers/repair/1366267456ae3965f8c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04586",
                "bytes": 282460,
                "reused": false,
                "local_path": "papers/repair/dfcdfea8469d7c081d06.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01780",
                "bytes": 863822,
                "reused": false,
                "local_path": "papers/repair/f5e8782daef1aa339f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6572",
                "bytes": 1036360,
                "reused": false,
                "local_path": "papers/repair/1b6f12d7db56a03ce596.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03976",
                "bytes": 8496008,
                "reused": false,
                "local_path": "papers/repair/7c610a3bc37a3c724c6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.03825",
                "bytes": 2774709,
                "reused": false,
                "local_path": "papers/repair/c0ed786bf3a3169d24a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": false,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": false,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": false,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04717",
                "bytes": 626230,
                "reused": false,
                "local_path": "papers/repair/ae6e8a0596cf6995095d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "bytes": 230483,
                "reused": false,
                "local_path": "papers/repair/aa557a37f131c5edaca1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.04252",
                "bytes": 2801395,
                "reused": false,
                "local_path": "papers/repair/2d5071bca517ed21302d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.11946",
                "bytes": 933600,
                "reused": false,
                "local_path": "papers/repair/b9c9141c18b68865cdc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09382",
                "bytes": 989025,
                "reused": false,
                "local_path": "papers/repair/531ae1708a14ac8b81dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.02194",
                "bytes": 2525939,
                "reused": false,
                "local_path": "papers/repair/46cf1aae6a3b935b22db.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.02983",
                "bytes": 904317,
                "reused": false,
                "local_path": "papers/repair/4e39b8b3af735acbdef2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10580",
                "bytes": 1245388,
                "reused": false,
                "local_path": "papers/repair/19c860b2949c2d91d5ec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": false,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.02249",
                "bytes": 520905,
                "reused": false,
                "local_path": "papers/repair/c84670ad345d150685e0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.09785",
                "bytes": 420212,
                "reused": false,
                "local_path": "papers/repair/e1bda50022ee2a740e73.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.07394",
                "bytes": 771769,
                "reused": false,
                "local_path": "papers/repair/a688eaa44d9b3d4d3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11238",
                "bytes": 3862031,
                "reused": false,
                "local_path": "papers/repair/4f8506d9f9d2559e3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.07685",
                "bytes": 770166,
                "reused": false,
                "local_path": "papers/repair/f068f1c17b46bc3eed3a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.06882",
                "bytes": 1655938,
                "reused": false,
                "local_path": "papers/repair/d7e01a0318a00ae28138.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": false,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10029",
                "bytes": 823706,
                "reused": false,
                "local_path": "papers/repair/558bd6a836d462b86d7a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.08941",
                "bytes": 345640,
                "reused": true,
                "local_path": "papers/repair/646a76cd251b8253359a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 39098,
            "expected_body_images": 20,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/76583c4985bd/pages/source.html",
            "local_html": "attachments/76583c4985bd/pages/article.html",
            "body_base_path": "attachments/76583c4985bd/pages/",
            "body_markdown_path": "attachments/76583c4985bd/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
          "status": "ok",
          "article_id": "028a8389cdec",
          "local_path": "series-follow/1602/repair/d2f5acee51aa81de8884.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
              "bytes": 251848,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d81486b940074ca7bee2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
              "bytes": 255226,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a6d3abf0912005132083.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
              "bytes": 208573,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/533dde5b3386ec869780.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
              "bytes": 582217,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a27ab134b2539e4fa927.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
              "bytes": 545888,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f2a382c35839b44510af.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
              "bytes": 705319,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5b0a42592fcac6b2269f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
              "bytes": 412179,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f70d56c397cd0359db6b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
              "bytes": 264815,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e108c7cf704e84720825.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
              "bytes": 1047500,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bd8c66b6e5605f2b18ac.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
              "bytes": 246545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/57159f6aa6eb14ac2a40.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
              "bytes": 217492,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cad8d44f6e9a7e9a6aef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
              "bytes": 896102,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5b32e280369a4496da10.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 2: Active Learning",
            "keywords": "主动学习,数据标注,采样",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
            "publish_date": "2022-02",
            "corpus_stage": "数据处理",
            "notes": "主动学习系列综述之二",
            "id": "028a8389cdec",
            "collected_at": "2026-10-02T14:13:03",
            "title": "Learning with not Enough Data Part 2: Active Learning | Lil'Log",
            "body_markdown": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.\nNotations\n#\nSymbol\nMeaning\n$K$\nNumber of unique class labels.\n$(\\mathbf{x}^l, y) \\sim \\mathcal{X}, y \\in \\{0, 1\\}^K$\nLabeled dataset. $y$ is a one-hot representation of the true label.\n$\\mathbf{u} \\sim \\mathcal{U}$\nUnlabeled dataset.\n$\\mathcal{D} = \\mathcal{X} \\cup \\mathcal{U}$\nThe entire dataset, including both labeled and unlabeled examples.\n$\\mathbf{x}$\nAny sample which can be either labeled or unlabeled.\n$\\mathbf{x}_i$\nThe $i$-th sample.\n$U(\\mathbf{x})$\nScoring function for active learning selection.\n$P_\\theta(y \\vert \\mathbf{x})$\nA softmax classifier parameterized by $\\theta$.\n$\\hat{y} = \\arg\\max_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x})$\nThe most confident prediction by the classifier.\n$B$\nLabeling budget (the maximum number of samples to label).\n$b$\nBatch size.\nWhat is Active Learning?\n#\nGiven an unlabeled dataset $\\mathcal{U}$ and a fixed amount of labeling cost $B$, active learning aims to select a subset of $B$ examples from $\\mathcal{U}$ to be labeled such that they can result in maximized improvement in model performance. This is an effective way of learning especially when data labeling is difficult and costly, e.g. medical images. This classical\nsurvey paper\nin 2010 lists many key concepts. While some conventional approaches may not apply to deep learning, discussion in this post mainly focuses on deep neural models and training in batch mode.\nIllustration of a cyclic workflow of active learning, producing better models more efficiently by smartly choosing which samples to label.\nTo simplify the discussion, we assume that the task is a $K$-class classification problem in all the following sections. The model with parameters $\\theta$ outputs a probability distribution over the label candidates, which may or may not be calibrated, $P_\\theta(y \\vert \\mathbf{x})$ and the most likely prediction is $\\hat{y} = \\arg\\max_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x})$.\nAcquisition Function\n#\nThe process of identifying the most valuable examples to label next is referred to as “sampling strategy” or “query strategy”. The scoring function in the sampling process is named “acquisition function”, denoted as $U(\\mathbf{x})$. Data points with higher scores are expected to produce higher value for model training if they get labeled.\nHere is a list of basic sampling strategies.\nUncertainty Sampling\n#\nUncertainty sampling\nselects examples for which the model produces most uncertain predictions. Given a single model, uncertainty can be estimated by the predicted probabilities, although one common complaint is that deep learning model predictions are often not calibrated and not correlated with true uncertainty well. In fact, deep learning models are often overconfident.\nLeast confident score\n, also known as\nvariation ratio\n: $U(\\mathbf{x}) = 1 - P_\\theta(\\hat{y} \\vert \\mathbf{x})$.\nMargin score\n: $U(\\mathbf{x}) = P_\\theta(\\hat{y}_1 \\vert \\mathbf{x}) - P_\\theta(\\hat{y}_2 \\vert \\mathbf{x})$, where $\\hat{y}_1$ and $\\hat{y}_2$ are the most likely and the second likely predicted labels.\nEntropy\n: $U(\\mathbf{x}) = \\mathcal{H}(P_\\theta(y \\vert \\mathbf{x})) = - \\sum_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x}) \\log P_\\theta(y \\vert \\mathbf{x})$.\nAnother way to quantify uncertainty is to rely on a committee of expert models, known as Query-By-Committee (QBC). QBC measures uncertainty based on a pool of opinions and thus it is critical to keep a level of disagreement among committee members. Given $C$ models in the committee pool, each parameterized by $\\theta_1, \\dots, \\theta_C$.\nVoter entropy\n: $U(\\mathbf{x}) = \\mathcal{H}(\\frac{V(y)}{C})$, where $V(y)$ counts the number of votes from the committee on the label $y$.\nConsensus entropy\n: $U(\\mathbf{x}) = \\mathcal{H}(P_\\mathcal{C})$, where $P_\\mathcal{C}$ is the prediction averaging across the committee.\nKL divergence\n: $U(\\mathbf{x}) = \\frac{1}{C} \\sum_{c=1}^C D_\\text{KL} (P_{\\theta_c} | P_\\mathcal{C})$\nDiversity Sampling\n#\nDiversity sampling\nintend to find a collection of samples that can well represent the entire data distribution. Diversity is important because the model is expected to work well on any data in the wild, just not on a narrow subset. Selected samples should be representative of the underlying distribution. Common approaches often rely on quantifying the similarity between samples.\nExpected Model Change\n#\nExpected model change\nrefers to the impact that a sample brings onto the model training. The impact can be the influence on the model weights or the improvement over the training loss. A\nlater section\nreviews several works on how to measure model impact triggered by selected data samples.\nHybrid Strategy\n#\nMany methods above are not mutually exclusive. A\nhybrid\nsampling strategy values different attributes of data points, combining different sampling preferences into one. Often we want to select\nuncertain but also highly representative\nsamples.\nDeep Acquisition Function\n#\nMeasuring Uncertainty\n#\nThe model uncertainty is commonly categorized into two buckets (\nDer Kiureghian & Ditlevsen 2009\n,\nKendall & Gal 2017\n):\nAleatoric uncertainty\nis introduced by noise in the data (e.g. sensor data, noise in the measurement process) and it can be input-dependent or input-independent. It is generally considered as irreducible since there is missing information about the ground truth.\nEpistemic uncertainty\nrefers to the uncertainty within the model parameters and therefore we do not know whether the model can best explain the data. This type of uncertainty is theoretically reducible given more data\nEnsemble and Approximated Ensemble\n#\nThere is a long tradition in machine learning of using ensembles to improve model performance. When there is a significant diversity among models, ensembles are expected to yield better results. This ensemble theory is proved to be correct by many ML algorithms; for example,\nAdaBoost\naggregates many weak learners to perform similar or even better than a single strong learner.\nBootstrapping\nensembles multiple trials of resampling to achieve more accurate estimation of metrics. Random forests or\nGBM\nis also a good example for the effectiveness of ensembling.\nTo get better uncertainty estimation, it is intuitive to aggregate a collection of independently trained models. However, it is expensive to train a single deep neural network model, let alone many of them. In reinforcement learning, Bootstrapped DQN  (\nOsband, et al. 2016\n) is equipped with multiple value heads and relies on the uncertainty among an ensemble of Q value approximation to guide\nexploration\nin RL.\nIn active learning, a commoner approach is to use\ndropout\nto “simulate” a probabilistic Gaussian process (\nGal & Ghahramani 2016\n). We thus ensemble multiple samples collected from the same model but with different dropout masks applied during the forward pass to estimate the model uncertainty (epistemic uncertainty). The process is named\nMC dropout\n(Monte Carlo dropout), where dropout is applied before every weight layer, is approved to be mathematically equivalent to an approximation to the probabilistic deep Gaussian process (\nGal & Ghahramani 2016\n). This simple idea has been shown to be effective for classification with small datasets and widely adopted in scenarios when efficient model uncertainty estimation is needed.\nDBAL\n(Deep Bayesian active learning;\nGal et al. 2017\n) approximates Bayesian neural networks with MC dropout such that it learns a distribution over model weights. In their experiment, MC dropout performed better than random baseline and mean standard deviation (Mean STD), similarly to variation ratios and entropy measurement.\nActive learning results of DBAL on MNIST. (Image source:\nGal et al. 2017\n).\nBeluch et al. (2018)\ncompared ensemble-based models with MC dropout and found that the combination of naive ensemble (i.e. train multiple models separately and independently) and variation ratio yields better calibrated predictions than others. However, naive ensembles are\nvery\nexpensive, so they explored a few alternative cheaper options:\nSnapshot ensemble: Use a cyclic learning rate schedule to train an implicit ensemble such that it converges to different local minima.\nDiversity encouraging ensemble (DEE): Use a base network trained for a small number of epochs as initialization for $n$ different networks, each trained with dropout to encourage diversity.\nSplit head approach: One base model has multiple heads, each corresponding to one classifier.\nUnfortunately all the cheap implicit ensemble options above perform worse than naive ensembles. Considering the limit on computational resources, MC dropout is still a pretty good and economical choice. Naturally, people also try to combine ensemble and MC dropout (\nPop & Fulop 2018\n) to get a bit of additional performance gain by stochastic ensemble.\nUncertainty in Parameter Space\n#\nBayes-by-backprop\n(\nBlundell et al. 2015\n) measures weight uncertainty in neural networks directly. The method maintains a probability distribution over the weights $\\mathbf{w}$, which is modeled as a variational distribution $q(\\mathbf{w} \\vert \\theta)$ since the true posterior $p(\\mathbf{w} \\vert \\mathcal{D})$ is not tractable directly. The loss is to minimize the KL divergence between $q(\\mathbf{w} \\vert \\theta)$ and $p(\\mathbf{w} \\vert \\mathcal{D})$,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta)\n&= \\text{KL}[q(\\mathbf{w}\\vert\\theta) \\| p(\\mathbf{w} \\vert \\mathcal{D})] \\\\ \n&= \\int q(\\mathbf{w}\\vert\\theta) \\log \\frac{q(\\mathbf{w}\\vert\\theta)}{p(\\mathbf{w}) p(\\mathcal{D}\\vert \\mathbf{w})} d\\mathbf{w} \\\\ \n&= \\text{KL}[q(\\mathbf{w}\\vert\\theta) \\| p(w)] - \\mathbb{E}_{q(\\mathbf{w}\\vert\\theta)} [\\log p(\\mathcal{D} \\vert \\mathbf{w})] \\\\\n&\\approx \\log q(\\mathbf{w} \\vert \\theta) - \\log p(\\mathbf{w}) p(\\mathcal{D}\\vert \\mathbf{w}) & \\text{; monte carlo sampling; }q(\\mathbf{w} \\vert \\theta)\\text{ & }p(\\mathbf{w})\\text{ are close.}\n\\end{aligned}\n$$\nThe variational distribution $q$ is typically a Gaussian with diagonal covariance and each weight is sampled from $\\mathcal{N}(\\mu_i, \\sigma_i^2)$. To ensure non-negativity of $\\sigma_i$, it is further parameterized via softplus, $\\sigma_i = \\log(1 + \\exp(\\rho_i))$ where the variational parameters are $\\theta = \\{\\mu_i , \\rho_i\\}^d_{i=1}$.\nThe process of Bayes-by-backprop can be summarized as:\nSample $\\epsilon \\sim \\mathcal{N}(0, I)$\nLet $\\mathbf{w} = \\mu + \\log(1+ \\exp(\\rho)) \\circ \\epsilon$\nLet $\\theta = (\\mu, \\rho)$\nLet $f(\\mathbf{w}, \\theta) = \\log q(\\mathbf{w} \\vert \\theta) - \\log p(\\mathbf{w})p(\\mathcal{D}\\vert \\mathbf{w})$\nCalculate the gradient of $f(\\mathbf{w}, \\theta)$ w.r.t. to $\\mu$ and $\\rho$ and then update $\\theta$.\nUncertainty is measured by sampling different model weights during inference.\nLoss Prediction\n#\nThe loss objective guides model training. A low loss value indicates that a model can make good and accurate predictions.\nYoo & Kweon (2019)\ndesigned a\nloss prediction module\nto predict the loss value for unlabeled inputs, as an estimation of how good a model prediction is on the given data. Data samples are selected if the loss prediction module makes uncertain predictions (high loss value) for them. The loss prediction module is a simple MLP with dropout, that takes several intermediate layer features as inputs and concatenates them after a global average pooling.\nUse the model with a loss prediction module to do active learning selection. (Image source:\nYoo & Kweon 2019\n)\nLet $\\hat{l}$ be the output of the loss prediction module and $l$ be the true loss. When training the loss prediction module, a simple MSE loss $=(l - \\hat{l})^2$ is not a good choice, because the loss decreases in time as the model learns to behave better. A good learning objective should be independent of the scale changes of the target loss. They instead rely on the comparison of sample pairs. Within each batch of size $b$, there are $b/2$ pairs of samples $(\\mathbf{x}_i, \\mathbf{x}_j)$ and the loss prediction model is expected to correctly predict which sample has a larger loss.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loss}(\\mathbf{x}_i, \\mathbf{x}_j) &= \\max\\big( 0, -\\mathbb{1}(l(\\mathbf{x}_i), l(\\mathbf{x}_j)) \\cdot (\\hat{l}(\\mathbf{x}_i) - \\hat{l}(\\mathbf{x}_j)) + \\epsilon \\big) \\\\ \n\\text{where } \\mathbb{1}(l_i, l_j) &= \\begin{cases} +1 & \\text{if }l_i > l_j \\\\ -1 & \\text{otherwise} \\end{cases} \n\\end{aligned}\n$$\nwhere $\\epsilon$ is a predefined positive margin constant.\nIn experiments on three vision tasks, active learning selection based on the loss prediction performs better than random baseline, entropy based acquisition and\ncore-set\n.\nActive learning results of loss prediction module based selection, in comparison with other approaches. (Image source:\nYoo & Kweon 2019\n)\nAdversarial Setup\n#\nSinha et al. (2019)\nproposed a GAN-like setup, named\nVAAL\n(Variational Adversarial Active Learning), where a discriminator is trained to distinguish unlabeled data from labeled data. Interestingly, active learning acquisition criteria does not depend on the task performance in VAAL.\nIllustration of VAAL (Variational adversarial active learning). (Image source:\nSinha et al. 2019\n)\nThe $\\beta$-VAE learns a latent feature space $\\mathbf{z}^l \\cup \\mathbf{z}^u$, for labeled and unlabeled data respectively, aiming to\ntrick\nthe discriminator $D(.)$ that all the data points are from the labeled pool;\nThe discriminator $D(.)$ predicts whether a sample is labeled (1) or not (0) based on a latent representation $\\mathbf{z}$. VAAL selects unlabeled samples with low discriminator scores, which indicates that those samples are sufficiently different from previously labeled ones.\nThe loss for VAE representation learning in VAAL contains both a reconstruction part (minimizing the ELBO of given samples) and an adversarial part (labeled and unlabeled data is drawn from the same probability distribution $q_\\phi$):\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{VAE} &= \\lambda_1 \\mathcal{L}^\\text{rec}_\\text{VAE} + \\lambda_2 \\mathcal{L}^\\text{adv}_\\text{VAE} \\\\\n\\mathcal{L}^\\text{rec}_\\text{VAE} &= \\mathbb{E}[\\log p_\\theta(\\mathbf{x}^l \\vert \\mathbf{z}^l)] - \\beta \\text{KL}(q_\\phi(\\mathbf{z}^l \\vert \\mathbf{x}^l) \\| p(\\mathbf{\\tilde{z}})) + \\mathbb{E}[\\log p_\\theta(\\mathbf{u} \\vert \\mathbf{z}^u)] - \\beta \\text{KL}(q_\\phi(\\mathbf{z}^u \\vert \\mathbf{u}) \\| p(\\mathbf{\\tilde{z}})) \\\\\n\\mathcal{L}^\\text{adv}_\\text{VAE} &= - \\mathbb{E}[\\log D(q_\\phi (\\mathbf{z}^l \\vert \\mathbf{x}^l))] - \\mathbb{E}[\\log D(q_\\phi(\\mathbf{z}^u \\vert \\mathbf{u}))]\n\\end{aligned}\n$$\nwhere $p(\\mathbf{\\tilde{z}})$ is a unit Gaussian as a predefined prior and $\\beta$ is the Lagrangian parameter.\nThe discriminator loss is:\n$$\n\\mathcal{L}_D = -\\mathbb{E}[\\log D(q_\\phi (\\mathbf{z}^l \\vert \\mathbf{x}^l))] - \\mathbb{E}[\\log (1 - D(q_\\phi (\\mathbf{z}^u \\vert \\mathbf{u})))]\n$$\nExperiment results of VAAL (variational adversarial active learning) on several image classification tasks. (Image source:\nSinha et al. 2019\nAblation studies showed that jointly training VAE and discriminator is critical. Their results are robust to the biased initial labeled pool, different labeling budgets and noisy oracle.\nMAL\n(Minimax Active Learning;\nEbrahimiet al. 2021\n) is an extension of VAAL. The MAL framework consists of an entropy minimizing feature encoding network $F$ followed by an entropy maximizing classifier $C$. This minimax setup reduces the distribution gap between labeled and unlabeled data.\nIllustration of the MAL (minimax active learning) framework. (Image source:\nEbrahimiet al. 2021\n)\nA feature encoder $F$ encodes a sample into a $\\ell_2$-normalized $d$-dimensional latent vector. Assuming there are $K$ classes, a classifier $C$ is parameterized by $\\mathbf{W} \\in \\mathbb{R}^{d \\times K}$.\n(1) First $F$ and $C$ are trained on labeled samples by a simple cross entropy loss to achieve good classification results,\n$$\n\\mathcal{L}_\\text{CE} = -\\mathbb{E}_{(\\mathbf{x}^l, y) \\sim \\mathcal{X}} \\sum_{k=1}^K \\mathbb{1}[k=y] \\log\\Big( \\sigma(\\frac{1}{T} \\frac{\\mathbf{W}^\\top F\\big(\\mathbf{x}^l)}{\\|F(\\mathbf{x}^l)\\|}\\big) \\Big)\n$$\n(2) When training on the unlabeled examples, MAL relies on a\nminimax\ngame setup\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{Ent} &= -\\sum^K_{k=1} p(y=k \\vert \\mathbf{u}) \\log p(y=k\\vert \\mathbf{u}) \\\\\n\\theta^*_F, \\theta^*_C &= \\min_F\\max_C \\mathcal{L}_\\text{Ent} \\\\\n\\theta_F &\\gets \\theta_F - \\alpha_1 \\nabla \\mathcal{L}_\\text{Ent} \\\\\n\\theta_C &\\gets \\theta_C + \\alpha_2 \\nabla \\mathcal{L}_\\text{Ent}\n\\end{aligned}\n$$\nwhere,\nFirst, minimizing the entropy in $F$ encourages unlabeled samples associated with similar predicted labels to have similar features.\nMaximizing the entropy in $C$ adversarially makes the prediction to follow a more uniform class distribution.\n(My understanding here is that because the true label of an unlabeled sample is unknown, we should not optimize the classifier to maximize the predicted labels just yet.)\nThe discriminator is trained in the same way as in VAAL.\nSampling strategy in MAL considers both diversity and uncertainty:\nDiversity: the score of $D$ indicates how similar a sample is to previously seen examples. A score closer to 0 is better to select unfamiliar data points.\nUncertainty: use the entropy obtained by $C$. A higher entropy score indicates that the model cannot make a confident prediction yet.\nThe experiments compared MAL to random, entropy, core-set, BALD and VAAL baselines, on image classification and segmentation tasks. The results look pretty strong.\nPerformance of MAL on ImageNet. (Table source:\nEbrahimiet al. 2021\n)\nCAL\n(Contrastive Active Learning;\nMargatina et al. 2021\n) intends to select\ncontrastive\nexamples. If two data points with different labels share similar network representations $\\Phi(.)$, they are considered as contrastive examples in CAL. Given a pair of contrastive examples $(\\mathbf{x}_i, \\mathbf{x}_j)$, they should\n$$\nd(\\Phi(\\mathbf{x}_i), \\Phi(\\mathbf{x}_j)) < \\epsilon \\quad\\text{and}\\quad \\text{KL}(p(y\\vert \\mathbf{x}_i) \\| p(y\\vert \\mathbf{x}_j)) \\rightarrow \\infty\n$$\nGiven an unlabeled sample $\\mathbf{x}$, CAL runs the following process:\nSelect the top $k$ nearest neighbors in the model feature space among the labeled samples, $\\{(\\mathbf{x}^l_i, y_i\\}_{i=1}^M \\subset \\mathcal{X}$.\nCompute the KL divergence between the model output probabilities of $\\mathbf{x}$ and each in $\\{\\mathbf{x}^l\\}$. The contrastive score of $\\mathbf{x}$ is the average of these KL divergence values: $s(\\mathbf{x}) = \\frac{1}{M} \\sum_{i=1}^M \\text{KL}(p(y \\vert \\mathbf{x}^l_i | p(y \\vert \\mathbf{x}))$.\nSamples with\nhigh contrastive scores\nare selected for active learning.\nOn a variety of classification tasks, the experiment results of CAL look similar to the entropy baseline.\nMeasuring Representativeness\n#\nCore-sets Approach\n#\nA\ncore-set\nis a concept in computational geometry, referring to a small set of points that approximates the shape of a larger point set. Approximation can be captured by some geometric measure. In the active learning, we expect a model that is trained over the core-set to behave comparably with the model on the entire data points.\nSener & Savarese (2018)\ntreats active learning as a core-set selection problem. Let’s say, there are $N$ samples in total accessible during training. During active learning, a small set of data points get labeled at every time step $t$, denoted as $\\mathcal{S}^{(t)}$. The upper bound of the learning objective can be written as follows, where the\ncore-set loss\nis defined as the difference between average empirical loss over the labeled samples and the loss over the entire dataset including unlabelled ones.\n$$\n\\begin{aligned}\n\\mathbb{E}_{(\\mathbf{x}, y) \\sim p} [\\mathcal{L}(\\mathbf{x}, y)]\n\\leq& \\bigg\\vert \\mathbb{E}_{(\\mathbf{x}, y) \\sim p} [\\mathcal{L}(\\mathbf{x}, y)] - \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) \\bigg\\vert & \\text{; Generalization error}\\\\\n+& \\frac{1}{\\vert \\mathcal{S}^{(t)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) & \\text{; Training error}\\\\\n+& \\bigg\\vert \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) - \\frac{1}{\\vert \\mathcal{S}^{(t)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) \\bigg\\vert & \\text{; Core-set error}\n\\end{aligned}\n$$\nThen the active learning problem can be redefined as:\n$$\n\\min_{\\mathcal{S}^{(t+1)} : \\vert \\mathcal{S}^{(t+1)} \\vert \\leq b} \\bigg\\vert \\frac{1}{N}\\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) - \\frac{1}{\\vert \\mathcal{S}^{(t)} \\cup \\mathcal{S}^{(t+1)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\cup \\mathcal{S}^{(t+1)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) \\bigg\\vert\n$$\nIt is equivalent to\nthe $k$-Center problem\n: choose $b$ center points such that the largest distance between a data point and its nearest center is minimized. This problem is NP-hard. An approximate solution depends on the greedy algorithm.\nActive learning results of core-sets algorithm in comparison with several common baselines on CIFAR-10, CIFAR-100, SVHN. (Image source:\nSener & Savarese 2018\n)\nIt works well on image classification tasks when there is a small number of classes. When the number of classes grows to be large or the data dimensionality increases (“curse of dimensionality”), the core-set method becomes less effective (\nSinha et al. 2019\n).\nBecause the core-set selection is expensive,\nColeman et al. (2020)\nexperimented with a weaker model (e.g. smaller, weaker architecture, not fully trained) and found that empirically using a weaker model as a proxy can significantly shorten each repeated data selection cycle of training models and selecting samples, without hurting the final error much. Their method is referred to as\nSVP\n(Selection via Proxy).\nDiverse Gradient Embedding\n#\nBADGE\n(Batch Active learning by Diverse Gradient Embeddings;\nAsh et al. 2020\n) tracks both model uncertainty and data diversity in the gradient space. Uncertainty is measured by the gradient magnitude w.r.t. the final layer of the network and diversity is captured by a diverse set of samples that span in the gradient space.\nUncertainty. Given an unlabeled sample $\\mathbf{x}$, BADGE first computes the prediction $\\hat{y}$ and the gradient $g_\\mathbf{x}$ of the loss on $(\\mathbf{x}, \\hat{y})$ w.r.t. the last layer’s parameters. They observed that the norm of $g_\\mathbf{x}$ conservatively estimates the example’s influence on the model learning and high-confidence samples tend to have gradient embeddings of small magnitude.\nDiversity. Given many gradient embeddings of many samples, $g_\\mathbf{x}$, BADGE runs\n$k$-means++\nto sample data points accordingly.\nAlgorithm of BADGE (batch active learning by diverse gradient embeddings). (Image source:\nAsh et al. 2020\n)\nMeasuring Training Effects\n#\nQuantify Model Changes\n#\nSettles et al. (2008)\nintroduced an active learning query strategy, named\nEGL\n(Expected Gradient Length). The motivation is to find samples that can trigger the greatest update on the model if their labels are known.\nLet $\\nabla \\mathcal{L}(\\theta)$ be the gradient of the loss function with respect to the model parameters. Specifically, given an unlabeled sample $\\mathbf{x}_i$, we need to calculate the gradient assuming the label is $y \\in \\mathcal{Y}$, $\\nabla \\mathcal{L}^{(y)}(\\theta)$. Because the true label $y_i$ is unknown, EGL relies on the current model belief to compute the expected gradient change:\n$$\n\\text{EGL}(\\mathbf{x}_i) = \\sum_{y_i \\in \\mathcal{Y}} p(y=y_i \\vert \\mathbf{x}) \\|\\nabla \\mathcal{L}^{(y_i)}(\\theta)\\|\n$$\nBALD\n(Bayesian Active Learning by Disagreement;\nHoulsby et al. 2011\n) aims to identify samples to maximize the information gain about the model weights, that is equivalent to maximize the decrease in expected posterior entropy.\n$$\n\\begin{aligned}\nI[\\boldsymbol{\\theta}, y \\vert x,\\mathcal{D}] \n&= H(\\boldsymbol{\\theta} \\vert \\mathcal{D}) - \\mathbb{E}_{y \\sim p(y \\vert \\boldsymbol{x}, \\mathcal{D})} \\big[ H(\\boldsymbol{\\theta} \\vert y, \\boldsymbol{x}, \\mathcal{D}) \\big] & \\text{; Decrease in expected posterior entropy}\\\\ \n&= H(y \\vert \\boldsymbol{x}, \\mathcal{D}) - \\mathbb{E}_{\\boldsymbol{\\theta} \\sim p(\\boldsymbol{\\theta} \\vert \\mathcal{D})} \\big[ H(y \\vert \\boldsymbol{x}, \\mathcal{\\theta}) \\big]\n\\end{aligned}\n$$\nThe underlying interpretation is to “seek $\\mathbf{x}$ for which the model is marginally most uncertain about $y$ (high $H(y \\vert \\mathbf{x}, \\mathcal{D})$), but for which individual settings of the parameters are confident (low $H(y \\vert \\mathbf{x}, \\boldsymbol{\\theta})$).” In other words, each individual posterior draw is confident but a collection of draws carry diverse opinions.\nBALD was originally proposed for an individual sample and\nKirsch et al. (2019)\nextended it to work in batch mode.\nForgetting Events\n#\nTo investigate whether neural networks have a tendency to\nforget\npreviously learned information,\nMariya Toneva et al. (2019)\ndesigned an experiment: They track the model prediction for each sample during the training process and count the transitions for each sample from being classified correctly to incorrectly or vice-versa. Then samples can be categorized accordingly,\nForgettable\n(redundant) samples: If the class label changes across training epochs.\nUnforgettable\nsamples: If the class label assignment is consistent across training epochs. Those samples are never forgotten once learned.\nThey found that there are a large number of unforgettable examples that are never forgotten once learnt. Examples with noisy labels or images with “uncommon” features (visually complicated to classify) are among the most forgotten examples. The experiments empirically validated that unforgettable examples can be safely removed without compromising model performance.\nIn the implementation, the forgetting event is only counted when a sample is included in the current training batch; that is, they compute forgetting across presentations of the same example in subsequent mini-batches. The number of forgetting events per sample is quite stable across different seeds and forgettable examples have a small tendency to be first-time learned later in the training. The forgetting events are also found to be transferable throughout the training period and between architectures.\nForgetting events can be used as a signal for active learning acquisition if we hypothesize a model changing predictions during training is an indicator of model uncertainty. However, ground truth is unknown for unlabeled samples.\nBengar et al. (2021)\nproposed a new metric called\nlabel dispersion\nfor such a purpose. Let’s see across the training time, $c^*$ is the most commonly predicted label for the input $\\mathbf{x}$ and the label dispersion measures the fraction of training steps when the model does not assign $c^**$ to this sample:\n$$\n\\text{Dispersion}(\\mathbf{x}) = 1 - \\frac{f_\\mathbf{x}}{T} \\text{ where }\nf_\\mathbf{x} = \\sum_{t=1}^T \\mathbb{1}[\\hat{y}_t = c^*], c^* = \\arg\\max_{c=1,\\dots,C}\\sum_{t=1}^T \\mathbb{1}[\\hat{y}_t = c]\n$$\nIn their implementation, dispersion is computed at every epoch. Label dispersion is low if the model consistently assigns the same label to the same sample but high if the prediction changes often. Label dispersion is correlated with network uncertainty, as shown in\nLabel dispersion is correlated with network uncertainty. On the x-axis, data points are sorted by label dispersion scores. The y-axis is the model prediction accuracy when the model trys to infer the labels for those samples. (Image source:\nBengar et al. 2021\n)\nHybrid\n#\nWhen running active learning in batch mode, it is important to control diversity within a batch.\nSuggestive Annotation\n(\nSA\n;\nYang et al. 2017\n) is a two-step hybrid strategy, aiming to select both high uncertainty & highly representative labeled samples. It uses uncertainty obtained from an ensemble of models trained on the labeled data and core-sets for choosing representative data samples.\nFirst, SA selects top $K$ images with high uncertainty scores to form a candidate pool $\\mathcal{S}_c \\subseteq \\mathcal{S}_U$. The uncertainty is measured as disagreement between multiple models training with bootstrapping.\nThe next step is to find a subset $\\mathcal{S}_a \\subseteq \\mathcal{S}_c$ with highest representativeness. The cosine similarity between feature vectors of two inputs approximates how similar they are. The representativeness of $\\mathcal{S}_a$ for $\\mathcal{S}_U$ reflects how well $\\mathcal{S}_a$ can represent all the samples in $\\mathcal{S}_u$, defined as:\n$$\nF(\\mathcal{S}_a, \\mathcal{S}_u) = \\sum_{\\mathbf{x}_j \\in \\mathcal{S}_u} f(\\mathcal{S}_a, \\mathbf{x}_j) = \\sum_{\\mathbf{x}_j \\in \\mathcal{S}_u} \\max_{\\mathbf{x}_i \\in \\mathcal{S}_a} \\text{sim}(\\mathbf{x}_i, \\mathbf{x}_j)\n$$\nFormulating $\\mathcal{S}_a \\subseteq \\mathcal{S}_c$ with $k$ data points that maximizes $F(\\mathcal{S}_a, \\mathcal{S}_u)$ is a generalized version of the maximum set cover problem. It is NP-hard and its best possible polynomial time approximation algorithm is a simple greedy method.\nInitially, $\\mathcal{S}_a = \\emptyset$ and $F(\\mathcal{S}_a, \\mathcal{S}_u) = 0$.\nThen,  iteratively add $\\mathbf{x}_i \\in \\mathcal{S}_c$ that maximizes $F(\\mathcal{S}_a \\cup I_i, \\mathcal{S}_u)$ over $\\mathcal{S}_a$, until $\\mathcal{S}_s$ contains $k$ images.\nZhdanov (2019)\nruns a similar process as SA, but at step 2, it relies on $k$-means instead of core-set, where the size of the candidate pool is configured relative to the batch size. Given batch size $b$ and a constant $beta$ (between 10 and 50), it follows these steps:\nTrain a classifier on the labeled data;\nMeasure informativeness of every unlabeled example (e.g. using uncertainty metrics);\nPrefilter top $\\beta b \\geq b$ most informative examples;\nCluster $\\beta b$ examples into $B$ clusters;\nSelect $b$ different examples closest to the cluster centers for this round of active learning.\nActive learning can be further combined with\nsemi-supervised learning\nto save the budget.\nCEAL\n(Cost-Effective Active Learning;\nYang et al. 2017\n) runs two things in parallel:\nSelect uncertain samples via active learning and get them labeled;\nSelect samples with the most confident prediction and assign them\npseudo labels\n. The confidence prediction is judged by whether the prediction entropy is below a threshold $\\delta$. As the model is getting better in time, the threshold $\\delta$ decays in time as well.\nIllustration of CEAL (cost-effective active learning). (Image source:\nYang et al. 2017\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Feb 2022). Learning with not enough data part 2: active learning. Lil’Log. https://lilianweng.github.io/posts/2022-02-20-active-learning/.\nOr\n@article{weng2022active,\n  title   = \"Learning with not Enough Data Part 2: Active Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2022\",\n  month   = \"Feb\",\n  url     = \"https://lilianweng.github.io/posts/2022-02-20-active-learning/\"\n}\nReferences\n#\n[1] Burr Settles.\nActive learning literature survey.\nUniversity of Wisconsin, Madison, 52(55-66):11, 2010.\n[2]\nhttps://jacobgil.github.io/deeplearning/activelearning\n[3] Yang et al.\n“Cost-effective active learning for deep image classification”\nTCSVT 2016.\n[4] Yarin Gal et al.\n“Dropout as a Bayesian Approximation: representing model uncertainty in deep learning.”\nICML 2016.\n[5] Blundell et al.\n“Weight uncertainty in neural networks (Bayes-by-Backprop)”\nICML 2015.\n[6] Settles et al.\n“Multiple-Instance Active Learning.”\nNIPS 2007.\n[7] Houlsby et al.\nBayesian Active Learning for Classification and Preference Learning.\"\narXiv preprint arXiv:1112.5745 (2020).\n[8] Kirsch et al.\n“BatchBALD: Efficient and Diverse Batch Acquisition for Deep Bayesian Active Learning.”\nNeurIPS 2019.\n[9] Beluch et al.\n“The power of ensembles for active learning in image classification.”\nCVPR 2018.\n[10] Sener & Savarese.\n“Active learning for convolutional neural networks: A core-set approach.”\nICLR 2018.\n[11] Donggeun Yoo & In So Kweon.\n“Learning Loss for Active Learning.”\nCVPR 2019.\n[12] Margatina et al.\n“Active Learning by Acquiring Contrastive Examples.”\nEMNLP 2021.\n[13] Sinha et al.\n“Variational Adversarial Active Learning”\nICCV 2019\n[14] Ebrahimiet al.\n“Minmax Active Learning”\narXiv preprint arXiv:2012.10467 (2021).\n[15] Mariya Toneva et al.\n“An empirical study of example forgetting during deep neural network learning.”\nICLR 2019.\n[16] Javad Zolfaghari Bengar et al.\n“When Deep Learners Change Their Mind: Learning Dynamics for Active Learning.”\nCAIP 2021.\n[17] Yang et al.\n“Suggestive annotation: A deep active learning framework for biomedical image segmentation.”\nMICCAI 2017.\n[18] Fedor Zhdanov.\n“Diverse mini-batch Active Learning”\narXiv preprint arXiv:1901.05954 (2019).",
            "metadata": {
              "title": "Learning with not Enough Data Part 2: Active Learning | Lil'Log",
              "description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "keywords": "data, active-learning",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 2: Active Learning",
              "og:description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 2: Active Learning",
              "twitter:description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "article:section": "posts",
              "article:published_time": "2022-02-20T00:00:00+00:00",
              "article:modified_time": "2022-02-20T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/028a8389cdec/code/body-000.txt",
                "chars": 276,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
                "bytes": 251848,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-d81486b940074ca7bee2.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
                "bytes": 255226,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-a6d3abf0912005132083.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
                "bytes": 208573,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-533dde5b3386ec869780.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
                "bytes": 582217,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-a27ab134b2539e4fa927.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
                "bytes": 545888,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-f2a382c35839b44510af.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
                "bytes": 705319,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-5b0a42592fcac6b2269f.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
                "bytes": 412179,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-f70d56c397cd0359db6b.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
                "bytes": 264815,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-e108c7cf704e84720825.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
                "bytes": 1047500,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-bd8c66b6e5605f2b18ac.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
                "bytes": 246545,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-57159f6aa6eb14ac2a40.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
                "bytes": 217492,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-cad8d44f6e9a7e9a6aef.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
                "bytes": 896102,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-5b32e280369a4496da10.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://burrsettles.com/pub/settles.activelearning.pdf",
                "label": "survey paper",
                "type": "a"
              },
              {
                "href": "https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.455.9057&rep=rep1&type=pdf",
                "label": "Der Kiureghian & Ditlevsen 2009",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.04977",
                "label": "Kendall & Gal 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/AdaBoost",
                "label": "AdaBoost",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bootstrapping_(statistics)",
                "label": "Bootstrapping",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Gradient_boosting",
                "label": "GBM",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.04621",
                "label": "Osband, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
                "label": "exploration",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02142",
                "label": "Gal & Ghahramani 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02157",
                "label": "Gal & Ghahramani 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.02910",
                "label": "Gal et al. 2017",
                "type": "a"
              },
              {
                "href": "https://openaccess.thecvf.com/content_cvpr_2018/papers/Beluch_The_Power_of_CVPR_2018_paper.pdf",
                "label": "Beluch et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.03897",
                "label": "Pop & Fulop 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05424",
                "label": "Blundell et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.03677",
                "label": "Yoo & Kweon (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.00370",
                "label": "Sinha et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2012.10467",
                "label": "Ebrahimiet al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2109.03764",
                "label": "Margatina et al. 2021",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "contrastive",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.00489",
                "label": "Sener & Savarese (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Metric_k-center",
                "label": "the $k$-Center problem",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.11829",
                "label": "Coleman et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.03671",
                "label": "Ash et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-means%2B%2B",
                "label": "$k$-means++",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2007/hash/a1519de5b5d44b31a01de013b9b51a80-Abstract.html",
                "label": "Settles et al. (2008)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1112.5745",
                "label": "Houlsby et al. 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.08158",
                "label": "Kirsch et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.05159",
                "label": "Mariya Toneva et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2107.14707",
                "label": "Bengar et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.04737",
                "label": "Yang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.05954",
                "label": "Zhdanov (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
                "label": "semi-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1701.03551",
                "label": "Yang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://jacobgil.github.io/deeplearning/activelearning",
                "label": "https://jacobgil.github.io/deeplearning/activelearning",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:24Z",
            "source_url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
            "papers": [
              {
                "status": "ok",
                "url": "https://burrsettles.com/pub/settles.activelearning.pdf",
                "bytes": 1939936,
                "reused": false,
                "local_path": "papers/repair/1a9a9c6742fab449158e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.04977",
                "bytes": 6719323,
                "reused": false,
                "local_path": "papers/repair/266ae612868b87b732a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.04621",
                "bytes": 6874097,
                "reused": false,
                "local_path": "papers/repair/d7a1d129f52a82d595ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02142",
                "bytes": 1107246,
                "reused": false,
                "local_path": "papers/repair/4fb011fb3475ef624220.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02157",
                "bytes": 436231,
                "reused": false,
                "local_path": "papers/repair/f341fa9dd0f0f593ee60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.02910",
                "bytes": 724240,
                "reused": false,
                "local_path": "papers/repair/523334b8d44dca5de9f0.pdf"
              },
              {
                "status": "ok",
                "url": "https://openaccess.thecvf.com/content_cvpr_2018/papers/Beluch_The_Power_of_CVPR_2018_paper.pdf",
                "bytes": 1715354,
                "reused": false,
                "local_path": "papers/repair/f0bcca0541114ac25b32.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.03897",
                "bytes": 4205547,
                "reused": false,
                "local_path": "papers/repair/ce97c4ced1411688db16.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05424",
                "bytes": 628773,
                "reused": false,
                "local_path": "papers/repair/475ff08ad5512624a7cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.03677",
                "bytes": 564131,
                "reused": false,
                "local_path": "papers/repair/79dc6ada83281404ff9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.00370",
                "bytes": 930575,
                "reused": false,
                "local_path": "papers/repair/79c5aedc49e45da7dda8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2012.10467",
                "bytes": 1339851,
                "reused": false,
                "local_path": "papers/repair/90cd58e430cea1408452.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2109.03764",
                "bytes": 2036447,
                "reused": false,
                "local_path": "papers/repair/f5ba7910af8e3a2395ac.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.00489",
                "bytes": 5033708,
                "reused": false,
                "local_path": "papers/repair/238fc8d82668ad254fc1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.11829",
                "bytes": 17351339,
                "reused": false,
                "local_path": "papers/repair/ad0851b7cc881c207705.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.03671",
                "bytes": 4265486,
                "reused": false,
                "local_path": "papers/repair/7474699a4e844a465ace.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1112.5745",
                "bytes": 556354,
                "reused": false,
                "local_path": "papers/repair/d0182f4c21330f972a26.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.08158",
                "bytes": 4001227,
                "reused": false,
                "local_path": "papers/repair/b525dbbc20e226a0e95a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.05159",
                "bytes": 1731989,
                "reused": true,
                "local_path": "papers/repair/55cf5f36e50e938900cd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2107.14707",
                "bytes": 488570,
                "reused": false,
                "local_path": "papers/repair/27448d46f2a1e682c257.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.04737",
                "bytes": 5679851,
                "reused": false,
                "local_path": "papers/repair/de814b520904eeb1ed6e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.05954",
                "bytes": 387045,
                "reused": false,
                "local_path": "papers/repair/3bd458965ad0d9c6d253.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.03551",
                "bytes": 2102878,
                "reused": false,
                "local_path": "papers/repair/85a5a6a9cc2ce15af84e.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 32971,
            "expected_body_images": 12,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/028a8389cdec/pages/source.html",
            "local_html": "attachments/028a8389cdec/pages/article.html",
            "body_base_path": "attachments/028a8389cdec/pages/",
            "body_markdown_path": "attachments/028a8389cdec/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
          "status": "ok",
          "article_id": "c8f3f2a59bb8",
          "local_path": "series-follow/1602/repair/0322612d07df5f51284a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
              "bytes": 82669,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c8feb8e3831d6f407222.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
              "bytes": 238558,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/864616500d13b290a57d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
              "bytes": 618000,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4d1eafbd2698e4b13414.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
              "bytes": 447800,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2202dbf059680ff25f64.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
              "bytes": 331316,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/56fdc531021fd8fc266d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
              "bytes": 92328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a3de29261702db65276c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
              "bytes": 292083,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9fbb7be242e78cf4064e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
              "bytes": 165448,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7c6e570b2b4acaea53ee.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
              "bytes": 410905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0dc7fb2e267a076918a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
              "bytes": 160971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/64c06b583b29bc8d849d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
              "bytes": 575598,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/24abca83dac665bdfd2c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
              "bytes": 191327,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/68a57a589ced1a8dcbeb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
              "bytes": 458778,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dec760a7d6d875b1e5f6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
              "bytes": 413067,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3b05f2c9b09900dd678c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
              "bytes": 307781,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9fe78703c0d6dd59901b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
              "bytes": 395407,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bcffab9e56e403b12eb6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
              "bytes": 378369,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/14fc3bb2a028bd633430.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
              "bytes": 269518,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1cdb06387d4aabe19e7f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
              "bytes": 1172082,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dc3294612801cee60ee0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
              "bytes": 299081,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4ecf4ae1a9c6c75e0b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
              "bytes": 102477,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2f938fd27f3112a7668b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
              "bytes": 302804,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/476b14449fa38214486c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
              "bytes": 459618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d417f179aa932198443f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
              "bytes": 248555,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/61290a159906f77df170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
              "bytes": 263986,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/25636cdf26fe48bc32a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
              "bytes": 127994,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1f6149bb39a134da1e75.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
              "bytes": 167429,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/75a0434d42ea9e13e5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
              "bytes": 235880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0873d959165b59705852.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
              "bytes": 403903,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7fc9d0b8fcf86efd800b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
              "bytes": 237372,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4a85aecfe0dc34b27289.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Contrastive Representation Learning",
            "keywords": "对比学习,表示学习,自监督",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "publish_date": "2021-05",
            "corpus_stage": "预训练/SFT",
            "notes": "对比表示学习综述（SimCLR、MoCo等）",
            "id": "c8f3f2a59bb8",
            "collected_at": "2026-10-02T14:12:57",
            "title": "Contrastive Representation Learning | Lil'Log",
            "body_markdown": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in\nself-supervised learning\n.\nContrastive Training Objectives\n#\nIn early versions of loss functions for contrastive learning, only one positive and one negative sample are involved. The trend in recent training objectives is to include multiple positive and negative pairs in one batch.\nContrastive Loss\n#\nContrastive loss\n(\nChopra et al. 2005\n) is one of the earliest training objectives used for deep metric learning in a contrastive fashion.\nGiven a list of input samples $\\{ \\mathbf{x}_i \\}$, each has a corresponding label $y_i \\in \\{1, \\dots, L\\}$ among $L$ classes. We would like to learn a function $f_\\theta(.): \\mathcal{X}\\to\\mathbb{R}^d$ that encodes $x_i$ into an embedding vector such that examples from the same class have similar embeddings and samples from different classes have very different ones. Thus, contrastive loss takes a pair of inputs $(x_i, x_j)$ and minimizes the embedding distance when they are from the same class but maximizes the distance otherwise.\n$$\n\\mathcal{L}_\\text{cont}(\\mathbf{x}_i, \\mathbf{x}_j, \\theta) = \\mathbb{1}[y_i=y_j] \\| f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\|^2_2 + \\mathbb{1}[y_i\\neq y_j]\\max(0, \\epsilon - \\|f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j)\\|_2)^2\n$$\nwhere $\\epsilon$ is a hyperparameter, defining the lower bound distance between samples of different classes.\nTriplet Loss\n#\nTriplet loss\nwas originally proposed in the FaceNet (\nSchroff et al. 2015\n) paper and was used to learn face recognition of the same person at different poses and angles.\nIllustration of triplet loss given one positive and one negative per anchor. (Image source:\nSchroff et al. 2015\n)\nGiven one anchor input $\\mathbf{x}$, we select one positive sample $\\mathbf{x}^+$ and one negative $\\mathbf{x}^-$, meaning that $\\mathbf{x}^+$ and $\\mathbf{x}$ belong to the same class and $\\mathbf{x}^-$ is sampled from another different class. Triplet loss learns to minimize the distance between the anchor $\\mathbf{x}$ and positive $\\mathbf{x}^+$ and maximize the distance between the anchor $\\mathbf{x}$ and negative $\\mathbf{x}^-$ at the same time with the following equation:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) = \\sum_{\\mathbf{x} \\in \\mathcal{X}} \\max\\big( 0, \\|f(\\mathbf{x}) - f(\\mathbf{x}^+)\\|^2_2 - \\|f(\\mathbf{x}) - f(\\mathbf{x}^-)\\|^2_2 + \\epsilon \\big)\n$$\nwhere the margin parameter $\\epsilon$ is configured as the minimum offset between distances of similar vs dissimilar pairs.\nIt is crucial to select challenging $\\mathbf{x}^-$ to truly improve the model.\nLifted Structured Loss\n#\nLifted Structured Loss\n(\nSong et al. 2015\n) utilizes all the pairwise edges within one training batch for better computational efficiency.\nIllustration compares contrastive loss, triplet loss and lifted structured loss. Red and blue edges connect similar and dissimilar sample pairs respectively. (Image source:\nSong et al. 2015\n)\nLet $D_{ij} = | f(\\mathbf{x}_i) - f(\\mathbf{x}_j) |_2$, a structured loss function is defined as\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{struct} &= \\frac{1}{2\\vert \\mathcal{P} \\vert} \\sum_{(i,j) \\in \\mathcal{P}} \\max(0, \\mathcal{L}_\\text{struct}^{(ij)})^2 \\\\\n\\text{where } \\mathcal{L}_\\text{struct}^{(ij)} &= D_{ij} + \\color{red}{\\max \\big( \\max_{(i,k)\\in \\mathcal{N}} \\epsilon - D_{ik}, \\max_{(j,l)\\in \\mathcal{N}} \\epsilon - D_{jl} \\big)}\n\\end{aligned}\n$$\nwhere $\\mathcal{P}$ contains the set of positive pairs and $\\mathcal{N}$ is the set of negative pairs. Note that the dense pairwise squared distance matrix can be easily computed per training batch.\nThe\nred\npart in $\\mathcal{L}_\\text{struct}^{(ij)}$ is used for mining hard negatives. However, it is not smooth and may cause the convergence to a bad local optimum in practice. Thus, it is relaxed to be:\n$$\n\\mathcal{L}_\\text{struct}^{(ij)} = D_{ij} + \\log \\Big( \\sum_{(i,k)\\in\\mathcal{N}} \\exp(\\epsilon - D_{ik}) + \\sum_{(j,l)\\in\\mathcal{N}} \\exp(\\epsilon - D_{jl}) \\Big)\n$$\nIn the paper, they also proposed to enhance the quality of negative samples in each batch by actively incorporating difficult negative samples given a few random positive pairs.\nN-pair Loss\n#\nMulti-Class N-pair loss\n(\nSohn 2016\n) generalizes triplet loss to include comparison with multiple negative samples.\nGiven a $(N + 1)$-tuplet of training samples, $\\{ \\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-_1, \\dots, \\mathbf{x}^-_{N-1} \\}$, including one positive and $N-1$ negative ones, N-pair loss is defined as:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{N-pair}(\\mathbf{x}, \\mathbf{x}^+, \\{\\mathbf{x}^-_i\\}^{N-1}_{i=1}) \n&= \\log\\big(1 + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i) - f(\\mathbf{x})^\\top f(\\mathbf{x}^+))\\big) \\\\\n&= -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+))}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)) + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i))}\n\\end{aligned}\n$$\nIf we only sample one negative sample per class, it is equivalent to the softmax loss for multi-class classification.\nNCE\n#\nNoise Contrastive Estimation\n, short for\nNCE\n, is a method for estimating parameters of a statistical model, proposed by\nGutmann & Hyvarinen\nin 2010. The idea is to run logistic regression to tell apart the target data from noise. Read more on how NCE is used for learning word embedding\nhere\n.\nLet $\\mathbf{x}$ be the target sample $\\sim P(\\mathbf{x} \\vert C=1; \\theta) = p_\\theta(\\mathbf{x})$ and $\\tilde{\\mathbf{x}}$ be the noise sample $\\sim  P(\\tilde{\\mathbf{x}} \\vert C=0) = q(\\tilde{\\mathbf{x}})$. Note that the logistic regression models the logit (i.e. log-odds) and in this case we would like to model the logit of a sample $u$ from the target data distribution instead of the noise distribution:\n$$\n\\ell_\\theta(\\mathbf{u}) = \\log \\frac{p_\\theta(\\mathbf{u})}{q(\\mathbf{u})} = \\log p_\\theta(\\mathbf{u}) - \\log q(\\mathbf{u})\n$$\nAfter converting logits into probabilities with sigmoid $\\sigma(.)$, we can apply cross entropy loss:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{NCE} &= - \\frac{1}{N} \\sum_{i=1}^N \\big[ \\log \\sigma (\\ell_\\theta(\\mathbf{x}_i)) + \\log (1 - \\sigma (\\ell_\\theta(\\tilde{\\mathbf{x}}_i))) \\big] \\\\\n\\text{ where }\\sigma(\\ell) &= \\frac{1}{1 + \\exp(-\\ell)} = \\frac{p_\\theta}{p_\\theta + q}\n\\end{aligned}\n$$\nHere I listed the original form of NCE loss which works with only one positive and one noise sample. In many follow-up works, contrastive loss incorporating multiple negative samples is also broadly referred to as NCE.\nInfoNCE\n#\nThe\nInfoNCE loss\nin CPC (\nContrastive Predictive Coding\n;\nvan den Oord, et al. 2018\n), inspired by\nNCE\n, uses categorical cross-entropy loss to identify the positive sample amongst a set of unrelated noise samples.\nGiven a context vector $\\mathbf{c}$, the positive sample should be drawn from the conditional distribution $p(\\mathbf{x} \\vert \\mathbf{c})$, while $N-1$ negative samples are drawn from the proposal distribution $p(\\mathbf{x})$, independent from the context $\\mathbf{c}$. For brevity, let us label all the samples as $X=\\{ \\mathbf{x}_i \\}^N_{i=1}$ among which only one of them $\\mathbf{x}_\\texttt{pos}$ is a positive sample. The probability of we detecting the positive sample correctly is:\n$$\np(C=\\texttt{pos} \\vert X, \\mathbf{c}) \n= \\frac{p(x_\\texttt{pos} \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq \\texttt{pos}} p(\\mathbf{x}_i)}{\\sum_{j=1}^N \\big[ p(\\mathbf{x}_j \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq j} p(\\mathbf{x}_i) \\big]}\n= \\frac{ \\frac{p(\\mathbf{x}_\\texttt{pos}\\vert c)}{p(\\mathbf{x}_\\texttt{pos})} }{ \\sum_{j=1}^N \\frac{p(\\mathbf{x}_j\\vert \\mathbf{c})}{p(\\mathbf{x}_j)} }\n= \\frac{f(\\mathbf{x}_\\texttt{pos}, \\mathbf{c})}{ \\sum_{j=1}^N f(\\mathbf{x}_j, \\mathbf{c}) }\n$$\nwhere the scoring function is $f(\\mathbf{x}, \\mathbf{c}) \\propto \\frac{p(\\mathbf{x}\\vert\\mathbf{c})}{p(\\mathbf{x})}$.\nThe InfoNCE loss optimizes the negative log probability of classifying the positive sample correctly:\n$$\n\\mathcal{L}_\\text{InfoNCE} = - \\mathbb{E} \\Big[\\log \\frac{f(\\mathbf{x}, \\mathbf{c})}{\\sum_{\\mathbf{x}' \\in X} f(\\mathbf{x}', \\mathbf{c})} \\Big]\n$$\nThe fact that $f(x, c)$ estimates the density ratio $\\frac{p(x\\vert c)}{p(x)}$ has a connection with mutual information optimization. To maximize the the mutual information between input $x$ and context vector $c$, we have:\n$$\nI(\\mathbf{x}; \\mathbf{c}) = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c}) \\log\\frac{p(\\mathbf{x}, \\mathbf{c})}{p(\\mathbf{x})p(\\mathbf{c})} = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c})\\log\\color{blue}{\\frac{p(\\mathbf{x}|\\mathbf{c})}{p(\\mathbf{x})}}\n$$\nwhere the logarithmic term in\nblue\nis estimated by $f$.\nFor sequence prediction tasks, rather than modeling the future observations $p_k(\\mathbf{x}_{t+k} \\vert \\mathbf{c}_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $\\mathbf{x}_{t+k}$ and $\\mathbf{c}_t$:\n$$\nf_k(\\mathbf{x}_{t+k}, \\mathbf{c}_t) = \\exp(\\mathbf{z}_{t+k}^\\top \\mathbf{W}_k \\mathbf{c}_t) \\propto \\frac{p(\\mathbf{x}_{t+k}\\vert\\mathbf{c}_t)}{p(\\mathbf{x}_{t+k})}\n$$\nwhere $\\mathbf{z}_{t+k}$ is the encoded input and $\\mathbf{W}_k$ is a trainable weight matrix.\nSoft-Nearest Neighbors Loss\n#\nSoft-Nearest Neighbors Loss\n(\nSalakhutdinov & Hinton 2007\n,\nFrosst et al. 2019\n) extends it to include multiple positive samples.\nGiven a batch of samples, $\\{\\mathbf{x}_i, y_i)\\}^B_{i=1}$ where $y_i$ is the class label of $\\mathbf{x}_i$ and a function $f(.,.)$ for measuring similarity between two inputs, the soft nearest neighbor loss at temperature $\\tau$ is defined as:\n$$\n\\mathcal{L}_\\text{snn} = -\\frac{1}{B}\\sum_{i=1}^B \\log \\frac{\\sum_{i\\neq j, y_i = y_j, j=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_j) / \\tau)}{\\sum_{i\\neq k, k=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_k) /\\tau)}\n$$\nThe temperature $\\tau$ is used for tuning how concentrated the features are in the representation space. For example, when at low temperature, the loss is dominated by the small distances and widely separated representations cannot contribute much and become irrelevant.\nCommon Setup\n#\nWe can loosen the definition of “classes” and “labels” in soft nearest-neighbor loss to create positive and negative sample pairs out of unsupervised data by, for example, applying data augmentation to create noise versions of original samples.\nMost recent studies follow the following definition of contrastive learning objective to incorporate multiple positive and negative samples. According to the setup in (\nWang & Isola 2020\n), let $p_\\texttt{data}(.)$ be the data distribution over $\\mathbb{R}^n$ and $p_\\texttt{pos}(., .)$ be the distribution of positive pairs over $\\mathbb{R}^{n \\times n}$. These two distributions should satisfy:\nSymmetry: $\\forall \\mathbf{x}, \\mathbf{x}^+, p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) = p_\\texttt{pos}(\\mathbf{x}^+, \\mathbf{x})$\nMatching marginal: $\\forall \\mathbf{x}, \\int p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) d\\mathbf{x}^+ = p_\\texttt{data}(\\mathbf{x})$\nTo learn an encoder $f(\\mathbf{x})$ to learn a\nL2-normalized feature vector\n, the contrastive learning objective is:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{contrastive} \n&= \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} } \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau)}{ \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau) + \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)} \\Big] & \\\\\n&\\approx \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} }\\Big[ - f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau + \\log\\big(\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big) \\Big] & \\scriptstyle{\\text{; Assuming infinite negatives}} \\\\\n&= -\\frac{1}{\\tau}\\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}}f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + \\mathbb{E}_{ \\mathbf{x} \\sim p_\\texttt{data}} \\Big[ \\log \\mathbb{E}_{\\mathbf{x}^- \\sim p_\\texttt{data}} \\big[ \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big] \\Big] &\n\\end{aligned}\n$$\nKey Ingredients\n#\nHeavy Data Augmentation\n#\nGiven a training sample, data augmentation techniques are needed for creating noise versions of itself to feed into the loss as positive samples. Proper data augmentation setup is critical for learning good and generalizable embedding features. It introduces the non-essential variations into examples without modifying semantic meanings and thus encourages the model to learn the essential part of the representation. For example, experiments in\nSimCLR\nshowed that the composition of random cropping and random color distortion is crucial for good performance on learning visual representation of images.\nLarge Batch Size\n#\nUsing a large batch size during training is another key ingredient in the success of many contrastive learning methods (e.g.\nSimCLR\n,\nCLIP\n), especially when it relies on in-batch negatives. Only when the batch size is big enough, the loss function can cover a diverse enough collection of negative samples, challenging enough for the model to learn meaningful representation to distinguish different examples.\nHard Negative Mining\n#\nHard negative samples should have different labels from the anchor sample, but have embedding features very close to the anchor embedding. With access to ground truth labels in supervised datasets, it is easy to identify task-specific hard negatives. For example when learning sentence embedding, we can treat sentence pairs labelled as “contradiction” in NLI datasets as hard negative pairs (e.g.\nSimCSE\n, or use top incorrect candidates returned by BM25 with most keywords matched as hard negative samples (\nDPR\n;\nKarpukhin et al., 2020\n).\nHowever, it becomes tricky to do hard negative mining when we want to remain unsupervised. Increasing training batch size or\nmemory bank\nsize implicitly introduces more hard negative samples, but it leads to a heavy burden of large memory usage as a side effect.\nChuang et al. (2020)\nstudied the sampling bias in contrastive learning and proposed debiased loss. In the unsupervised setting, since we do not know the ground truth labels, we may accidentally sample false negative samples. Sampling bias can lead to significant performance drop.\nSampling bias which refers to false negative samples in contrastive learning can lead to a big performance drop. (Image source:\nChuang et al., 2020\n)\nLet us assume the probability of anchor class $c$ is uniform $\\rho(c)=\\eta^+$ and the probability of observing a different class is $\\eta^- = 1-\\eta^+$.\nThe probability of observing a positive example for $\\mathbf{x}$ is $p^+_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}=\\mathbf{h}_x)$;\nThe probability of getting a negative sample for $\\mathbf{x}$ is $p^-_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}\\neq\\mathbf{h}_x)$.\nWhen we are sampling $\\mathbf{x}^-$ , we cannot access the true $p^-_x(\\mathbf{x}^-)$ and thus $\\mathbf{x}^-$ may be sampled from the (undesired) anchor class $c$ with probability $\\eta^+$. The actual sampling data distribution becomes:\n$$\np(\\mathbf{x}') = \\eta^+ p^+_x(\\mathbf{x}') + \\eta^- p_x^-(\\mathbf{x}')\n$$\nThus we can use $p^-_x(\\mathbf{x}’) = (p(\\mathbf{x}’) - \\eta^+ p^+_x(\\mathbf{x}’))/\\eta^-$ for sampling $\\mathbf{x}^-$ to debias the loss. With $N$ samples $\\{\\mathbf{u}_i\\}^N_{i=1}$ from $p$ and $M$ samples $\\{ \\mathbf{v}_i \\}_{i=1}^M$ from $p^+_x$ , we can estimate the expectation of the second term $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ in the denominator of contrastive learning loss:\n$$\ng(\\mathbf{x}, \\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M) = \\max\\Big\\{ \\frac{1}{\\eta^-}\\Big( \\frac{1}{N}\\sum_{i=1}^N \\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}_i)) - \\frac{\\eta^+}{M}\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}_i)) \\Big), \\exp(-1/\\tau) \\Big\\}\n$$\nwhere $\\tau$ is the temperature and $\\exp(-1/\\tau)$ is the theoretical lower bound of $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$.\nThe final debiased contrastive loss looks like:\n$$\n\\mathcal{L}^{N,M}_\\text{debias}(f) = \\mathbb{E}_{\\mathbf{x},\\{\\mathbf{u}_i\\}^N_{i=1}\\sim p;\\;\\mathbf{x}^+, \\{\\mathbf{v}_i\\}_{i=1}^M\\sim p^+} \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + N g(x,\\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M)} \\Big]\n$$\nt-SNE visualization of learned representation with debiased contrastive learning. (Image source:\nChuang et al., 2020\n)\nFollowing the above annotation,\nRobinson et al. (2021)\nmodified the sampling probabilities to target at hard negatives by up-weighting the probability $p^-_x(x’)$ to be proportional to its similarity to the anchor sample. The new sampling probability $q_\\beta(x^-)$ is:\n$$\nq_\\beta(\\mathbf{x}^-) \\propto \\exp(\\beta f(\\mathbf{x})^\\top f(\\mathbf{x}^-)) \\cdot p(\\mathbf{x}^-)\n$$\nwhere $\\beta$ is a hyperparameter to tune.\nWe can estimate the second term in the denominator $\\mathbb{E}_{\\mathbf{x}^- \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ using importance sampling where both the partition functions $Z_\\beta, Z^+_\\beta$ can be estimated empirically.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\mathbf{u} \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] &= \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{q_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] = \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{1}{Z_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{u}))] \\\\\n\\mathbb{E}_{\\mathbf{v} \\sim q^+_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] &= \\mathbb{E}_{\\mathbf{v} \\sim p^+} [\\frac{q^+_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] = \\mathbb{E}_{\\mathbf{v} \\sim p} [\\frac{1}{Z^+_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{v}))]\n\\end{aligned}\n$$\nPseudo code for computing NCE loss, debiased contrastive loss, and hard negative sample objective when setting $M=1$. (Image source:\nRobinson et al., 2021\n)\nVision: Image Embedding\n#\nImage Augmentations\n#\nMost approaches for contrastive representation learning in the vision domain rely on creating a noise version of a sample by applying a sequence of data augmentation techniques. The augmentation should significantly change its visual appearance but keep the semantic meaning unchanged.\nBasic Image Augmentation\n#\nThere are many ways to modify an image while retaining its semantic meaning. We can use any one of the following augmentation or a composition of multiple operations.\nRandom cropping and then resize back to the original size.\nRandom color distortions\nRandom Gaussian blur\nRandom color jittering\nRandom horizontal flip\nRandom grayscale conversion\nMulti-crop augmentation: Use two standard resolution crops and sample a set of additional low resolution crops that cover only small parts of the image. Using low resolution crops reduces the compute cost. (\nSwAV\n)\nAnd many more …\nAugmentation Strategies\n#\nMany frameworks are designed for learning good data augmentation strategies (i.e. a composition of multiple transforms). Here are a few common ones.\nAutoAugment\n(\nCubuk, et al. 2018\n): Inspired by\nNAS\n, AutoAugment frames the problem of learning best data augmentation operations (i.e. shearing, rotation, invert, etc.) for image classification as an RL problem and looks for the combination that leads to the highest accuracy on the evaluation set.\nRandAugment (\nCubuk et al., 2019\n): RandAugment greatly reduces the search space of AutoAugment by controlling the magnitudes of different transformation operations with a single magnitude parameter.\nPBA (Population based augmentation;\nHo et al., 2019\n): PBA combined PBT (\nJaderberg et al, 2017\n) with AutoAugment, using the evolutionary algorithm to train a population of children models in parallel to evolve the best augmentation strategies.\nUDA (Unsupervised Data Augmentation;\nXie et al., 2019\n): Among a set of possible augmentation strategies, UDA selects those to minimize the KL divergence between the predicted distribution over an unlabelled example and its unlabelled augmented version.\nImage Mixture\n#\nImage mixture methods can construct new training examples from existing data points.\nMixup (\nZhang et al., 2018\n): It runs global-level mixture by creating a weighted pixel-wise combination of two existing images $I_1$ and $I_2$: $I_\\text{mixup} \\gets \\alpha I_1 + (1-\\alpha) I_2$ and $\\alpha \\in [0, 1]$.\nCutmix (\nYun et al., 2019\n): Cutmix does region-level mixture by generating a new example by combining a local region of one image with the rest of the other image. $I_\\text{cutmix} \\gets \\mathbf{M}_b \\odot I_1 + (1-\\mathbf{M}_b) \\odot I_2$, where $\\mathbf{M}_b \\in \\{0, 1\\}^I$ is a binary mask and $\\odot$ is element-wise multiplication. It is equivalent to filling the cutout (\nDeVries & Taylor 2017\n) region with the same region from another image.\nMoCHi (“Mixing of Contrastive Hard Negatives”;\nKalantidis et al. 2020\n): Given a query $\\mathbf{q}$, MoCHi maintains a queue of $K$ negative features $Q=\\{\\mathbf{n}_1, \\dots, \\mathbf{n}_K \\}$ and sorts these negative features by similarity to the query, $\\mathbf{q}^\\top \\mathbf{n}$, in descending order. The first $N$ items in the queue are considered as the hardest negatives, $Q^N$. Then synthetic hard examples can be generated by $\\mathbf{h} = \\tilde{\\mathbf{h}} / |\\tilde{\\mathbf{h}}|$ where $\\tilde{\\mathbf{h}} = \\alpha\\mathbf{n}_i + (1-\\alpha) \\mathbf{n}_j$ and $\\alpha \\in (0, 1)$. Even harder examples can be created by mixing with the query feature, $\\mathbf{h}’ = \\tilde{\\mathbf{h}’} / |\\tilde{\\mathbf{h}’}|_2$ where $\\tilde{\\mathbf{h}’} = \\beta\\mathbf{q} + (1-\\beta) \\mathbf{n}_j$ and $\\beta \\in (0, 0.5)$.\nParallel Augmentation\n#\nThis category of approaches produce two noise versions of one anchor image and aim to learn representation such that these two augmented samples share the same embedding.\nSimCLR\n#\nSimCLR\n(\nChen et al, 2020\n) proposed a simple framework for contrastive learning of visual representations. It learns representations for visual inputs by maximizing agreement between differently augmented views of the same sample via a contrastive loss in the latent space.\nA simple framework for contrastive learning of visual representations. (Image source:\nChen et al, 2020\n)\nRandomly sample a minibatch of $N$ samples and each sample is applied with two different data augmentation operations, resulting in $2N$ augmented samples in total.\n$$\n\\tilde{\\mathbf{x}}_i = t(\\mathbf{x}),\\quad\\tilde{\\mathbf{x}}_j = t'(\\mathbf{x}),\\quad t, t' \\sim \\mathcal{T}\n$$\nwhere two separate data augmentation operators, $t$ and $t’$, are sampled from the same family of augmentations $\\mathcal{T}$. Data augmentation includes random crop, resize with random flip, color distortions, and Gaussian blur.\nGiven one positive pair, other $2(N-1)$ data points are treated as negative samples. The representation is produced by a base encoder $f(.)$:\n$$\n\\mathbf{h}_i = f(\\tilde{\\mathbf{x}}_i),\\quad \\mathbf{h}_j = f(\\tilde{\\mathbf{x}}_j)\n$$\nThe contrastive learning loss is defined using cosine similarity $\\text{sim}(.,.)$. Note that the loss operates on an extra projection layer of the representation $g(.)$ rather than on the representation space directly. But only the representation $\\mathbf{h}$ is used for downstream tasks.\n$$\n\\begin{aligned}\n\\mathbf{z}_i &= g(\\mathbf{h}_i),\\quad\n\\mathbf{z}_j = g(\\mathbf{h}_j) \\\\\n\\mathcal{L}_\\text{SimCLR}^{(i,j)} &= - \\log\\frac{\\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_j) / \\tau)}{\\sum_{k=1}^{2N} \\mathbb{1}_{[k \\neq i]} \\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_k) / \\tau)}\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{[k \\neq i]}$ is an indicator function: 1 if $k\\neq i$ 0 otherwise.\nSimCLR needs a large batch size to incorporate enough negative samples to achieve good performance.\nThe algorithm for SimCLR. (Image source:\nChen et al, 2020\n).\nBarlow Twins\n#\nBarlow Twins\n(\nZbontar et al. 2021\n) feeds two distorted versions of samples into the same network to extract features and learns to make the\ncross-correlation matrix\nbetween these two groups of output features close to the identity. The goal is to keep the representation vectors of different distorted versions of one sample similar, while minimizing the redundancy between these vectors.\nIllustration of Barlow Twins learning pipeline. (Image source:\nZbontar et al. 2021\n).\nLet $\\mathcal{C}$ be a cross-correlation matrix computed between outputs from two identical networks along the batch dimension. $\\mathcal{C}$ is a square matrix with the size same as the feature network’s output dimensionality. Each entry in the matrix $\\mathcal{C}_{ij}$ is the cosine similarity between network output vector dimension at index $i, j$ and batch index $b$, $\\mathbf{z}_{b,i}^A$ and $\\mathbf{z}_{b,j}^B$, with a value between -1 (i.e. perfect anti-correlation) and 1 (i.e. perfect correlation).\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{BT} &= \\underbrace{\\sum_i (1-\\mathcal{C}_{ii})^2}_\\text{invariance term} + \\lambda \\underbrace{\\sum_i\\sum_{i\\neq j} \\mathcal{C}_{ij}^2}_\\text{redundancy reduction term} \\\\ \\text{where } \\mathcal{C}_{ij} &= \\frac{\\sum_b \\mathbf{z}^A_{b,i} \\mathbf{z}^B_{b,j}}{\\sqrt{\\sum_b (\\mathbf{z}^A_{b,i})^2}\\sqrt{\\sum_b (\\mathbf{z}^B_{b,j})^2}}\n\\end{aligned}\n$$\nBarlow Twins is competitive with SOTA methods for self-supervised learning. It naturally avoids trivial constants (i.e. collapsed representations), and is robust to different training batch sizes.\nAlgorithm of Barlow Twins in Pytorch style pseudo code. (Image source:\nZbontar et al. 2021\n).\nBYOL\n#\nDifferent from the above approaches, interestingly,\nBYOL\n(Bootstrap Your Own Latent;\nGrill, et al 2020\n) claims to achieve a new state-of-the-art results\nwithout using negative samples\n. It relies on two neural networks, referred to as\nonline\nand\ntarget\nnetworks that interact and learn from each other. The target network (parameterized by $\\xi$) has the same architecture as the online one (parameterized by $\\theta$), but with polyak averaged weights, $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe goal is to learn a presentation $y$ that can be used in downstream tasks. The online network parameterized by $\\theta$ contains:\nAn encoder $f_\\theta$;\nA projector $g_\\theta$;\nA predictor $q_\\theta$.\nThe target network has the same network architecture, but with different parameter $\\xi$, updated by polyak averaging $\\theta$: $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe model architecture of BYOL. After training, we only care about $f\\_\\theta$ for producing representation, $y=f\\_\\theta(x)$, and everything else is discarded. $\\text{sg}$ means stop gradient. (Image source:\nGrill, et al 2020\n)\nGiven an image $\\mathbf{x}$, the BYOL loss is constructed as follows:\nCreate two augmented views: $\\mathbf{v}=t(\\mathbf{x}); \\mathbf{v}’=t’(\\mathbf{x})$ with augmentations sampled $t \\sim \\mathcal{T}, t’ \\sim \\mathcal{T}’$;\nThen they are encoded into representations, $\\mathbf{y}_\\theta=f_\\theta(\\mathbf{v}), \\mathbf{y}’=f_\\xi(\\mathbf{v}’)$;\nThen they are projected into latent variables, $\\mathbf{z}_\\theta=g_\\theta(\\mathbf{y}_\\theta), \\mathbf{z}’=g_\\xi(\\mathbf{y}’)$;\nThe online network outputs a prediction $q_\\theta(\\mathbf{z}_\\theta)$;\nBoth $q_\\theta(\\mathbf{z}_\\theta)$ and $\\mathbf{z}’$ are L2-normalized, giving us $\\bar{q}_\\theta(\\mathbf{z}_\\theta) = q_\\theta(\\mathbf{z}_\\theta) / | q_\\theta(\\mathbf{z}_\\theta) |$ and $\\bar{\\mathbf{z}’} = \\mathbf{z}’ / |\\mathbf{z}’|$;\nThe loss $\\mathcal{L}^\\text{BYOL}_\\theta$ is MSE between L2-normalized prediction $\\bar{q}_\\theta(\\mathbf{z})$ and $\\bar{\\mathbf{z}’}$;\nThe other symmetric loss $\\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ can be generated by switching $\\mathbf{v}’$ and $\\mathbf{v}$; that is, feeding $\\mathbf{v}’$ to online network and $\\mathbf{v}$ to target network.\nThe final loss is $\\mathcal{L}^\\text{BYOL}_\\theta + \\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ and only  parameters $\\theta$ are optimized.\nUnlike most popular contrastive learning based approaches, BYOL does not use negative pairs. Most bootstrapping approaches rely on pseudo-labels or cluster indices, but BYOL directly boostrapps the latent representation.\nIt is quite interesting and surprising that\nwithout\nnegative samples, BYOL still works well. Later I ran into this\npost\nby Abe Fetterman & Josh Albrecht, they highlighted two surprising findings while they were trying to reproduce BYOL:\nBYOL generally performs no better than random when\nbatch normalization is removed\n.\nThe presence of batch normalization implicitly causes a form of contrastive learning.\nThey believe that using negative samples is important for avoiding model collapse (i.e. what if you use all-zeros representation for every data point?). Batch normalization injects dependency on negative samples\ninexplicitly\nbecause no matter how similar a batch of inputs are, the values are re-distributed (spread out $\\sim \\mathcal{N}(0, 1$) and therefore batch normalization prevents model collapse. Strongly recommend you to read the\nfull article\nif you are working in this area.\nMemory Bank\n#\nComputing embeddings for a large number of negative samples in every batch is extremely expensive. One common approach is to store the representation in memory to trade off data staleness for cheaper compute.\nInstance Discrimination with Memoy Bank\n#\nInstance contrastive learning\n(\nWu et al, 2018\n) pushes the class-wise supervision to the extreme by considering each instance as\na distinct class of its own\n. It implies that the number of “classes” will be the same as the number of samples in the training dataset. Hence, it is unfeasible to train a softmax layer with these many heads, but instead it can be approximated by\nNCE\n.\nThe training pipeline of instance-level contrastive learning. The learned embedding is L2-normalized. (Image source:\nWu et al, 2018\n)\nLet $\\mathbf{v} = f_\\theta(x)$ be an embedding function to learn and the vector is normalized to have $|\\mathbf{v}|=1$. A non-parametric classifier predicts the probability of a sample $\\mathbf{v}$ belonging to class $i$ with a temperature parameter $\\tau$:\n$$\nP(C=i\\vert \\mathbf{v}) = \\frac{\\exp(\\mathbf{v}_i^\\top \\mathbf{v} / \\tau)}{\\sum_{j=1}^n \\exp(\\mathbf{v}_j^\\top \\mathbf{v} / \\tau)}\n$$\nInstead of computing the representations for all the samples every time, they implement an\nMemory Bank\nfor storing sample representation in the database from past iterations. Let $V=\\{ \\mathbf{v}_i \\}$ be the memory bank and $\\mathbf{f}_i = f_\\theta(\\mathbf{x}_i)$ be the feature generated by forwarding the network. We can use the representation from the memory bank $\\mathbf{v}_i$ instead of the feature forwarded from the network $\\mathbf{f}_i$ when comparing pairwise similarity.\nThe denominator theoretically requires access to the representations of all the samples, but that is too expensive in practice. Instead we can estimate it via Monte Carlo approximation using a random subset of $M$ indices $\\{j_k\\}_{k=1}^M$.\n$$\nP(i\\vert \\mathbf{v}) \n= \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\sum_{j=1}^N \\exp(\\mathbf{v}_j^\\top \\mathbf{f}_i / \\tau)}\n\\simeq \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\frac{N}{M} \\sum_{k=1}^M \\exp(\\mathbf{v}_{j_k}^\\top \\mathbf{f}_i / \\tau)}\n$$\nBecause there is only one instance per class, the training is unstable and fluctuates a lot. To improve the training smoothness, they introduced an extra term for positive samples in the loss function based on the\nproximal optimization method\n. The final NCE loss objective looks like:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{instance} &= - \\mathbb{E}_{P_d}\\big[\\log h(i, \\mathbf{v}^{(t-1)}_i) - \\lambda \\|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i\\|^2_2\\big] - M\\mathbb{E}_{P_n}\\big[\\log(1 - h(i, \\mathbf{v}'^{(t-1)})\\big] \\\\\nh(i, \\mathbf{v}) &= \\frac{P(i\\vert\\mathbf{v})}{P(i\\vert\\mathbf{v}) + MP_n(i)} \\text{ where the noise distribution is uniform }P_n = 1/N\n\\end{aligned}\n$$\nwhere $\\{ \\mathbf{v}^{(t-1)} \\}$ are embeddings stored in the memory bank from the previous iteration. The difference between iterations $|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i|^2_2$ will gradually vanish as the learned embedding converges.\nMoCo & MoCo-V2\n#\nMomentum Contrast\n(\nMoCo\n;\nHe et al, 2019\n) provides a framework of unsupervised learning visual representation as a\ndynamic dictionary look-up\n. The dictionary is structured as a large FIFO queue of encoded representations of data samples.\nGiven a query sample $\\mathbf{x}_q$, we get a query representation through an encoder $\\mathbf{q} = f_q(\\mathbf{x}_q)$. A list of key representations $\\{\\mathbf{k}_1, \\mathbf{k}_2, \\dots \\}$ in the dictionary are encoded by a momentum encoder $\\mathbf{k}_i = f_k (\\mathbf{x}^k_i)$. Let’s assume among them there is a single\npositive\nkey $\\mathbf{k}^+$ in the dictionary that matches $\\mathbf{q}$. In the paper, they create $\\mathbf{k}^+$ using a noise copy of $\\mathbf{x}_q$ with different\naugmentation\n. Then the\nInfoNCE\ncontrastive loss with temperature $\\tau$ is used over one positive and $N-1$ negative samples:\n$$\n\\mathcal{L}_\\text{MoCo} = - \\log \\frac{\\exp(\\mathbf{q} \\cdot \\mathbf{k}^+ / \\tau)}{\\sum_{i=1}^N \\exp(\\mathbf{q} \\cdot \\mathbf{k}_i / \\tau)}\n$$\nCompared to the\nmemory bank\n, a queue-based dictionary in MoCo enables us to reuse representations of immediately preceding mini-batches of data.\nThe MoCo dictionary is not differentiable as a queue, so we cannot rely on back-propagation to update the key encoder $f_k$. One naive way might be to use the same encoder for both $f_q$ and $f_k$. Differently, MoCo proposed to use a momentum-based update with a momentum coefficient $m \\in [0, 1)$. Say, the parameters of $f_q$ and $f_k$ are labeled as $\\theta_q$ and $\\theta_k$, respectively.\n$$\n\\theta_k \\leftarrow m \\theta_k + (1-m) \\theta_q\n$$\nIllustration of how Momentum Contrast (MoCo) learns visual representations. (Image source:\nHe et al, 2019\n)\nThe advantage of MoCo compared to\nSimCLR\nis that MoCo decouples the batch size from the number of negatives, but SimCLR requires a large batch size in order to have enough negative samples and suffers performance drops when their batch size is reduced.\nTwo designs in SimCLR, namely, (1) an MLP projection head and (2) stronger data augmentation, are proved to be very efficient.\nMoCo V2\n(\nChen et al, 2020\n) combined these two designs, achieving even better transfer performance with no dependency on a very large batch size.\nCURL\n#\nCURL\n(\nSrinivas, et al. 2020\n) applies the above ideas in\nReinforcement Learning\n. It learns a visual representation for RL tasks by matching embeddings of two data-augmented versions, $o_q$ and $o_k$, of the raw observation $o$ via contrastive loss. CURL primarily relies on random crop data augmentation. The key encoder is implemented as a momentum encoder with weights as EMA of the query encoder weights, same as in\nMoCo\n.\nOne significant difference between RL and supervised visual tasks is that RL depends on\ntemporal consistency\nbetween consecutive frames. Therefore, CURL applies augmentation consistently on each stack of frames to retain information about the temporal structure of the observation.\nThe architecture of CURL. (Image source:\nSrinivas, et al. 2020\n)\nFeature Clustering\n#\nDeepCluster\n#\nDeepCluster\n(\nCaron et al. 2018\n) iteratively clusters features via k-means and uses cluster assignments as pseudo labels to provide supervised signals.\nIllustration of DeepCluster method which iteratively clusters deep features and uses the cluster assignments as pseudo-labels. (Image source:\nCaron et al. 2018\n)\nIn each iteration, DeepCluster clusters data points using the prior representation and then produces the new cluster assignments as the classification targets for the new representation. However this iterative process is prone to trivial solutions. While avoiding the use of negative pairs, it requires a costly clustering phase and specific precautions to avoid collapsing to trivial solutions.\nSwAV\n#\nSwAV\n(\nSwapping Assignments between multiple Views\n;\nCaron et al. 2020\n) is an online contrastive learning algorithm. It computes a code from an augmented version of the image and tries to predict this code using another augmented version of the same image.\nComparison of SwAV and [contrastive instance learning](#instance-discrimination-with-memoy-bank). (Image source:\nCaron et al. 2020\n)\nGiven features of images with two different augmentations, $\\mathbf{z}_t$ and $\\mathbf{z}_s$, SwAV computes corresponding codes $\\mathbf{q}_t$ and $\\mathbf{q}_s$ and the loss quantifies the fit by swapping two codes using $\\ell(.)$ to measure the fit between a feature and a code.\n$$\n\\mathcal{L}_\\text{SwAV}(\\mathbf{z}_t, \\mathbf{z}_s) = \\ell(\\mathbf{z}_t, \\mathbf{q}_s) + \\ell(\\mathbf{z}_s, \\mathbf{q}_t)\n$$\nThe swapped fit prediction depends on the cross entropy between the predicted code and a set of $K$ trainable prototype vectors $\\mathbf{C} = \\{\\mathbf{c}_1, \\dots, \\mathbf{c}_K\\}$. The prototype vector matrix is shared across different batches and represents\nanchor clusters\nthat each instance should be clustered to.\n$$\n\\ell(\\mathbf{z}_t, \\mathbf{q}_s) = - \\sum_k \\mathbf{q}^{(k)}_s\\log\\mathbf{p}^{(k)}_t \\text{ where } \\mathbf{p}^{(k)}_t = \\frac{\\exp(\\mathbf{z}_t^\\top\\mathbf{c}_k  / \\tau)}{\\sum_{k'}\\exp(\\mathbf{z}_t^\\top \\mathbf{c}_{k'} / \\tau)}\n$$\nIn a mini-batch containing $B$ feature vectors $\\mathbf{Z} = [\\mathbf{z}_1, \\dots, \\mathbf{z}_B]$, the mapping matrix between features and prototype vectors is defined as $\\mathbf{Q} = [\\mathbf{q}_1, \\dots, \\mathbf{q}_B] \\in \\mathbb{R}_+^{K\\times B}$. We would like to maximize the similarity between the features and the prototypes:\n$$\n\\begin{aligned}\n\\max_{\\mathbf{Q}\\in\\mathcal{Q}} &\\text{Tr}(\\mathbf{Q}^\\top \\mathbf{C}^\\top \\mathbf{Z}) + \\varepsilon \\mathcal{H}(\\mathbf{Q}) \\\\\n\\text{where }\\mathcal{Q} &= \\big\\{ \\mathbf{Q} \\in \\mathbb{R}_{+}^{K \\times B} \\mid \\mathbf{Q}\\mathbf{1}_B = \\frac{1}{K}\\mathbf{1}_K, \\mathbf{Q}^\\top\\mathbf{1}_K = \\frac{1}{B}\\mathbf{1}_B \\big\\}\n\\end{aligned}\n$$\nwhere $\\mathcal{H}$ is the entropy, $\\mathcal{H}(\\mathbf{Q}) = - \\sum_{ij} \\mathbf{Q}_{ij} \\log \\mathbf{Q}_{ij}$, controlling the smoothness of the code. The coefficient $\\epsilon$ should not be too large; otherwise, all the samples will be assigned uniformly to all the clusters. The candidate set of solutions for $\\mathbf{Q}$ requires every mapping matrix to have each row sum up to $1/K$ and each column to sum up to $1/B$, enforcing that each prototype gets selected at least $B/K$ times on average.\nSwAV relies on the iterative Sinkhorn-Knopp algorithm (\nCuturi 2013\n) to find the solution for $\\mathbf{Q}$.\nWorking with Supervised Datasets\n#\nCLIP\n#\nCLIP\n(\nContrastive Language-Image Pre-training\n;\nRadford et al. 2021\n) jointly trains a text encoder and an image feature extractor over the pretraining task that predicts which caption goes with which image.\nIllustration of CLIP contrastive pre-training over text-image pairs. (Image source:\nRadford et al. 2021\n)\nGiven a batch of $N$ (image, text) pairs, CLIP computes the dense cosine similarity matrix between all $N\\times N$ possible (image, text) candidates within this batch. The text and image encoders are jointly trained to maximize the similarity between $N$ correct pairs of (image, text) associations while minimizing the similarity for $N(N-1)$ incorrect pairs via a symmetric cross entropy loss over the dense matrix.\nSee the numy-like pseudo code for CLIP in\nCLIP algorithm in Numpy style pseudo code. (Image source:\nRadford et al. 2021\n)\nCompared to other methods above for learning good visual representation, what makes CLIP really special is\n“the appreciation of using natural language as a training signal”\n. It does demand access to supervised dataset in which we know which text matches which image. It is trained on 400 million (text, image) pairs, collected from the Internet. The query list contains all the words occurring at least 100 times in the English version of Wikipedia. Interestingly, they found that Transformer-based language models are 3x slower than a bag-of-words (BoW) text encoder at zero-shot ImageNet classification. Using contrastive objective instead of trying to predict the exact words associated with images (i.e. a method commonly adopted by image caption prediction tasks) can further improve the data efficiency another 4x.\nUsing bag-of-words text encoding and contrastive training objectives can bring in multiple folds of data efficiency improvement. (Image source:\nRadford et al. 2021\n)\nCLIP produces good visual representation that can non-trivially transfer to many CV benchmark datasets, achieving results competitive with supervised baseline. Among tested transfer tasks, CLIP struggles with very fine-grained classification, as well as abstract or systematic tasks such as counting the number of objects. The transfer performance of CLIP models is smoothly correlated with the amount of model compute.\nSupervised Contrastive Learning\n#\nThere are several known issues with cross entropy loss, such as the lack of robustness to noisy labels and the possibility of poor margins. Existing improvement for cross entropy loss involves the curation of better training data, such as label smoothing and data augmentation.\nSupervised Contrastive Loss\n(\nKhosla et al. 2021\n) aims to leverage label information more effectively than cross entropy, imposing that normalized embeddings from the same class are closer together than embeddings from different classes.\nSupervised vs self-supervised contrastive losses. Supervised contrastive learning considers different samples from the same class as positive examples, in addition to augmented versions. (Image source:\nKhosla et al. 2021\n)\nGiven a set of randomly sampled $n$ (image, label) pairs, $\\{\\mathbf{x}_i, y_i\\}_{i=1}^n$, $2n$ training pairs can be created by applying two random augmentations of every sample, $\\{\\tilde{\\mathbf{x}}_i, \\tilde{y}_i\\}_{i=1}^{2n}$.\nSupervised contrastive loss $\\mathcal{L}_\\text{supcon}$ utilizes multiple positive and negative samples, very similar to\nsoft nearest-neighbor loss\n:\n$$\n\\mathcal{L}_\\text{supcon} = - \\sum_{i=1}^{2n} \\frac{1}{2 \\vert N_i \\vert - 1} \\sum_{j \\in N(y_i), j \\neq i} \\log \\frac{\\exp(\\mathbf{z}_i \\cdot \\mathbf{z}_j / \\tau)}{\\sum_{k \\in I, k \\neq i}\\exp({\\mathbf{z}_i \\cdot \\mathbf{z}_k / \\tau})}\n$$\nwhere $\\mathbf{z}_k=P(E(\\tilde{\\mathbf{x}_k}))$, in which $E(.)$ is an encoder network (augmented image mapped to vector) $P(.)$ is a projection network (one vector mapped to another). $N_i= \\{j \\in I: \\tilde{y}_j = \\tilde{y}_i \\}$ contains a set of indices of samples with label $y_i$. Including more positive samples into the set $N_i$ leads to improved results.\nAccording to their experiments, supervised contrastive loss:\ndoes outperform the base cross entropy, but only by a small amount.\noutperforms the cross entropy on robustness benchmark (ImageNet-C, which applies common naturally occuring perturbations such as noise, blur and contrast changes to the ImageNet dataset).\nis less sensitive to hyperparameter changes.\nLanguage: Sentence Embedding\n#\nIn this section, we focus on how to learn sentence embedding.\nText Augmentation\n#\nMost contrastive methods in vision applications depend on creating an augmented version of each image. However, it is more challenging to construct text augmentation which does not alter the semantics of a sentence.  In this section we look into three approaches for augmenting text sequences, including lexical edits, back-translation and applying cutoff or dropout.\nLexical Edits\n#\nEDA\n(\nEasy Data Augmentation\n;\nWei & Zou 2019\n) defines a set of simple but powerful operations for text augmentation. Given a sentence, EDA randomly chooses and applies one of four simple operations:\nSynonym replacement (SR): Replace $n$ random non-stop words with their synonyms.\nRandom insertion (RI): Place a random synonym of a randomly selected non-stop word in the sentence at a random position.\nRandom swap (RS): Randomly swap two words and repeat $n$ times.\nRandom deletion (RD): Randomly delete each word in the sentence with probability $p$.\nwhere $p=\\alpha$ and $n=\\alpha \\times \\text{sentence_length}$, with the intuition that longer sentences can absorb more noise while maintaining the original label. The hyperparameter $\\alpha$ roughly indicates the percent of words in one sentence that may be changed by one augmentation.\nEDA is shown to improve the classification accuracy on several classification benchmark datasets compared to baseline without EDA. The performance lift is more significant on a smaller training set. All the four operations in EDA help improve the classification accuracy, but get to optimal at different $\\alpha$’s.\nEDA leads to performance improvement on several classification benchmarks. (Image source:\nWei & Zou 2019\n)\nIn\nContextual Augmentation\n(\nSosuke Kobayashi, 2018\n), new substitutes for word $w_i$ at position $i$ can be smoothly sampled from a given probability distribution, $p(.\\mid S\\setminus\\{w_i\\})$, which is predicted by a bidirectional LM like BERT.\nBack-translation\n#\nCERT\n(\nContrastive self-supervised Encoder Representations from Transformers\n;\nFang et al. (2020)\n;\ncode\n) generates augmented sentences via\nback-translation\n. Various translation models for different languages can be employed for creating different versions of augmentations. Once we have a noise version of text samples, many contrastive learning frameworks introduced above, such as\nMoCo\n, can be used to learn sentence embedding.\nDropout and Cutoff\n#\nShen et al. (2020)\nproposed to apply\nCutoff\nto text augmentation, inspired by\ncross-view training\n. They proposed three cutoff augmentation strategies:\nToken cutoff\nremoves the information of a few selected tokens. To make sure there is no data leakage, corresponding tokens in the input, positional and other relevant embedding matrices should all be zeroed out.,\nFeature cutoff\nremoves a few feature columns.\nSpan cutoff\nremoves a continuous chunk of texts.\nSchematic illustration of token, feature and span cutoff augmentation strategies. (Image source:\nShen et al. 2020\n)\nMultiple augmented versions of one sample can be created. When training,\nShen et al. (2020)\napplied an additional KL-divergence term to measure the consensus between predictions from different augmented samples.\nSimCSE\n(\nGao et al. 2021\n;\ncode\n) learns from unsupervised data by predicting a sentence from itself with only\ndropout\nnoise. In other words, they treat dropout as data augmentation for text sequences. A sample is simply fed into the encoder twice with different dropout masks and these two versions are the positive pair where the other in-batch samples are considered as negative pairs. It feels quite similar to the cutoff augmentation, but dropout is more flexible with less well-defined semantic meaning of what content can be masked off.\nSimCSE creates augmented samples by applying different dropout masks. The supervised version leverages NLI datasets to predict positive (entailment) or negative (contradiction) given a pair of sentences. (Image source:\nGao et al. 2021\n)\nThey ran experiments on 7 STS (Semantic Text Similarity) datasets and computed cosine similarity between sentence embeddings.  They also tried out an optional MLM auxiliary objective loss to help avoid catastrophic forgetting of token-level knowledge. This aux loss was found to help improve performance on transfer tasks, but a consistent drop on the main STS tasks.\nExperiment numbers on a collection of STS benchmarks with SimCES. (Image source:\nGao et al. 2021\n)\nSupervision from NLI\n#\nThe pre-trained BERT sentence embedding without any fine-tuning has been found to have poor performance for semantic similarity tasks. Instead of using the raw embeddings directly, we need to refine the embedding with further fine-tuning.\nNatural Language Inference (NLI)\ntasks are the main data sources to provide supervised signals for learning sentence embedding; such as\nSNLI\n,\nMNLI\n, and\nQQP\n.\nSentence-BERT\n#\nSBERT (Sentence-BERT)\n(\nReimers & Gurevych, 2019\n) relies on siamese and triplet network architectures to learn sentence embeddings such that the sentence similarity can be estimated by cosine similarity between pairs of embeddings. Note that learning SBERT depends on supervised data, as it is fine-tuned on several NLI datasets.\nThey experimented with a few different prediction heads on top of BERT model:\nSoftmax classification objective: The classification head of the siamese network is built on the concatenation of two embeddings $f(\\mathbf{x}), f(\\mathbf{x}’)$ and $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$. The predicted output is $\\hat{y}=\\text{softmax}(\\mathbf{W}_t [f(\\mathbf{x}); f(\\mathbf{x}’); \\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert])$. They showed that the most important component is the element-wise difference $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$.\nRegression objective: This is the regression loss on $\\cos(f(\\mathbf{x}), f(\\mathbf{x}’))$, in which the pooling strategy has a big impact. In the experiments, they observed that\nmax\nperforms much worse than\nmean\nand\nCLS\n-token.\nTriplet objective: $\\max(0, |f(\\mathbf{x}) - f(\\mathbf{x}^+)|- |f(\\mathbf{x}) - f(\\mathbf{x}^-)| + \\epsilon)$, where $\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-$ are embeddings of the anchor, positive and negative sentences.\nIn the experiments, which objective function works the best depends on the datasets, so there is no universal winner.\nIllustration of Sentence-BERT training framework with softmax classification head and regression head. (Image source:\nReimers & Gurevych, 2019\n)\nThe\nSentEval\nlibrary (\nConneau and Kiela, 2018\n) is commonly used for evaluating the quality of learned sentence embedding. SBERT outperformed other baselines at that time (Aug 2019) on 5 out of 7 tasks.\nThe performance of Sentence-BERT on the SentEval benchmark. (Image source:\nReimers & Gurevych, 2019\n)\nBERT-flow\n#\nThe embedding representation space is deemed\nisotropic\nif embeddings are uniformly distributed on each dimension; otherwise, it is\nanisotropic\n.\nLi et al, (2020)\nshowed that a pre-trained BERT learns a non-smooth\nanisotropic\nsemantic space of sentence embeddings and thus leads to poor performance for text similarity tasks without fine-tuning. Empirically, they observed two issues with BERT sentence embedding:\nWord frequency biases the embedding space. High-frequency words are close to the origin, but low-frequency ones are far away from the origin.\nLow-frequency words scatter sparsely. The embeddings of low-frequency words tend to be farther to their $k$-NN neighbors, while the embeddings of high-frequency words concentrate more densely.\nBERT-flow\n(\nLi et al, 2020\n;\ncode\n) was proposed to transform the embedding to a smooth and isotropic Gaussian distribution via\nnormalizing flows\n.\nIllustration of the flow-based calibration over the original sentence embedding space in BERT-flow. (Image source:\nLi et al, 2020\n)\nLet $\\mathcal{U}$ be the observed BERT sentence embedding space and $\\mathcal{Z}$ be the desired latent space which is a standard Gaussian. Thus, $p_\\mathcal{Z}$ is a Gaussian density function and $f_\\phi: \\mathcal{Z}\\to\\mathcal{U}$ is an invertible transformation:\n$$\n\\mathbf{z}\\sim p_\\mathcal{Z}(\\mathbf{z}) \\quad \n\\mathbf{u}=f_\\phi(\\mathbf{z}) \\quad\n\\mathbf{z}=f^{-1}_\\phi(\\mathbf{u}) \n$$\nA flow-based generative model learns the invertible mapping function by maximizing the likelihood of $\\mathcal{U}$’s marginal:\n$$\n\\max_\\phi\\mathbb{E}_{\\mathbf{u}=\\text{BERT}(s), s\\sim\\mathcal{D}} \\Big[ \\log p_\\mathcal{Z}(f^{-1}_\\phi(\\mathbf{u})) + \\log\\big\\vert\\det\\frac{\\partial f^{-1}_\\phi(\\mathbf{u})}{\\partial\\mathbf{u}}\\big\\vert \\Big]\n$$\nwhere $s$ is a sentence sampled from the text corpus $\\mathcal{D}$. Only the flow parameters $\\phi$ are optimized while parameters in the pretrained BERT stay unchanged.\nBERT-flow was shown to improve the performance on most STS tasks either with or without supervision from NLI datasets. Because learning normalizing flows for calibration does not require labels, it can utilize the entire dataset including validation and test sets.\nWhitening Operation\n#\nSu et al. (2021)\napplied\nwhitening\noperation to improve the\nisotropy\nof the learned representation and also to reduce the dimensionality of sentence embedding.\nThey transform the mean value of the sentence vectors to 0 and the covariance matrix to the identity matrix. Given a set of samples $\\{\\mathbf{x}_i\\}_{i=1}^N$, let $\\tilde{\\mathbf{x}}_i$ and $\\tilde{\\Sigma}$ be the transformed samples and corresponding covariance matrix:\n$$\n\\begin{aligned}\n\\mu &= \\frac{1}{N}\\sum_{i=1}^N \\mathbf{x}_i \\quad \\Sigma = \\frac{1}{N}\\sum_{i=1}^N (\\mathbf{x}_i - \\mu)^\\top (\\mathbf{x}_i - \\mu) \\\\\n\\tilde{\\mathbf{x}}_i &= (\\mathbf{x}_i - \\mu)W \\quad \\tilde{\\Sigma} = W^\\top\\Sigma W = I \\text{ thus } \\Sigma = (W^{-1})^\\top W^{-1}\n\\end{aligned}\n$$\nIf we get\nSVD\ndecomposition of $\\Sigma = U\\Lambda U^\\top$, we will have $W^{-1}=\\sqrt{\\Lambda} U^\\top$ and  $W=U\\sqrt{\\Lambda^{-1}}$. Note that within SVD, $U$ is an orthogonal matrix with column vectors as eigenvectors and $\\Lambda$ is a diagonal matrix with all positive elements as sorted eigenvalues.\nA dimensionality reduction strategy can be applied by only taking the first $k$ columns of $W$, named\nWhitening\n-$k$.\nPseudo code of the whitening-$k$ operation. (Image source:\nSu et al. 2021\n)\nWhitening operations were shown to outperform BERT-flow and achieve SOTA with 256 sentence dimensionality on many STS benchmarks, either with or without NLI supervision.\nUnsupervised Sentence Embedding Learning\n#\nContext Prediction\n#\nQuick-Thought (QT) vectors\n(\nLogeswaran & Lee, 2018\n) formulate sentence representation learning as a\nclassification\nproblem: Given a sentence and its context, a classifier distinguishes context sentences from other contrastive sentences based on their vector representations (\n“cloze test”\n). Such a formulation removes the softmax output layer which causes training slowdown.\nIllustration of how Quick-Thought sentence embedding vectors are learned. (Image source:\nLogeswaran & Lee, 2018\n)\nLet $f(.)$ and $g(.)$ be two functions that encode a sentence $s$ into a fixed-length vector. Let $C(s)$ be the set of sentences in the context of $s$ and $S(s)$ be the set of candidate sentences including only one sentence $s_c \\in C(s)$ and many other non-context negative sentences. Quick Thoughts model learns to optimize the probability of predicting the only true context sentence $s_c \\in S(s)$. It is essentially NCE loss when considering the sentence $(s, s_c)$ as the positive pairs while other pairs $(s, s’)$ where $s’ \\in S(s), s’\\neq s_c$ as negatives.\n$$\n\\mathcal{L}_\\text{QT} \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)} \\log p(s_c \\vert s, S(s)) \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)}\\frac{\\exp(f(s)^\\top g(s_c))}{\\sum_{s'\\in S(s)} \\exp(f(s)^\\top g(s'))}\n$$\nMutual Information Maximization\n#\nIS-BERT (Info-Sentence BERT)\n(\nZhang et al. 2020\n;\ncode\n) adopts a self-supervised learning objective based on\nmutual information maximization\nto learn good sentence embeddings in the\nunsupervised\nmanners.\nIllustration of Info-Sentence BERT. (Image source:\nZhang et al. 2020\n)\nIS-BERT works as follows:\nUse BERT to encode an input sentence $s$ to a token embedding of length $l$, $\\mathbf{h}_{1:l}$.\nThen apply 1-D conv net with different kernel sizes (e.g. 1, 3, 5) to process the token embedding sequence to capture the n-gram local contextual dependencies: $\\mathbf{c}_i = \\text{ReLU}(\\mathbf{w} \\cdot \\mathbf{h}_{i:i+k-1} + \\mathbf{b})$. The output sequences are padded to stay the same sizes of the inputs.\nThe final local representation of the $i$-th token $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$ is the concatenation of representations of different kernel sizes.\nThe global sentence representation $\\mathcal{E}_\\theta(\\mathbf{x})$ is computed by applying a mean-over-time pooling layer on the token representations $\\mathcal{F}_\\theta(\\mathbf{x}) = \\{\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}) \\in \\mathbb{R}^d\\}_{i=1}^l$.\nSince the mutual information estimation is generally intractable for continuous and high-dimensional random variables, IS-BERT relies on the Jensen-Shannon estimator (\nNowozin et al., 2016\n,\nHjelm et al., 2019\n) to maximize the mutual information between $\\mathcal{E}_\\theta(\\mathbf{x})$ and $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$.\n$$\nI^\\text{JSD}_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})) = \\mathbb{E}_{\\mathbf{x}\\sim P} [-\\text{sp}(-T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})))] \\\\ - \\mathbb{E}_{\\mathbf{x}\\sim P, \\mathbf{x}' \\sim\\tilde{P}} [\\text{sp}(T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}'); \\mathcal{E}_\\theta(\\mathbf{x})))]\n$$\nwhere $T_\\omega: \\mathcal{F}\\times\\mathcal{E} \\to \\mathbb{R}$ is a learnable network with parameters $\\omega$, generating discriminator scores. The negative sample $\\mathbf{x}’$ is sampled from the distribution $\\tilde{P}=P$. And $\\text{sp}(x)=\\log(1+e^x)$ is the softplus activation function.\nThe unsupervised numbers on SentEval with IS-BERT outperforms most of the unsupervised baselines (Sep 2020), but unsurprisingly weaker than supervised runs. When using labelled NLI datasets, IS-BERT produces results comparable with SBERT (See Fig. 25 & 30).\nThe performance of IS-BERT on the SentEval benchmark. (Image source:\nZhang et al. 2020\n)\nCitation\n#\nCited as:\nWeng, Lilian. (May 2021). Contrastive representation learning. Lil’Log. https://lilianweng.github.io/posts/2021-05-31-contrastive/.\nOr\n@article{weng2021contrastive,\n  title   = \"Contrastive Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"May\",\n  url     = \"https://lilianweng.github.io/posts/2021-05-31-contrastive/\"\n}\nReferences\n#\n[1] Sumit Chopra, Raia Hadsell and Yann LeCun.\n“Learning a similarity metric discriminatively, with application to face verification.”\nCVPR 2005.\n[2] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering.”\nCVPR 2015.\n[3] Hyun Oh Song et al.\n“Deep Metric Learning via Lifted Structured Feature Embedding.”\nCVPR 2016. [\ncode\n]\n[4] Ruslan Salakhutdinov and Geoff Hinton.\n“Learning a Nonlinear Embedding by Preserving Class Neighbourhood Structure”\nAISTATS 2007.\n[5] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nAISTATS 2010.\n[6] Kihyuk Sohn et al.\n“Improved Deep Metric Learning with Multi-class N-pair Loss Objective”\nNIPS 2016.\n[7] Nicholas Frosst, Nicolas Papernot and Geoffrey Hinton.\n“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”\nICML 2019\n[8] Tongzhou Wang and Phillip Isola.\n“Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere.”\nICML 2020. [\ncode\n]\n[9] Zhirong Wu et al.\n“Unsupervised feature learning via non-parametric instance-level discrimination.”\nCVPR 2018.\n[10] Ekin D. Cubuk et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv preprint arXiv:1805.09501 (2018).\n[11] Daniel Ho et al.\n“Population Based Augmentation: Efficient Learning of Augmentation Policy Schedules.”\nICML 2019.\n[12] Ekin D. Cubuk & Barret Zoph et al.\n“RandAugment: Practical automated data augmentation with a reduced search space.”\narXiv preprint arXiv:1909.13719 (2019).\n[13] Hongyi Zhang et al.\n“mixup: Beyond Empirical Risk Minimization.”\nICLR 2017.\n[14] Sangdoo Yun et al.\n“CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features.”\nICCV 2019.\n[15] Yannis Kalantidis et al.\n“Mixing of Contrastive Hard Negatives”\nNeuriPS 2020.\n[16] Ashish Jaiswal et al.\n“A Survey on Contrastive Self-Supervised Learning.”\narXiv preprint arXiv:2011.00362 (2021)\n[17] Jure Zbontar et al.\n“Barlow Twins: Self-Supervised Learning via Redundancy Reduction.”\narXiv preprint arXiv:2103.03230 (2021) [\ncode\n]\n[18] Alec Radford, et al.\n“Learning Transferable Visual Models From Natural Language Supervision”\narXiv preprint arXiv:2103.00020 (2021)\n[19] Mathilde Caron et al.\n“Unsupervised Learning of Visual Features by Contrasting Cluster Assignments (SwAV).”\nNeuriPS 2020.\n[20] Mathilde Caron et al.\n“Deep Clustering for Unsupervised Learning of Visual Features.”\nECCV 2018.\n[21] Prannay Khosla et al.\n“Supervised Contrastive Learning.”\nNeurIPS 2020.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748 (2018).\n[23] Jason Wei and Kai Zou.\n“EDA: Easy data augmentation techniques for boosting performance on text classification tasks.”\nEMNLP-IJCNLP 2019.\n[24] Sosuke Kobayashi.\n“Contextual Augmentation: Data Augmentation by Words with Paradigmatic Relations.”\nNAACL 2018\n[25] Hongchao Fang et al.\n“CERT: Contrastive self-supervised learning for language understanding.”\narXiv preprint arXiv:2005.12766 (2020).\n[26] Dinghan Shen et al.\n“A Simple but Tough-to-Beat Data Augmentation Approach for Natural Language Understanding and Generation.”\narXiv preprint arXiv:2009.13818 (2020) [\ncode\n]\n[27] Tianyu Gao et al.\n“SimCSE: Simple Contrastive Learning of Sentence Embeddings.”\narXiv preprint arXiv:2104.08821 (2020). [\ncode\n]\n[28] Nils Reimers and Iryna Gurevych.\n“Sentence-BERT: Sentence embeddings using Siamese BERT-networks.”\nEMNLP 2019.\n[29] Jianlin Su et al.\n“Whitening sentence representations for better semantics and faster retrieval.”\narXiv preprint arXiv:2103.15316 (2021). [\ncode\n]\n[30] Yan Zhang et al.\n“An unsupervised sentence embedding method by mutual information maximization.”\nEMNLP 2020. [\ncode\n]\n[31] Bohan Li et al.\n“On the sentence embeddings from pre-trained language models.”\nEMNLP 2020.\n[32] Lajanugen Logeswaran and Honglak Lee.\n“An efficient framework for learning sentence representations.”\nICLR 2018.\n[33] Joshua Robinson, et al.\n“Contrastive Learning with Hard Negative Samples.”\nICLR 2021.\n[34] Ching-Yao Chuang et al.\n“Debiased Contrastive Learning.”\nNeuriPS 2020.",
            "metadata": {
              "title": "Contrastive Representation Learning | Lil'Log",
              "description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "keywords": "representation-learning, long-read, language-model, unsupervised-learning, data-augmentation",
              "author": "Lilian Weng",
              "og:title": "Contrastive Representation Learning",
              "og:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
              "twitter:card": "summary",
              "twitter:title": "Contrastive Representation Learning",
              "twitter:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "article:section": "posts",
              "article:published_time": "2021-05-31T00:00:00+00:00",
              "article:modified_time": "2021-05-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c8f3f2a59bb8/code/body-000.txt",
                "chars": 259,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "bytes": 82669,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-c8feb8e3831d6f407222.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "bytes": 238558,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-864616500d13b290a57d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "bytes": 618000,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4d1eafbd2698e4b13414.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "bytes": 447800,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2202dbf059680ff25f64.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "bytes": 331316,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-56fdc531021fd8fc266d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "bytes": 92328,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-a3de29261702db65276c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "bytes": 292083,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fbb7be242e78cf4064e.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "bytes": 165448,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7c6e570b2b4acaea53ee.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "bytes": 410905,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0dc7fb2e267a076918a0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "bytes": 160971,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-64c06b583b29bc8d849d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "bytes": 575598,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-24abca83dac665bdfd2c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "bytes": 191327,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-68a57a589ced1a8dcbeb.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "bytes": 458778,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dec760a7d6d875b1e5f6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "bytes": 413067,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-3b05f2c9b09900dd678c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "bytes": 307781,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fe78703c0d6dd59901b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "bytes": 395407,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-bcffab9e56e403b12eb6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "bytes": 378369,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-14fc3bb2a028bd633430.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "bytes": 269518,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1cdb06387d4aabe19e7f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "bytes": 1172082,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dc3294612801cee60ee0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "bytes": 299081,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4ecf4ae1a9c6c75e0b98.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "bytes": 102477,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2f938fd27f3112a7668b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "bytes": 302804,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-476b14449fa38214486c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "bytes": 459618,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-d417f179aa932198443f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "bytes": 248555,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-61290a159906f77df170.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "bytes": 263986,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-25636cdf26fe48bc32a6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "bytes": 127994,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1f6149bb39a134da1e75.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "bytes": 167429,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-75a0434d42ea9e13e5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "bytes": 235880,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0873d959165b59705852.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "bytes": 403903,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7fc9d0b8fcf86efd800b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "bytes": 237372,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4a85aecfe0dc34b27289.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "label": "Chopra et al. 2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "Schroff et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06452",
                "label": "Song et al. 2015",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2016/hash/6b180037abbebea991d8b1232f8a8ca9-Abstract.html",
                "label": "Sohn 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a.html",
                "label": "Gutmann & Hyvarinen",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v2/salakhutdinov07a.html",
                "label": "Salakhutdinov & Hinton 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01889",
                "label": "Frosst et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.10242",
                "label": "Wang & Isola 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "DPR",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.00224",
                "label": "Chuang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.04592",
                "label": "Robinson et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "AutoAugment",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.05393",
                "label": "Ho et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.04899",
                "label": "Yun et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.04552",
                "label": "DeVries & Taylor 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.01028",
                "label": "Kalantidis et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.03230",
                "label": "Zbontar et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "Grill, et al 2020",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "Wu et al, 2018",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/~boyd/papers/prox_algs.html",
                "label": "proximal optimization method",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "He et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "Srinivas, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.05520",
                "label": "Caron et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09882",
                "label": "Caron et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1306.0895",
                "label": "Cuturi 2013",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.00020",
                "label": "Radford et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.11362",
                "label": "Khosla et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11196",
                "label": "Wei & Zou 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.06201",
                "label": "Sosuke Kobayashi, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.12766",
                "label": "Fang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/UCSD-AI4H/CERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.13818",
                "label": "Shen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "cross-view training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08821",
                "label": "Gao et al. 2021",
                "type": "a"
              },
              {
                "href": "https://github.com/princeton-nlp/SimCSE",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://cims.nyu.edu/~sbowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/c/quora-question-pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.10084",
                "label": "Reimers & Gurevych, 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/SentEval",
                "label": "SentEval",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.05449",
                "label": "Conneau and Kiela, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.05864",
                "label": "Li et al, (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/bohanli/BERT-flow",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.15316",
                "label": "Su et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Singular_value_decomposition",
                "label": "SVD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02893",
                "label": "Logeswaran & Lee, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.12061",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/yanzhangnlp/IS-BERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.00709",
                "label": "Nowozin et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.06670",
                "label": "Hjelm et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/rksltnl/Deep-Metric-Learning-CVPR16",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v97/frosst19a.html",
                "label": "“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”",
                "type": "a"
              },
              {
                "href": "https://ssnl.github.io/hypersphere/",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978",
                "label": "“Unsupervised feature learning via non-parametric instance-level discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.00362",
                "label": "“A Survey on Contrastive Self-Supervised Learning.”",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/barlowtwins",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/dinghanshen/cutoff",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/bojone/BERT-whitening",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:20Z",
            "source_url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "papers": [
              {
                "status": "ok",
                "url": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "bytes": 313804,
                "reused": false,
                "local_path": "papers/repair/84881b743b9447eb9afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": false,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06452",
                "bytes": 9011569,
                "reused": false,
                "local_path": "papers/repair/738c3f04b7e4d7dad3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": false,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01889",
                "bytes": 3823806,
                "reused": false,
                "local_path": "papers/repair/66ab4748bfca0238682e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.10242",
                "bytes": 4185717,
                "reused": false,
                "local_path": "papers/repair/8a0c585591f7f1918d90.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.00224",
                "bytes": 5343399,
                "reused": false,
                "local_path": "papers/repair/7dcaf70ed91e5defcf23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.04592",
                "bytes": 2199907,
                "reused": false,
                "local_path": "papers/repair/3f84b66b72f5c381c05a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": true,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.05393",
                "bytes": 873126,
                "reused": true,
                "local_path": "papers/repair/4634b6280b855d570ac8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": true,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": true,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.04899",
                "bytes": 1682836,
                "reused": true,
                "local_path": "papers/repair/fec62c4fe8efdeebd877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.04552",
                "bytes": 741919,
                "reused": true,
                "local_path": "papers/repair/c3d681ed19bf88f43a98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.01028",
                "bytes": 970998,
                "reused": true,
                "local_path": "papers/repair/d4d3c2412459021d347a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": false,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.03230",
                "bytes": 2434163,
                "reused": false,
                "local_path": "papers/repair/7f141d9ed4155ccf53f5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": false,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": false,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": false,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": false,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.05520",
                "bytes": 8629266,
                "reused": false,
                "local_path": "papers/repair/0a5b97b834b6a105dd9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09882",
                "bytes": 702914,
                "reused": false,
                "local_path": "papers/repair/0838c337bef6ccd33d62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1306.0895",
                "bytes": 1004298,
                "reused": false,
                "local_path": "papers/repair/598da2f78a40c9c822ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.00020",
                "bytes": 6813639,
                "reused": true,
                "local_path": "papers/repair/7db0b9244bb1fd42ae98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.11362",
                "bytes": 2197586,
                "reused": false,
                "local_path": "papers/repair/a64eec551d692894bad9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11196",
                "bytes": 365049,
                "reused": true,
                "local_path": "papers/repair/389e34d78a0045e6d861.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.06201",
                "bytes": 722323,
                "reused": true,
                "local_path": "papers/repair/aebd3f77254c72e012a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.12766",
                "bytes": 412104,
                "reused": false,
                "local_path": "papers/repair/bae8e6b74f13390eb0a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.13818",
                "bytes": 398629,
                "reused": true,
                "local_path": "papers/repair/40a2d9b786e78e3cf30e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08821",
                "bytes": 1672580,
                "reused": true,
                "local_path": "papers/repair/e7a40652bdd04cd4b25f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.10084",
                "bytes": 548961,
                "reused": true,
                "local_path": "papers/repair/20151599fbbbabacaa9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.05449",
                "bytes": 1257905,
                "reused": false,
                "local_path": "papers/repair/748bb3642ea0aef5571f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.05864",
                "bytes": 408978,
                "reused": false,
                "local_path": "papers/repair/3bfe284fc1ebd8a9d3a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.15316",
                "bytes": 659541,
                "reused": false,
                "local_path": "papers/repair/6e8262dafcfd96e9b679.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02893",
                "bytes": 232651,
                "reused": false,
                "local_path": "papers/repair/12ee892560b48ed47fb8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.12061",
                "bytes": 408861,
                "reused": false,
                "local_path": "papers/repair/5c6f2a504c1b0ff66969.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.00709",
                "bytes": 3615251,
                "reused": false,
                "local_path": "papers/repair/b555d3a1dac849208314.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.06670",
                "bytes": 4984410,
                "reused": false,
                "local_path": "papers/repair/ca0c4e18cba031b31bd0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/2408633e99d87285a643.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.00362",
                "bytes": 5998084,
                "reused": false,
                "local_path": "papers/repair/20fd1312b2e030a81069.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 62279,
            "expected_body_images": 30,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c8f3f2a59bb8/pages/source.html",
            "local_html": "attachments/c8f3f2a59bb8/pages/article.html",
            "body_base_path": "attachments/c8f3f2a59bb8/pages/",
            "body_markdown_path": "attachments/c8f3f2a59bb8/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
          "status": "partial",
          "article_id": "607baf97b999",
          "local_path": "series-follow/1602/repair/98f025266fe083b5aa56.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
              "bytes": 929637,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5e717a51b0a5329fa972.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
              "bytes": 268193,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bcfb5637b30440671005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
              "bytes": 183059,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7365015a0a10cc69acd8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
              "bytes": 473871,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9d994d94aa3f953655fe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
              "bytes": 244780,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4b7c5a8a25f1aef4e33a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
              "bytes": 269806,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7ad146452781a398f651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
              "bytes": 1588495,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2208e66f87d45609e14a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
              "bytes": 516917,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e495e282eb1d3f3e9144.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
              "bytes": 51037,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8a0f9752f056eb917bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
              "bytes": 272909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b96d2353529c40b14aef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
              "bytes": 100122,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e2ee524fbebc06b6e190.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
              "bytes": 227696,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5d14984c36bf66c73897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
              "bytes": 87898,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/08c8fd1e0c80108aa470.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
              "bytes": 415583,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c58896fcdd52fc06c2a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
              "bytes": 253294,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7970b3c999effb6f02b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
              "bytes": 88113,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/85fc2d78dbd4ba853f15.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
              "bytes": 282592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dd77dfe447995839038a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
              "bytes": 384564,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3be7c9763f11993ba7a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
              "bytes": 76634,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e529afcc9a2bd0fb2fae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
              "bytes": 180008,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8045a59ac9bcdcc697fc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
              "bytes": 258219,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c0273e122159d4c19386.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
              "bytes": 88004,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8bf9b1628b286eb863de.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
              "bytes": 138525,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/76b71f8459361bdc98c5.png"
            }
          ],
          "article": {
            "id": "607baf97b999",
            "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "bytes": 929637,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5e717a51b0a5329fa972.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "bytes": 268193,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-bcfb5637b30440671005.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "bytes": 183059,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7365015a0a10cc69acd8.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "bytes": 473871,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-9d994d94aa3f953655fe.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "bytes": 244780,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-4b7c5a8a25f1aef4e33a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "bytes": 269806,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7ad146452781a398f651.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "bytes": 1588495,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-2208e66f87d45609e14a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "bytes": 516917,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e495e282eb1d3f3e9144.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "bytes": 51037,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8a0f9752f056eb917bbf.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "bytes": 272909,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-b96d2353529c40b14aef.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "bytes": 100122,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e2ee524fbebc06b6e190.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "bytes": 227696,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5d14984c36bf66c73897.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "bytes": 87898,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-08c8fd1e0c80108aa470.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "bytes": 415583,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c58896fcdd52fc06c2a0.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "bytes": 253294,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7970b3c999effb6f02b6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "bytes": 88113,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-85fc2d78dbd4ba853f15.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "bytes": 282592,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-dd77dfe447995839038a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "bytes": 384564,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-3be7c9763f11993ba7a6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "bytes": 76634,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e529afcc9a2bd0fb2fae.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "bytes": 180008,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8045a59ac9bcdcc697fc.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "bytes": 258219,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c0273e122159d4c19386.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "bytes": 88004,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8bf9b1628b286eb863de.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "bytes": 138525,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-76b71f8459361bdc98c5.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "src": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/607baf97b999/videos/repair-l5einDQ-Ttc.mp4",
                "bytes": 19398754,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "139.221000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-02-14: add\nULMFiT\nand\nGPT-2\n.]\n[Updated on 2020-02-29: add\nALBERT\n.]\n[Updated on 2020-10-25: add\nRoBERTa\n.]\n[Updated on 2020-12-13: add\nT5\n.]\n[Updated on 2020-12-30: add\nGPT-3\n.]\n[Updated on 2021-11-13: add\nXLNet\n,\nBART\nand\nELECTRA\n; Also updated the\nSummary\nsection.]\nI guess they are Elmo & Bert? (Image source:\nhere\n)\nWe have seen amazing progress in NLP in 2018. Large-scale pre-trained language modes like\nOpenAI GPT\nand\nBERT\nhave achieved great performance on a variety of language tasks using generic model architectures. The idea is similar to how ImageNet classification pre-training helps many vision tasks (*). Even better than vision classification pre-training, this simple and powerful approach in NLP does not require labeled data for pre-training, allowing us to experiment with increased training scale, up to our very limit.\n(*) He et al. (2018)\nfound\nthat pre-training might not be necessary for image segmentation task.\nIn my previous NLP\npost on word embedding\n, the introduced embeddings are not context-specific — they are learned based on word concurrency but not sequential context. So in two sentences, “\nI am eating an apple\n” and “\nI have an Apple phone\n”, two “apple” words refer to very different things but they would still share the same word embedding vector.\nDespite this, early adoption of word embeddings in problem-solving is to use them as additional features for an existing task-specific model and in a way the improvement is bounded.\nIn this post, we will discuss how various approaches were proposed to make embeddings dependent on context, and to make them easier and cheaper to be applied to downstream tasks in general form.\nCoVe\n#\nCoVe\n(\nMcCann et al. 2017\n), short for\nContextual Word Vectors\n, is a type of word embeddings learned by an encoder in an\nattentional seq-to-seq\nmachine translation model.\nDifferent from traditional word embeddings introduced\nhere\n, CoVe word representations are functions of the entire input sentence.\nNMT Recap\n#\nHere the Neural Machine Translation (\nNMT\n) model is composed of a standard, two-layer, bidirectional LSTM encoder and an attentional two-layer unidirectional LSTM decoder. It is pre-trained on the English-German translation task. The encoder learns and optimizes the embedding vectors of English words in order to translate them to German. With the intuition that the encoder should capture high-level semantic and syntactic meanings before transforming words into another language, the encoder output is used to provide contextualized word embeddings for various downstream language tasks.\nThe NMT base model used in CoVe.\nA sequence of $n$ words in source language (English): $x = [x_1, \\dots, x_n]$.\nA sequence of $m$ words in target language (German): $y = [y_1, \\dots, y_m]$.\nThe\nGloVe\nvectors of source words: $\\text{GloVe}(x)$.\nRandomly initialized embedding vectors of target words: $z = [z_1, \\dots, z_m]$.\nThe biLSTM encoder outputs a sequence of hidden states: $h = [h_1, \\dots, h_n] = \\text{biLSTM}(\\text{GloVe}(x))$ and $h_t = [\\overrightarrow{h}_t; \\overleftarrow{h}_t]$ where the forward LSTM computes $\\overrightarrow{h}_t = \\text{LSTM}(x_t, \\overrightarrow{h}_{t-1})$ and the backward computation gives us $\\overleftarrow{h}_t = \\text{LSTM}(x_t, \\overleftarrow{h}_{t-1})$.\nThe attentional decoder outputs a distribution over words: $p(y_t \\mid H, y_1, \\dots, y_{t-1})$ where $H$ is a stack of hidden states $\\{h\\}$ along the time dimension:\n$$\n\\begin{aligned}\n\\text{decoder hidden state: } s_t &= \\text{LSTM}([z_{t-1}; \\tilde{h}_{t-1}], s_{t-1}) \\\\\n\\text{attention weights: } \\alpha_t &= \\text{softmax}(H(W_1 s_t + b_1)) \\\\\n\\text{context-adjusted hidden state: } \\tilde{h}_t &= \\tanh(W_2[H^\\top\\alpha_t;s_t] + b_2) \\\\\n\\text{decoder output: } p(y_t\\mid H, y_1, \\dots, y_{t-1}) &= \\text{softmax}(W_\\text{out} \\tilde{h}_t + b_\\text{out})\n\\end{aligned}\n$$\nUse CoVe in Downstream Tasks\n#\nThe hidden states of NMT encoder are defined as\ncontext vectors\nfor other language tasks:\n$$\n\\text{CoVe}(x) = \\text{biLSTM}(\\text{GloVe}(x))\n$$\nThe paper proposed to use the concatenation of GloVe and CoVe for question-answering and classification tasks. GloVe learns from the ratios of global word co-occurrences, so it has no sentence context, while CoVe is generated by processing text sequences is able to capture the contextual information.\n$$\nv = [\\text{GloVe}(x); \\text{CoVe}(x)]\n$$\nGiven a downstream task, we first generate the concatenation of GloVe + CoVe vectors of input words and then feed them into the task-specific models as additional features.\nThe CoVe embeddings are generated by an encoder trained for machine translation task. The encoder can be plugged into any downstream task-specific model. (Image source:\noriginal paper\n)\nSummary\n: The limitation of CoVe is obvious: (1) pre-training is bounded by available datasets on the supervised translation task; (2) the contribution of CoVe to the final performance is constrained by the task-specific model architecture.\nIn the following sections, we will see that ELMo overcomes issue (1) by unsupervised pre-training and OpenAI GPT & BERT further overcome both problems by unsupervised pre-training + using generative model architecture for different downstream tasks.\nELMo\n#\nELMo\n, short for\nEmbeddings from Language Model\n(\nPeters, et al, 2018\n) learns contextualized word representation by pre-training a language model in an\nunsupervised\nway.\nBidirectional Language Model\n#\nThe bidirectional Language Model (\nbiLM\n) is the foundation for ELMo. While the input is a sequence of $n$ tokens, $(x_1, \\dots, x_n)$, the language model learns to predict the probability of next token given the history.\nIn the forward pass, the history contains words before the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_1, \\dots, x_{i-1})\n$$\nIn the backward pass, the history contains words after the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_{i+1}, \\dots, x_n)\n$$\nThe predictions in both directions are modeled by multi-layer LSTMs with hidden states $\\overrightarrow{\\mathbf{h}}_{i,\\ell}$ and $\\overleftarrow{\\mathbf{h}}_{i,\\ell}$ for input token $x_i$ at the layer level $\\ell=1,\\dots,L$.\nThe final layer’s hidden state $\\mathbf{h}_{i,L} = [\\overrightarrow{\\mathbf{h}}_{i,L}; \\overleftarrow{\\mathbf{h}}_{i,L}]$ is used to output the probabilities over tokens after softmax normalization. They share the embedding layer and the softmax layer, parameterized by $\\Theta_e$ and $\\Theta_s$ respectively.\nThe biLSTM base model of ELMo. (Image source: recreated based on the figure in [\"Neural Networks, Types, and Functional Programming\"](http://colah.github.io/posts/2015-09-NN-Types-FP/) by Christopher Olah.)\nThe model is trained to minimize the negative log likelihood (= maximize the log likelihood for true words) in both directions:\n$$\n\\begin{aligned}\n\\mathcal{L} = - \\sum_{i=1}^n \\Big( \n\\log p(x_i \\mid x_1, \\dots, x_{i-1}; \\Theta_e, \\overrightarrow{\\Theta}_\\text{LSTM}, \\Theta_s) + \\\\\n\\log p(x_i \\mid x_{i+1}, \\dots, x_n; \\Theta_e, \\overleftarrow{\\Theta}_\\text{LSTM}, \\Theta_s) \\Big)\n\\end{aligned}\n$$\nELMo Representations\n#\nOn top of a $L$-layer biLM, ELMo stacks all the hidden states across layers together by learning a task-specific linear combination. The hidden state representation for the token $x_i$ contains $2L+1$ vectors:\n$$\nR_i = \\{ \\mathbf{h}_{i,\\ell} \\mid \\ell = 0, \\dots, L \\}\n$$\nwhere $\\mathbf{h}_{0, \\ell}$ is the embedding layer output and $\\mathbf{h}_{i, \\ell} = [\\overrightarrow{\\mathbf{h}}_{i,\\ell}; \\overleftarrow{\\mathbf{h}}_{i,\\ell}]$.\nThe weights, $\\mathbf{s}^\\text{task}$, in the linear combination are learned for each end task and normalized by softmax. The scaling factor $\\gamma^\\text{task}$ is used to correct the misalignment between the distribution of biLM hidden states and the distribution of task specific representations.\n$$\nv_i = f(R_i; \\Theta^\\text{task}) = \\gamma^\\text{task} \\sum_{\\ell=0}^L s^\\text{task}_i \\mathbf{h}_{i,\\ell}\n$$\nTo evaluate what kind of information is captured by hidden states across different layers, ELMo is applied on semantic-intensive and syntax-intensive tasks respectively using representations in different layers of biLM:\nSemantic task\n: The\nword sense disambiguation (WSD)\ntask emphasizes the meaning of a word given a context. The biLM top layer is better at this task than the first layer.\nSyntax task\n: The\npart-of-speech\n(POS) tagging\ntask aims to infer the grammatical role of a word in one sentence. A higher accuracy can be achieved by using the biLM first layer than the top layer.\nThe comparison study indicates that syntactic information is better represented at lower layers while semantic information is captured by higher layers. Because different layers tend to carry different type of information,\nstacking them together helps\n.\nUse ELMo in Downstream Tasks\n#\nSimilar to how\nCoVe\ncan help different downstream tasks, ELMo embedding vectors are included in the input or lower levels of task-specific models. Moreover, for some tasks (i.e.,\nSNLI\nand\nSQuAD\n, but not\nSRL\n), adding them into the output level helps too.\nThe improvements brought up by ELMo are largest for tasks with a small supervised dataset. With ELMo, we can also achieve similar performance with much less labeled data.\nSummary\n: The language model pre-training is unsupervised and theoretically the pre-training can be scaled up as much as possible since the unlabeled text corpora are abundant. However, it still has the dependency on task-customized models and thus the improvement is only incremental, while searching for a good model architecture for every task remains non-trivial.\nCross-View Training\n#\nIn ELMo the unsupervised pre-training and task-specific learning happen for two independent models in two separate training stages.\nCross-View Training\n(abbr.\nCVT\n;\nClark et al., 2018\n) combines them into one unified semi-supervised learning procedure where the representation of a biLSTM encoder is improved by both supervised learning with labeled data and unsupervised learning with unlabeled data on auxiliary tasks.\nModel Architecture\n#\nThe model consists of a two-layer bidirectional LSTM encoder and a primary prediction module. During training, the model is fed with labeled and unlabeled data batches alternatively.\nOn\nlabeled examples\n, all the model parameters are updated by standard supervised learning. The loss is the standard cross entropy.\nOn\nunlabeled examples\n, the primary prediction module still can produce a “soft” target, even though we cannot know exactly how accurate they are. In a couple of auxiliary tasks, the predictor only sees and processes a restricted view of the input, such as only using encoder hidden state representation in one direction. The auxiliary task outputs are expected to match the primary prediction target for a full view of input.\nIn this way, the encoder is forced to distill the knowledge of the full context into partial representation. At this stage, the biLSTM encoder is backpropagated but the primary prediction module is\nfixed\n. The loss is to minimize the distance between auxiliary and primary predictions.\nThe overview of semi-supervised language model cross-view training. (Image source:\noriginal paper\n)\nMulti-Task Learning\n#\nWhen training for multiple tasks simultaneously, CVT adds several extra primary prediction models for additional tasks. They all share the same sentence representation encoder.\nDuring supervised training, once one task is randomly selected, parameters in its corresponding predictor and the representation encoder are updated.\nWith unlabeled data samples, the encoder is optimized jointly across all the tasks by minimizing the differences between auxiliary outputs and primary prediction for every task.\nThe multi-task learning encourages better generality of representation and in the meantime produces a nice side-product: all-tasks-labeled examples from unlabeled data. They are precious data labels considering that cross-task labels are useful but fairly rare.\nUse CVT in Downstream Tasks\n#\nTheoretically the primary prediction module can take any form, generic or task-specific design. The examples presented in the CVT paper include both cases.\nIn sequential tagging tasks (classification for every token) like\nNER\nor\nPOS\ntagging, the predictor module contains two fully connected layers and a softmax layer on the output to produce a probability distribution over class labels.\nFor each token $\\mathbf{x}_i$, we take the corresponding hidden states in two layers, $\\mathbf{h}_1^{(i)}$ and $\\mathbf{h}_2^{(i)}$:\n$$\n\\begin{aligned}\np_\\theta(y_i \\mid \\mathbf{x}_i) \n&= \\text{NN}(\\mathbf{h}^{(i)}) \\\\\n&= \\text{NN}([\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) \\\\\n&= \\text{softmax} \\big( \\mathbf{W}\\cdot\\text{ReLU}(\\mathbf{W'}\\cdot[\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) + \\mathbf{b} \\big)\n\\end{aligned}\n$$\nThe auxiliary tasks are only fed with forward or backward LSTM state in the first layer. Because they only observe partial context, either on the left or right, they have to learn like a language model, trying to predict the next token given the context. The\nfwd\nand\nbwd\nauxiliary tasks only take one direction. The\nfuture\nand\npast\ntasks take one step further in forward and backward direction, respectively.\n$$\n\\begin{aligned}\np_\\theta^\\text{fwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{fwd}(\\overrightarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{bwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{bwd}(\\overleftarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{future}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{future}(\\overrightarrow{\\mathbf{h}}^{(i-1)}) \\\\\np_\\theta^\\text{past}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{past}(\\overleftarrow{\\mathbf{h}}^{(i+1)})\n\\end{aligned}\n$$\nThe sequential tagging task depends on four auxiliary prediction models, their inputs only involving hidden states in one direction: forward, backward, future and past. (Image source:\noriginal paper\n)\nNote that if the primary prediction module has dropout, the dropout layer works as usual when training with labeled data, but it is not applied when generating “soft” target for auxiliary tasks during training with unlabeled data.\nIn the machine translation task, the primary prediction module is replaced with a standard unidirectional LSTM decoder with attention. There are two auxiliary tasks: (1) apply dropout on the attention weight vector by randomly zeroing out some values; (2) predict the future word in the target sequence. The primary prediction for auxiliary tasks to match is the best predicted target sequence produced by running the fixed primary decoder on the input sequence with\nbeam search\n.\nULMFiT\n#\nThe idea of using generative pretrained LM + task-specific fine-tuning was first explored in ULMFiT (\nHoward & Ruder, 2018\n), directly motivated by the success of using ImageNet pre-training for computer vision tasks. The base model is\nAWD-LSTM\n.\nULMFiT follows three steps to achieve good transfer learning results on downstream language classification tasks:\nGeneral LM pre-training\n: on Wikipedia text.\nTarget task LM fine-tuning\n: ULMFiT proposed two training techniques for stabilizing the fine-tuning process. See below.\nDiscriminative fine-tuning\nis motivated by the fact that different layers of LM capture different types of information (see\ndiscussion\nabove). ULMFiT proposed to tune each layer with different learning rates, $\\{\\eta^1, \\dots, \\eta^\\ell, \\dots, \\eta^L\\}$, where $\\eta$ is the base learning rate for the first layer, $\\eta^\\ell$ is for the $\\ell$-th layer and there are $L$ layers in total.\nSlanted triangular learning rates (STLR)\nrefer to a special learning rate scheduling that first linearly increases the learning rate and then linearly decays it. The increase stage is short so that the model can converge to a parameter space suitable for the task fast, while the decay period is long allowing for better fine-tuning.\nTarget task classifier fine-tuning\n: The pretrained LM is augmented with two standard feed-forward layers and a softmax normalization at the end to predict a target label distribution.\nConcat pooling\nextracts max-polling and mean-pooling over the history of hidden states and concatenates them with the final hidden state.\nGradual unfreezing\nhelps to avoid catastrophic forgetting by gradually unfreezing the model layers starting from the last one. First the last layer is unfrozen and fine-tuned for one epoch. Then the next lower layer is unfrozen. This process is repeated until all the layers are tuned.\nThree training stages of ULMFiT. (Image source:\noriginal paper\n)\nGPT\n#\nFollowing the similar idea of ELMo, OpenAI\nGPT\n, short for\nGenerative Pre-training Transformer\n(\nRadford et al., 2018\n), expands the unsupervised language model to a much larger scale by training on a giant collection of free text corpora. Despite of the similarity, GPT has two major differences from ELMo.\nThe model architectures are different: ELMo uses a shallow concatenation of independently trained left-to-right and right-to-left multi-layer LSTMs, while GPT is a multi-layer transformer decoder.\nThe use of contextualized embeddings in downstream tasks are different: ELMo feeds embeddings into models customized for specific tasks as additional features, while GPT fine-tunes the same base model for all end tasks.\nTransformer Decoder as Language Model\n#\nCompared to the\noriginal transformer\narchitecture, the\ntransformer decoder\nmodel discards the encoder part, so there is only one single input sentence rather than two separate source and target sequences.\nThis model applies multiple transformer blocks over the embeddings of input sequences. Each block contains a masked\nmulti-headed self-attention\nlayer and a\npointwise feed-forward\nlayer. The final output produces a distribution over target tokens after softmax normalization.\nThe transformer decoder model architecture in OpenAI GPT.\nThe loss is the negative log-likelihood, same as\nELMo\n, but without backward computation. Let’s say, the context window of the size $k$ is located before the target word and the loss would look like:\n$$\n\\mathcal{L}_\\text{LM} = -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1})\n$$\nByte Pair Encoding\n#\nByte Pair Encoding\n(\nBPE\n) is used to encode the input sequences. BPE was originally proposed as a data compression algorithm in 1990s and then was adopted to solve the open-vocabulary issue in machine translation, as we can easily run into rare and unknown words when translating into a new language. Motivated by the intuition that rare and unknown words can often be decomposed into multiple subwords, BPE finds the best word segmentation by iteratively and greedily merging frequent pairs of characters.\nSupervised Fine-Tuning\n#\nThe most substantial upgrade that OpenAI GPT proposed is to get rid of the task-specific model and use the pre-trained language model directly!\nLet’s take classification as an example. Say, in the labeled dataset, each input has $n$ tokens, $\\mathbf{x} = (x_1, \\dots, x_n)$, and one label $y$. GPT first processes the input sequence $\\mathbf{x}$ through the pre-trained transformer decoder and the last layer output for the last token $x_n$ is $\\mathbf{h}_L^{(n)}$. Then with only one new trainable weight matrix $\\mathbf{W}_y$, it can predict a distribution over class labels.\n$$\nP(y\\mid x_1, \\dots, x_n) = \\text{softmax}(\\mathbf{h}_L^{(n)}\\mathbf{W}_y)\n$$\nThe loss is to minimize the negative log-likelihood for true labels. In addition, adding the LM loss as an auxiliary loss is found to be beneficial, because:\n(1) it helps accelerate convergence during training and\n(2) it is expected to improve the generalization of the supervised model.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{cls} &= \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log P(y\\mid x_1, \\dots, x_n) = \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log \\text{softmax}(\\mathbf{h}_L^{(n)}(\\mathbf{x})\\mathbf{W}_y) \\\\\n\\mathcal{L}_\\text{LM} &= -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1}) \\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\lambda \\mathcal{L}_\\text{LM}\n\\end{aligned}\n$$\nWith similar designs, no customized model structure is needed for other end tasks (see Fig. 7). If the task input contains multiple sentences, a special delimiter token (\n$\n) is added between each pair of sentences. The embedding for this delimiter token is a new parameter we need to learn, but it should be pretty minimal.\nFor the sentence similarity task, because the ordering does not matter, both orderings are included. For the multiple choice task, the context is paired with every answer candidate.\nTraining objects in slightly modified GPT transformer models for downstream tasks. (Image source:\noriginal paper\n)\nSummary\n: It is super neat and encouraging to see that such a general framework is capable to beat SOTA on most language tasks at that time (June 2018). At the first stage, generative pre-training of a language model can absorb as much free text as possible. Then at the second stage, the model is fine-tuned on specific tasks with a small labeled dataset and a minimal set of new parameters to learn.\nOne limitation of GPT is its uni-directional nature — the model is only trained to predict the future left-to-right context.\nBERT\n#\nBERT\n, short for\nBidirectional Encoder Representations from Transformers\n(\nDevlin, et al., 2019\n) is a direct descendant to\nGPT\n: train a large language model on free text and then fine-tune on specific tasks without customized network architectures.\nCompared to GPT, the largest difference and improvement of BERT is to make training\nbi-directional\n. The model learns to predict both context on the left and right. The paper according to the ablation study claimed that:\n“bidirectional nature of our model is the single most important new contribution”\nPre-training Tasks\n#\nThe model architecture of BERT is a multi-layer bidirectional Transformer encoder.\nRecap of Transformer Encoder model architecture. (Image source:\nTransformer paper\n)\nTo encourage the bi-directional prediction and sentence-level understanding, BERT is trained with two tasks instead of the basic language task (that is, to predict the next token given context).\n*\nTask 1: Mask language model (MLM)\nFrom\nWikipedia\n: “A cloze test (also cloze deletion test) is an exercise, test, or assessment consisting of a portion of language with certain items, words, or signs removed (cloze text), where the participant is asked to replace the missing language item. … The exercise was first described by W.L. Taylor in 1953.”\nIt is unsurprising to believe that a representation that learns the context around a word rather than just after the word is able to better capture its meaning, both syntactically and semantically. BERT encourages the model to do so by training on the\n“mask language model” task\n:\nRandomly mask 15% of tokens in each sequence. Because if we only replace masked tokens with a special placeholder\n[MASK]\n, the special token would never be encountered during fine-tuning. Hence, BERT employed several heuristic tricks:\n(a) with 80% probability, replace the chosen words with\n[MASK]\n;\n(b) with 10% probability, replace with a random word;\n(c) with 10% probability, keep it the same.\nThe model only predicts the missing words, but it has no information on which words have been replaced or which words should be predicted. The output size is only 15% of the input size.\nTask 2: Next sentence prediction\nMotivated by the fact that many downstream tasks involve the understanding of relationships between sentences (i.e.,\nQA\n,\nNLI\n), BERT added another auxiliary task on training a\nbinary classifier\nfor telling whether one sentence is the next sentence of the other:\nSample sentence pairs (A, B) so that:\n(a) 50% of the time, B follows A;\n(b) 50% of the time, B does not follow A.\nThe model processes both sentences and output a binary label indicating whether B is the next sentence of A.\nThe training data for both auxiliary tasks above can be trivially generated from any monolingual corpus. Hence the scale of training is unbounded. The training loss is the sum of the mean masked LM likelihood and mean next sentence prediction likelihood.\nComparison of BERT, OpenAI GPT and ELMo model architectures. (Image source:\noriginal paper\n)\nInput Embedding\n#\nThe input embedding is the sum of three parts:\nWordPiece tokenization embeddings\n: The\nWordPiece\nmodel\nwas originally proposed for Japanese or Korean segmentation problem. Instead of using naturally split English word, they can be further divided into smaller sub-word units so that it is more effective to handle rare or unknown words. Please read\nlinked\npapers\nfor the optimal way to split words if interested.\nSegment embeddings\n: If the input contains two sentences, they have sentence A embeddings and sentence B embeddings respectively and they are separated by a special character\n[SEP]\n; Only sentence A embeddings are used if the input only contains one sentence.\nPosition embeddings\n: Positional embeddings are learned rather than hard-coded.\nBERT input representation. (Image source:\noriginal paper\n)\nNote that the first token is always forced to be\n[CLS]\n— a placeholder that will be used later for prediction in downstream tasks.\nUse BERT in Downstream Tasks\n#\nBERT fine-tuning requires only a few new parameters added, just like OpenAI GPT.\nFor classification tasks, we get the prediction by taking the final hidden state of the special first token\n[CLS]\n, $\\mathbf{h}^\\text{[CLS]}_L$, and multiplying it with a small weight matrix, $\\text{softmax}(\\mathbf{h}^\\text{[CLS]}_L \\mathbf{W}_\\text{cls})$.\nFor\nQA\ntasks like SQuAD, we need to predict the text span in the given paragraph for an given question. BERT predicts two probability distributions of every token, being the start and the end of the text span. Only two new small matrices, $\\mathbf{W}_\\text{s}$ and $\\mathbf{W}_\\text{e}$, are newly learned during fine-tuning and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{s})$ and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{e})$ define two probability distributions.\nOverall the add-on part for end task fine-tuning is very minimal — one or two weight matrices to convert the Transform hidden states to an interpretable format. Check the paper for implementation details for other cases.\nTraining objects in slightly modified BERT models for downstream tasks.  (Image source:\noriginal paper\n)\nA summary table compares differences between fine-tuning of\nOpenAI GPT\nand BERT.\n|              |\nOpenAI GPT\n|\nBERT\n|\n| Special char |\n[SEP]\nand\n[CLS]\nare only introduced at fine-tuning stage. |\n[SEP]\nand\n[CLS]\nand sentence A/B embeddings are learned at the pre-training stage. |\n| Training process | 1M steps, batch size 32k words. | 1M steps, batch size 128k words. |\n| Fine-tuning  | lr = 5e-5 for all fine-tuning tasks. | Use task-specific lr for fine-tuning. |\nALBERT\n#\nALBERT\n(\nLan, et al. 2019\n), short for\nA Lite BERT\n, is a light-weighted version of\nBERT\nmodel. An ALBERT model can be trained 1.7x faster with 18x fewer parameters, compared to a BERT model of similar configuration. ALBERT incorporates three changes as follows: the first two help reduce parameters and memory consumption and hence speed up the training speed, while the third one proposes a more chanllenging training task to replace the next sentence prediction (NSP) objective.\nFactorized Embedding Parameterization\n#\nIn BERT, the WordPiece tokenization embedding size $E$ is configured to be the same as the hidden state size $H$. That is saying, if we want to increase the model size (larger $H$), we need to learn a larger tokenization embedding too, which is expensive because it depends on the vocabulary size ($V$).\nConceptually, because the tokenization embedding is expected to learn\ncontext-independent\nrepresentation and the hidden states are\ncontext-dependent\n, it makes sense to separate the size of the hidden layers from the size of vocabulary embedding. Using factorized embedding parameterization, the large vocabulary embedding matrix of size $V \\times H$ is decomposed into two small matrices of size $V \\times E$ and $E \\times H$. Given $H \\gt E$ or even $H \\gg E$, factorization can result in significant parameter reduction.\nCross-layer Parameter Sharing\n#\nParameter sharing across layers can happen in many ways: (a) only share feed-forward part; (b) only share attention parameters; or (c) share all the parameters. This technique reduces the number of parameters by a ton and does not damage the performance too much.\nSentence-Order Prediction (SOP)\n#\nInterestingly, the\nnext sentence prediction (NSP)\ntask of BERT turned out to be too easy. ALBERT instead adopted a sentence-order prediction (SOP)\nself-supervised\nloss,\nPositive sample: two consecutive segments from the same document.\nNegative sample: same as above, but the segment order is switched.\nFor the NSP task, the model can make reasonable predictions if it is able to detect topics when A and B are from different contexts. In comparison, SOP is harder as it requires the model to fully understand the coherence and ordering between segments.\nGPT-2\n#\nThe\nOpenAI\nGPT-2\nlanguage model is a direct successor to\nGPT\n. GPT-2 has 1.5B parameters, 10x more than the original GPT, and it achieves SOTA results on 7 out of 8 tested language modeling datasets in a\nzero-shot transfer setting\nwithout any task-specific fine-tuning. The pre-training dataset contains 8 million Web pages collected by crawling qualified outbound links from\nReddit\n. Large improvements by OpenAI GPT-2 are specially noticeable on small datasets and datasets used for measuring\nlong-term dependency\n.\nZero-Shot Transfer\n#\nThe pre-training task for GPT-2 is solely language modeling. All the downstream language tasks are framed as predicting conditional probabilities and there is no task-specific fine-tuning.\nText generation is straightforward using LM.\nMachine translation task, for example, English to Chinese, is induced by conditioning LM on pairs of “English sentence = Chinese sentence” and “the target English sentence =” at the end.\nFor example, the conditional probability to predict might look like:\nP(? | I like green apples. = 我喜欢绿苹果。 A cat meows at him. = 一只猫对他喵。It is raining cats and dogs. =\")\nQA task is formatted similar to translation with pairs of questions and answers in the context.\nSummarization task is induced by adding\nTL;DR:\nafter the articles in the context.\nBPE on Byte Sequences\n#\nSame as the original GPT, GPT-2 uses\nBPE\nbut on\nUTF-8\nbyte sequences. Each byte can represent 256 different values in 8 bits, while UTF-8 can use up to 4 bytes for one character, supporting up to $2^{31}$ characters in total. Therefore, with byte sequence representation we only need a vocabulary of size 256 and do not need to worry about pre-processing, tokenization, etc. Despite of the benefit, current byte-level LMs still have non-negligible performance gap with the SOTA word-level LMs.\nBPE merges frequently co-occurred byte pairs in a greedy manner. To prevent it from generating multiple versions of common words (i.e.\ndog.\n,\ndog!\nand\ndog?\nfor the word\ndog\n), GPT-2 prevents BPE from merging characters across categories (thus\ndog\nwould not be merged with punctuations like\n.\n,\n!\nand\n?\n). This tricks help increase the quality of the final byte segmentation.\nUsing the byte sequence representation, GPT-2 is able to assign a probability to any Unicode string, regardless of any pre-processing steps.\nModel Modifications\n#\nCompared to GPT, other than having many more transformer layers and parameters, GPT-2 incorporates only a few architecture modifications:\nLayer normalization\nwas moved to the input of each sub-block, similar to a residual unit of type\n“building block”\n(differently from the original type\n“bottleneck”\n, it has batch normalization applied before weight layers).\nAn additional layer normalization was added after the final self-attention block.\nA modified initialization was constructed as a function of the model depth.\nThe weights of residual layers were initially scaled by a factor of $1/ \\sqrt{N}$ where N is the number of residual layers.\nUse larger vocabulary size and context size.\nRoBERTa\n#\nRoBERTa\n(short for\nR\nobustly\no\nptimized\nBERT\na\npproach;\nLiu, et al. 2019\n) refers to a new receipt for training BERT to achieve better results, as they found that the original BERT model is significantly undertrained. The receipt contains the following learnings:\nTrain for longer with bigger batch size.\nRemove the\nnext sentence prediction (NSP)\ntask.\nUse longer sequences in training data format. The paper found that using individual sentences as inputs hurts downstream performance. Instead we should use multiple sentences sampled contiguously to form longer segments.\nChange the masking pattern dynamically. The original BERT applies masking once during the data preprocessing stage, resulting in a static mask across training epochs. RoBERTa applies masks in 10 different ways across 40 epochs.\nRoBERTa also added a new dataset\nCommonCrawl News\nand further confirmed that pretraining with\nmore data helps\nimprove the performance on downstream tasks. It was trained with the\nBPE on byte sequences\n, same as in\nGPT-2\n. They also found that choices of hyperparameters have a big impact on the model performance.\nT5\n#\nThe language model\nT5\nis short for\n“Text-to-Text Transfer Transformer”\n(\nRaffel et al., 2020\n). The encoder-decoder implementation follows the\noriginal Transformer\narchitecture: tokens → embedding → encoder → decoder → output. T5 adopts the framework “Natural Language Decathlon” (\nMcCann et al., 2018\n), where many common NLP tasks are translated into question-answering over a context. Instead of an explicit QA format, T5 uses short task prefixes to distinguish task intentions and separately fine-tunes the model on every individual task. The text-to-text framework enables easier transfer learning evaluation with the same model on a diverse set of tasks.\nA diagram of T5 task evaluation. The text-to-text framework casts every task into a generic form: feeding input text to predict some target text. (Image source:\nRaffel et al., 2020\n)\nThe model is trained on Web corpus extracted from Apr 2019 with various filters applied. The model is fine-tuned for each downstream task separately via “adapter layers” (add an extra layer for training) or “gradual unfreezing” (see\nULMFiT\n). Both fine-tuning approaches only update partial parameters while keeping the majority of the model parameters unchanged. T5-11B achieved SOTA results on many NLP tasks.\nAs the authors mentioned in the paper “…our goal is not to propose new methods but instead to provide a comprehensive perspective on where the field stands”, the T5 long paper described a lot of training setup and evaluation processes in detail, a good read for people who are interested in training a LM from scratch.\nGPT-3\n#\nGPT-3\n(\nBrown et al., 2020\n) has the same architecture as\nGPT-2\nbut contains 175B parameters, 10x larger than GPT-2 (1.5B). In addition, GPT-3 uses alternating dense and locally banded sparse attention patterns, same as in\nsparse transformer\n. In order to fit such a huge model across multiple GPUs, GPT-3 is trained with partitions along both width and depth dimension. The training data is a filtered version of Common Crawl mixed with a few other high-quality curated datasets. To avoid the contamination that downstream tasks might appear in the training data, the authors attempted to remove all the overlaps with all the studied benchmark dataset from the training dataset. Unfortunately the filtering process is not perfect due to a bug.\nTraining datasets for GPT-3. Note that the occurrence of each dataset during training is not proportional to the dataset size.  (Table source:\nBrown et al., 2020\n)\nFor all the downstream evaluation, GPT-3 is tested in the few-shot setting without any gradient-based fine-tuning. Here the few-shot examples are provided as part of the prompt. GPT-3 achieves strong performance on many NLP datasets, comparable with fine-tuned BERT models.\nThe evaluation performance increases with the model size and the number of examples. (Image source:\nBrown et al., 2020\n)\nXLNet\n#\nThe\nAutoregressive (AR)\nmodel such as GPT and\nautoencoder (AE)\nmodel such as BERT are two most common ways for language modeling. However, each has their own disadvantages: AR does not learn the bidirectional context, which is needed by downstream tasks like reading comprehension and AE assumes masked positions are independent given all other unmasked tokens which oversimplifies the long context dependency.\nXLNet\n(\nYang et al. 2019\n) generalizes the AE method to incorporate the benefits of AR. XLNet proposed the\npermutation language modeling\nobjective. For a text sequence, it samples a factorization order $\\mathbf{z}$ and decomposes the likelihood $p_\\theta(\\mathbf{x})$ according to this factorization order,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{XLNet} \n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\sum_{t=1}^T \\log p_\\theta (X_{z_t} = x \\mid \\mathbf{x}_{\\mathbf{z}_{<{t}}})\\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) } \\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) } \\Big]\n\\end{aligned}\n$$\nwhere $\\mathcal{Z}_T$ is a set of all possible permutation of length $T$;  $z_t$ and $\\mathbf{z}_{<t}$  denote the $t$-th element and the first $t-1$ elements of a permutation $\\mathbf{z} \\in \\mathcal{Z}_T$.\nNote that the naive representation of the hidden state of the context, $h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}})$ in red, does not depend on which position the model tries to predict, as the permutation breaks the default ordering. Therefore, XLNet re-parameterized it to a function of the target position too, $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ in blue.\nHowever,  two different requirements on  $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ lead to a two-stream self-attention design to accommodate:\nWhen predicting $x_{z_t}$, it should only encode the position $z_t$ but not the content $x_{z_t}$; otherwise it is trivial. This is wrapped into the “query representation”  $g_{z_t} = g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ does not encode $x_{z_t}$.\nWhen predicting $x_j$ where $j > t$, it should encode the content $x_{z_t}$ as well to provide the full context. This is the “content representation” $h_{z_t} = h_\\theta(\\mathbf{x}_{\\leq t})$.\nThe illustration of two-stream self-attention mechanism in XLNet. (Image source:\nYang et al. 2019\n)\nConceptually, the two streams of representations are updated as follows,\n$$\n\\begin{aligned}\ng_{z_t}^{(m)} &\\gets \\text{Attention}(Q = g^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{red}{\\mathbf{z}_{<{t}}}}; \\theta) &\\text{(query stream: use }z_t\\text{ but cannot see }x_{z_t}\\text{)}\\\\\nh_{z_t}^{(m)} &\\gets \\text{Attention}(Q = h^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{blue}{\\mathbf{z}_{\\leq t}}}; \\theta) &\\text{(content stream: use both }x_{z_t}\\text{ and }x_{z_t}\\text{)}\\\\\n\\end{aligned}\n$$\nGiven the difficulty of optimization in permutation language modeling, XLNet is set to only predict the last chunk of tokens in a factorization order.\nThe name in XLNet actually comes from\nTransformer-XL\n. It incorporates the design of Transformer-XL to extend the attention span by reusing hidden states from previous segments.\nComparison of model performance of XLNet with a couple other language models on GLUE, all single-task, no ensembles. (Image source:\nYang et al. 2019\n)\nBART\n#\nBART\n(\nLewis et al., 2019\n) is a denoising autoencoder to recover the original text from a randomly corrupted version. It combines\nB\nidirectional and\nA\nuto\nR\negressive\nT\nransformer: precisely, jointly training BERT-like bidirectional encoder and GPT-like autoregressive decoder together. The loss is simply just to minimize the negative log-likelihood.\nA schematic comparison of BART with BERT and GPT. (Image source:\nLewis et al., 2019\n)\nThey experimented with a variety of noising transformations, including token masking, token deletion, text infilling (i.e. A randomly sampled text span, which may contain multiple tokens, is replaced with a\n[MASK]\ntoken), sentence permutation, documentation rotation (i.e. A document is rotated to begin with a random token.). The best noising approach they discovered is text infilling and sentence shuffling.\nComparison of different language modeling pre-training objectives. (Image source:\nLewis et al., 2019\n)\nLearnings from their experiments:\nThe performance of pre-training methods varies significantly across downstream tasks.\nToken masking is crucial, as the performance is poor when only sentence permutation or documentation rotation is applied.\nLeft-to-right pre-training improves generation.\nBidirectional encoders are crucial for SQuAD.\nThe pre-training objective is not the only important factor. Architectural improvements such as relative-position embeddings or segment-level recurrence matter too.\nAutoregressive language models perform best on ELI5.\nBART achieves the most consistently strong performance.\nELECTRA\n#\nMost current pre-training large language models demand a lot of computation resources, raising concerns about their cost and accessibility.\nELECTRA\n(“Efficiently Learning an Encoder that Classifies Token Replacements Accurately”;\nClark et al. 2020\n) aims to improve the\npre-training efficiency\n, which frames the language modeling as a discrimination task instead of generation task.\nIllustration of ELECTRA model architecture. (Image source:\nClark et al. 2020\n)\nELECTRA proposes a new pretraining task, called “Replaced Token Detection” (RTD). Let’s randomly sample $k$ positions to be masked. Each selected token in the original text is replaced by a plausible alternative predicted by a small language model, known as the generator $G$. The discriminator $D$ predicts whether each token is original or replaced.\n$$\n\\begin{aligned}\n\\boldsymbol{m} &= [m_1, \\dots, m_k] \\text{ where } m_i \\sim \\text{unif}\\{1, n\\}\\text{ for } i=1, \\dots, k \\\\\n\\boldsymbol{x}^\\text{masked} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\texttt{[MASK]}) \\\\\n\\boldsymbol{x}^\\text{corrupt} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\tilde{\\boldsymbol{x}}) \\text{ where } \\tilde{x}_t \\sim p_G(x_i \\mid \\boldsymbol{x}^\\text{masked}) \\text{ for } i \\in \\boldsymbol{m} \\\\\n\\end{aligned}\n$$\nThe loss for the generator is the negative log-likelihood just as in other language models. The loss for the discriminator is the cross-entropy. Note that the generator is not adversarially trained to fool the discriminator but simply to optimize the NLL, since their experiments show negative results.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{MLM}(\\mathbf{x}, \\theta_G) &= \\mathbb{E}\\Big(\\sum_{i \\in \\boldsymbol{m}} -\\log p_G (x_i \\mid \\boldsymbol{x}^\\text{masked} )\\Big) \\\\\n\\mathcal{L}_\\text{Disc}(\\mathbf{x}, \\theta_D) &= \\mathbb{E}\\Big( - \\mathbb{1}[x^\\text{corrupt}_t = x_t] \\log D(\\boldsymbol{x}^\\text{corrupt}, t) - \\mathbb{1}[x^\\text{corrupt}_t \\neq x_t] \\log (1 - \\log D(\\boldsymbol{x}^\\text{corrupt}, t))  \\Big)\n\\end{aligned}\n$$\nThey found it more beneficial to only share the embeddings between generator & discriminator while using a small generator (1/4 to 1/2 the discriminator size), rather than sharing all the weights (i.e. two models have to be the same size then). In addition, joint training of the generator and discriminator works better than two-stage training of each alternatively.\nAfter pretraining the generator is discarded and only the ELECTRA discriminator is fine-tuned further for downstream tasks. The following table shows ELECTRA’s performance on the GLUE dev set.\nComparison of ELECTRA with other language models on the GLUE dev set. (Image source:\nClark et al. 2020\n)\nSummary\n#\nBase model\nPretraining Tasks\nCoVe\nseq2seq NMT model\nsupervised learning using translation dataset.\nELMo\ntwo-layer biLSTM\nnext token prediction\nCVT\ntwo-layer biLSTM\nsemi-supervised learning using both labeled and unlabeled datasets\nULMFiT\nAWD-LSTM\nautoregressive pretraining on Wikitext-103\nGPT\nTransformer decoder\nnext token prediction\nBERT\nTransformer encoder\nmask language model + next sentence prediction\nALBERT\nsame as BERT but light-weighted\nmask language model + sentence order prediction\nGPT-2\nTransformer decoder\nnext token prediction\nRoBERTa\nsame as BERT\nmask language model (dynamic masking)\nT5\nTransformer encoder + decoder\npre-trained on a multi-task mixture of unsupervised and supervised tasks and for which each task is converted into a text-to-text format.\nGPT-3\nTransformer decoder\nnext token prediction\nXLNet\nsame as BERT\npermutation language modeling\nBART\nBERT encoder + GPT decoder\nreconstruct text from a noised version\nELECTRA\nsame as BERT\nreplace token detection\nMetric: Perplexity\n#\nPerplexity is often used as an intrinsic evaluation metric for gauging how well a language model can capture the real word distribution conditioned on the context.\nA\nperplexity\nof a discrete proability distribution $p$ is defined as the exponentiation of the entropy:\n$$\n2^{H(p)} = 2^{-\\sum_x p(x) \\log_2 p(x)}\n$$\nGiven a sentence with $N$ words, $s = (w_1, \\dots, w_N)$, the entropy looks as follows, simply assuming that each word has the same frequency, $\\frac{1}{N}$:\n$$\nH(s) = -\\sum_{i=1}^N P(w_i) \\log_2  p(w_i)  = -\\sum_{i=1}^N \\frac{1}{N} \\log_2  p(w_i)\n$$\nThe perplexity for the sentence becomes:\n$$\n\\begin{aligned}\n2^{H(s)} &= 2^{-\\frac{1}{N} \\sum_{i=1}^N \\log_2  p(w_i)}\n= (2^{\\sum_{i=1}^N \\log_2  p(w_i)})^{-\\frac{1}{N}}\n= (p(w_1) \\dots p(w_N))^{-\\frac{1}{N}}\n\\end{aligned}\n$$\nA good language model should predict high word probabilities. Therefore, the smaller perplexity the better.\nCommon Tasks and Datasets\n#\nQuestion-Answering\nSQuAD\n(Stanford Question Answering Dataset): A reading comprehension dataset, consisting of questions posed on a set of Wikipedia articles, where the answer to every question is a span of text.\nRACE\n(ReAding Comprehension from Examinations): A large-scale reading comprehension dataset with more than 28,000 passages and nearly 100,000 questions. The dataset is collected from English examinations in China, which are designed for middle school and high school students.\nSee\nmore QA datasets in a later post\n.\nCommonsense Reasoning\nStory Cloze Test\n: A commonsense reasoning framework for evaluating story understanding and generation. The test requires a system to choose the correct ending to multi-sentence stories from two options.\nSWAG\n(Situations With Adversarial Generations): multiple choices; contains 113k sentence-pair completion examples that evaluate grounded common-sense inference\nNatural Language Inference (NLI)\n: also known as\nText Entailment\n, an exercise to discern in logic whether one sentence can be inferred from another.\nRTE\n(Recognizing Textual Entailment): A set of datasets initiated by text entailment challenges.\nSNLI\n(Stanford Natural Language Inference): A collection of 570k human-written English sentence pairs manually labeled for balanced classification with the labels\nentailment\n,\ncontradiction\n, and\nneutral\n.\nMNLI\n(Multi-Genre NLI): Similar to SNLI, but with a more diverse variety of text styles and topics, collected from transcribed speech, popular fiction, and government reports.\nQNLI\n(Question NLI): Converted from SQuAD dataset to be a binary classification task over pairs of (question, sentence).\nSciTail\n: An entailment dataset created from multiple-choice science exams and web sentences.\nNamed Entity Recognition (NER)\n: labels sequences of words in a text which are the names of things, such as person and company names, or gene and protein names\nCoNLL 2003 NER task\n: consists of newswire from the Reuters, concentrating on four types of named entities: persons, locations, organizations and names of miscellaneous entities.\nOntoNotes 5.0\n: This corpus contains text in English, Arabic and Chinese, tagged with four different entity types (PER, LOC, ORG, MISC).\nReuters Corpus\n: A large collection of Reuters News stories.\nFine-Grained NER (FGN)\nSentiment Analysis\nSST\n(Stanford Sentiment Treebank)\nIMDb\n: A large dataset of movie reviews with binary sentiment classification labels.\nSemantic Role Labeling (SRL)\n: models the predicate-argument structure of a sentence, and is often described as answering “Who did what to whom”.\nCoNLL-2004 & CoNLL-2005\nSentence similarity\n: also known as\nparaphrase detection\nMRPC\n(MicRosoft Paraphrase Corpus): It contains pairs of sentences extracted from news sources on the web, with annotations indicating whether each pair is semantically equivalent.\nQQP\n(Quora Question Pairs)\nSTS Benchmark: Semantic Textual Similarity\nSentence Acceptability\n: a task to annotate sentences for grammatical acceptability.\nCoLA\n(Corpus of Linguistic Acceptability): a binary single-sentence classification task.\nText Chunking\n: To divide a text in syntactically correlated parts of words.\nCoNLL-2000\nPart-of-Speech (POS) Tagging\n: tag parts of speech to each token, such as noun, verb, adjective, etc.\nthe Wall Street Journal portion of the Penn Treebank (Marcus et al., 1993).\nMachine Translation\n:  See\nStandard NLP\npage.\nWMT 2015 English-Czech data (Large)\nWMT 2014 English-German data (Medium)\nIWSLT 2015 English-Vietnamese data (Small)\nCoreference Resolution\n: cluster mentions in text that refer to the same underlying real world entities.\nCoNLL-2012\nLong-range Dependency\nLAMBADA\n(LAnguage Modeling Broadened to Account for Discourse Aspects): A collection of narrative passages extracted from the BookCorpus and the task is to predict the last word, which require at least 50 tokens of context for a human to successfully predict.\nChildren’s Book Test\n: is built from books that are freely available in\nProject Gutenberg\n. The task is to predict the missing word among 10 candidates.\nMulti-task benchmark\nGLUE multi-task benchmark:\nhttps://gluebenchmark.com\ndecaNLP benmark:\nhttps://decanlp.com\nUnsupervised pretraining dataset\nBooks corpus\n: The corpus contains “over 7,000 unique unpublished books from a variety of genres including Adventure, Fantasy, and Romance.”\n1B Word Language Model Benchmark\nEnglish Wikipedia\n: ~2500M words\nCited as:\n@article{weng2019LM,\n  title   = \"Generalized Language Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-01-31-lm/\"\n}\nReference\n#\n[1] Bryan McCann, et al.\n“Learned in translation: Contextualized word vectors.”\nNIPS. 2017.\n[2] Kevin Clark et al.\n“Semi-Supervised Sequence Modeling with Cross-View Training.”\nEMNLP 2018.\n[3] Matthew E. Peters, et al.\n“Deep contextualized word representations.”\nNAACL-HLT 2017.\n[4] OpenAI Blog\n“Improving Language Understanding with Unsupervised Learning”\n, June 11, 2018.\n[5] OpenAI Blog\n“Better Language Models and Their Implications.”\nFeb 14, 2019.\n[6] Jeremy Howard and Sebastian Ruder.\n“Universal language model fine-tuning for text classification.”\nACL 2018.\n[7] Alec Radford et al.\n“Improving Language Understanding by Generative Pre-Training”\n. OpenAI Blog, June 11, 2018.\n[8] Jacob Devlin, et al.\n“BERT: Pre-training of deep bidirectional transformers for language understanding.”\narXiv:1810.04805 (2018).\n[9] Mike Schuster, and Kaisuke Nakajima.\n“Japanese and Korean voice search.”\nICASSP. 2012.\n[10] Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation\n[11] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[12] Peter J. Liu, et al.\n“Generating wikipedia by summarizing long sequences.”\nICLR 2018.\n[13] Sebastian Ruder.\n“10 Exciting Ideas of 2018 in NLP”\nDec 2018.\n[14] Alec Radford, et al.\n“Language Models are Unsupervised Multitask Learners.”\n. 2019.\n[15] Rico Sennrich, et al.\n“Neural machine translation of rare words with subword units.”\narXiv preprint arXiv:1508.07909. 2015.\n[16] Zhenzhong Lan, et al.\n“ALBERT: A Lite BERT for Self-supervised Learning of Language Representations.”\narXiv Preprint arXiv:1909.11942 (2019).\n[17] Yinhan Liu, et al.\n“RoBERTa: A Robustly Optimized BERT Pretraining Approach.”\narXiv Preprint arXiv:1907.11692 (2019).\n[18] Tom B Brown, et al.\n“Language Models are Few-Shot Learners”\nNeuriPS 2020.\n[19] Zhilin Yang et al.\n“XLNet: Generalized Autoregressive Pretraining for Language Understanding.”\nNeuriPS 2019.\n[20] Mike Lewis et al.\n“BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension.”\nACL 2020.\n[21] Kevin Clark et al.\n“ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators.”\nICLR 2020.\n[22] Colin Raffel, et al.\n“Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer”\nJMLR 2020.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:17Z",
            "title": "Generalized Language Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/607baf97b999/code/body-000.txt",
                "chars": 214,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": true,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.00107",
                "bytes": 446263,
                "reused": true,
                "local_path": "papers/repair/e2c0a99965fb6abdde60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05365",
                "bytes": 425880,
                "reused": true,
                "local_path": "papers/repair/c4dc3d740cad43df1dd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.08370",
                "bytes": 811545,
                "reused": true,
                "local_path": "papers/repair/459221e6be389ff8d946.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.06146",
                "bytes": 979417,
                "reused": true,
                "local_path": "papers/repair/f99f602eebf2965d0ed0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02182",
                "bytes": 185413,
                "reused": true,
                "local_path": "papers/repair/f2555bb43fcea5781c7c.pdf"
              },
              {
                "status": "http_403",
                "url": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "retried_at": "2026-10-20T18:10:14Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.10198",
                "bytes": 1134703,
                "reused": true,
                "local_path": "papers/repair/fe35dee079dad5528221.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.07909",
                "bytes": 193216,
                "reused": true,
                "local_path": "papers/repair/a5d0ca76205630ec8110.pdf"
              },
              {
                "status": "ok",
                "url": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "bytes": 144257,
                "reused": true,
                "local_path": "papers/repair/0eab031e51f81c92fda2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.08144.pdf",
                "bytes": 1688289,
                "reused": true,
                "local_path": "papers/repair/29316aab6d109d3a9ea6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11942",
                "bytes": 419105,
                "reused": true,
                "local_path": "papers/repair/9c6f91591bd290ea5163.pdf"
              },
              {
                "status": "download_error",
                "url": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "reason": "ConnectionError: HTTPSConnectionPool(host='d4mucfpksywv.cloudfront.net', port=443): Max retries exceeded with url: /better-language-models/language_models_are_unsupervised_multitask_learners.pdf (C",
                "retried_at": "2026-10-20T22:25:42Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1607.06450",
                "bytes": 612446,
                "reused": true,
                "local_path": "papers/repair/52a2360d9b658baa64ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.05027",
                "bytes": 1166414,
                "reused": true,
                "local_path": "papers/repair/780d6bd86240bf248474.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385",
                "bytes": 819383,
                "reused": true,
                "local_path": "papers/repair/523013cf51110acbfe60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.11692",
                "bytes": 209675,
                "reused": true,
                "local_path": "papers/repair/8acd467c11db68744d3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.08730",
                "bytes": 1187133,
                "reused": true,
                "local_path": "papers/repair/e2a98f1a611cef094a63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.08237",
                "bytes": 761790,
                "reused": true,
                "local_path": "papers/repair/e1dc08bfcdc2d830fa23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10555",
                "bytes": 497999,
                "reused": true,
                "local_path": "papers/repair/95df7a9ffe51e8dc3c44.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53020,
            "expected_body_images": 23,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_403",
            "raw_html": "attachments/607baf97b999/pages/source.html",
            "local_html": "attachments/607baf97b999/pages/article.html",
            "body_base_path": "attachments/607baf97b999/pages/",
            "body_markdown_path": "attachments/607baf97b999/pages/article.md",
            "links": [
              {
                "href": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/language-unsupervised/",
                "label": "OpenAI GPT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "found",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "post on word embedding",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.00107",
                "label": "McCann et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attentional seq-to-seq",
                "type": "a"
              },
              {
                "href": "https://github.com/THUNLP-MT/MT-Reading-List",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05365",
                "label": "Peters, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Part-of-speech_tagging",
                "label": "part-of-speech",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.08370",
                "label": "Clark et al., 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beam_search",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.06146",
                "label": "Howard & Ruder, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02182",
                "label": "AWD-LSTM",
                "type": "a"
              },
              {
                "href": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "label": "Radford et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "original transformer",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.10198",
                "label": "transformer decoder",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.07909",
                "label": "BPE",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Wikipedia",
                "type": "a"
              },
              {
                "href": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "label": "WordPiece",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1609.08144.pdf",
                "label": "model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11942",
                "label": "Lan, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/better-language-models/",
                "label": "OpenAI",
                "type": "a"
              },
              {
                "href": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "label": "GPT-2",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/",
                "label": "Reddit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/UTF-8",
                "label": "UTF-8",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1607.06450",
                "label": "Layer normalization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.05027",
                "label": "“building block”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.03385",
                "label": "“bottleneck”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.11692",
                "label": "Liu, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/2016/10/news-dataset-available/",
                "label": "CommonCrawl News",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "Raffel et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.08730",
                "label": "McCann et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "sparse transformer",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2020/hash/1457c0d6bfcb4967418bfb8ac142f64a-Abstract.html",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.08237",
                "label": "Yang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "Lewis et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10555",
                "label": "Clark et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Perplexity",
                "label": "perplexity",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "more QA datasets in a later post",
                "type": "a"
              },
              {
                "href": "http://cs.rochester.edu/nlp/rocstories/",
                "label": "Story Cloze Test",
                "type": "a"
              },
              {
                "href": "https://rowanzellers.com/swag/",
                "label": "SWAG",
                "type": "a"
              },
              {
                "href": "https://aclweb.org/aclwiki/Textual_Entailment_Resource_Pool",
                "label": "RTE",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://www.nyu.edu/projects/bowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/tasks",
                "label": "QNLI",
                "type": "a"
              },
              {
                "href": "http://data.allenai.org/scitail/",
                "label": "SciTail",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2003/",
                "label": "CoNLL 2003 NER task",
                "type": "a"
              },
              {
                "href": "https://catalog.ldc.upenn.edu/LDC2013T19",
                "label": "OntoNotes 5.0",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/reuters/reuters.html",
                "label": "Reuters Corpus",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/sentiment/index.html",
                "label": "SST",
                "type": "a"
              },
              {
                "href": "http://ai.stanford.edu/~amaas/data/sentiment/",
                "label": "IMDb",
                "type": "a"
              },
              {
                "href": "http://www.lsi.upc.edu/~srlconll/",
                "label": "CoNLL-2004 & CoNLL-2005",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/download/details.aspx?id=52398",
                "label": "MRPC",
                "type": "a"
              },
              {
                "href": "https://data.quora.com/First-Quora-Dataset-Release-Question-Pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://nyu-mll.github.io/CoLA/",
                "label": "CoLA",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2000/chunking/",
                "label": "CoNLL-2000",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/nmt/",
                "label": "Standard NLP",
                "type": "a"
              },
              {
                "href": "http://conll.cemantix.org/2012/data.html",
                "label": "CoNLL-2012",
                "type": "a"
              },
              {
                "href": "http://clic.cimec.unitn.it/lambada/",
                "label": "LAMBADA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "Children’s Book Test",
                "type": "a"
              },
              {
                "href": "https://www.gutenberg.org/",
                "label": "Project Gutenberg",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/",
                "label": "https://gluebenchmark.com",
                "type": "a"
              },
              {
                "href": "https://decanlp.com/",
                "label": "https://decanlp.com",
                "type": "a"
              },
              {
                "href": "https://googlebooks.byu.edu/",
                "label": "Books corpus",
                "type": "a"
              },
              {
                "href": "http://www.statmt.org/lm-benchmark/",
                "label": "1B Word Language Model Benchmark",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wikipedia:Database_download",
                "label": "English Wikipedia",
                "type": "a"
              },
              {
                "href": "http://ruder.io/10-exciting-ideas-of-2018-in-nlp/",
                "label": "“10 Exciting Ideas of 2018 in NLP”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
          "status": "ok",
          "article_id": "4ceb83900555",
          "local_path": "series-follow/1602/repair/e7cc4652c4afc9c11bf9.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
              "bytes": 205910,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2795fb5ace8ffbc1b24d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
              "bytes": 483584,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1ad2438e764ecf66f44b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
              "bytes": 88034,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c8c63c3f68a56e1637ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
              "bytes": 791396,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cfd79c5354e69b23974e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
              "bytes": 464686,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3c61bc54c452df857d49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
              "bytes": 412094,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/896ff9901d3559eccc2a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
              "bytes": 208079,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a68ed63975ef71160d3c.png"
            }
          ],
          "article": {
            "id": "4ceb83900555",
            "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "bytes": 205910,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-2795fb5ace8ffbc1b24d.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "bytes": 483584,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-1ad2438e764ecf66f44b.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "bytes": 88034,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-c8c63c3f68a56e1637ef.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "bytes": 791396,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-cfd79c5354e69b23974e.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "bytes": 464686,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-3c61bc54c452df857d49.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "bytes": 412094,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-896ff9901d3559eccc2a.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "bytes": 208079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-a68ed63975ef71160d3c.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=DKe8FumoD4E",
                "src": "https://www.youtube.com/embed/DKe8FumoD4E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4ceb83900555/videos/repair-DKe8FumoD4E.mp4",
                "bytes": 37082109,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "434.721000",
                "reused": false
              }
            ],
            "body_markdown": "In Robotics, one of the hardest problems is how to make your model transfer to the real world. Due to the sample inefficiency of deep RL algorithms and the cost of data collection on real robots, we often need to train models in a simulator which theoretically provides an infinite amount of data. However, the reality gap between the simulator and the physical world often leads to failure when working with physical robots. The gap is triggered by an inconsistency between physical parameters (i.e. friction, kp, damping, mass, density) and, more fatally, the incorrect physical modeling (i.e. collision between soft surfaces).\nTo close the sim2real gap, we need to improve the simulator and make it closer to reality. A couple of approaches:\nSystem identification\nSystem identification\nis to build a mathematical model for a physical system; in the context of RL, the mathematical model is the simulator. To make the simulator more realistic, careful calibration is necessary.\nUnfortunately, calibration is expensive. Furthermore, many physical parameters of the same machine might vary significantly due to temperature, humidity, positioning or its wear-and-tear in time.\nDomain adaptation\nDomain adaptation (DA)\nrefers to a set of transfer learning techniques developed to update the data distribution in sim to match the real one through a mapping or regularization enforced by the task model.\nMany DA models, especially for image classification or end-to-end image-based RL task, are built on adversarial loss or\nGAN\n.\nDomain randomization\nWith\ndomain randomization (DR)\n, we are able to create a variety of simulated environments with randomized properties and train a model that works across all of them.\nLikely this model can adapt to the real-world environment, as the real system is expected to be one sample in that rich distribution of training variations.\nBoth DA and DR are unsupervised. Compared to DA which requires a decent amount of real data samples to capture the distribution, DR may need\nonly a little or no\nreal data. DR is the focus of this post.\nConceptual illustrations of three approaches for sim2real transfer.\nWhat is Domain Randomization?\n#\nTo make the definition more general, let us call the environment that we have full access to (i.e. simulator)\nsource domain\nand the environment that we would like to transfer the model to\ntarget domain\n(i.e. physical world). Training happens in the source domain. We can control a set of $N$ randomization parameters in the source domain $e_\\xi$ with a configuration $\\xi$, sampled from a randomization space, $\\xi \\in \\Xi \\subset \\mathbb{R}^N$.\nDuring policy training, episodes are collected from source domain with randomization applied. Thus the policy is exposed to a variety of environments and learns to generalize. The policy parameter $\\theta$ is trained to maximize the expected reward $R(.)$ average across a distribution of configurations:\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{\\xi \\sim \\Xi} [\\mathbb{E}_{\\pi_\\theta, \\tau \\sim e_\\xi} [R(\\tau)]]\n$$\nwhere $\\tau_\\xi$ is a trajectory collected in source domain randomized with $\\xi$. In a way,\n“discrepancies between the source and target domains are modeled as variability in the source domain.”\n(quote from\nPeng et al. 2018\n).\nUniform Domain Randomization\n#\nIn the original form of DR (\nTobin et al, 2017\n;\nSadeghi et al. 2016\n), each randomization parameter $\\xi_i$ is bounded by an interval, $\\xi_i \\in [\\xi_i^\\text{low}, \\xi_i^\\text{high}], i=1,\\dots,N$ and each parameter is uniformly sampled within the range.\nThe randomization parameters can control appearances of the scene, including but not limited to the followings (see Fig. 2). A model trained on simulated and randomized images is able to transfer to real non-randomized images.\nPosition, shape, and color of objects,\nMaterial texture,\nLighting condition,\nRandom noise added to images,\nPosition, orientation, and field of view of the camera in the simulator.\nImages captured in the training environment are randomized. (Image source:\nTobin et al, 2017\n)\nPhysical dynamics in the simulator can also be randomized (\nPeng et al. 2018\n). Studies have showed that a\nrecurrent\npolicy can adapt to different physical dynamics including the partially observable reality. A set of physical dynamics features include but are not limited to:\nMass and dimensions of objects,\nMass and dimensions of robot bodies,\nDamping, kp, friction of the joints,\nGains for the PID controller (P term),\nJoint limit,\nAction delay,\nObservation noise.\nWith visual and dynamics DR, at OpenAI Robotics, we were able to learn a policy that works on real dexterous robot hand (\nOpenAI, 2018\n). Our manipulation task is to teach the robot hand to rotate an object continously to achieve 50 successive random target orientations. The sim2real gap in this task is very large, due to (a) a high number of simultaneous contacts between the robot and the object and (b) imperfect simulation of object collision and other motions. At first, the policy could barely survive for more than 5 seconds without dropping the object. But with the help of DR, the policy evolved to work surprisingly well in reality eventually.\nWhy does Domain Randomization Work?\n#\nNow you may ask, why does domain randomization work so well? The idea sounds really simple. Here are two non-exclusive explanations I found most convincing.\nDR as Optimization\n#\nOne idea (\nVuong, et al, 2019\n) is to view learning randomization parameters in DR as a\nbilevel optimization\n. Assuming we have access to the real environment $e_\\text{real}$ and the randomization config is sampled from a distribution parameterized by $\\phi$, $\\xi \\sim P_\\phi(\\xi)$, we would like to learn a distribution on which a policy $\\pi_\\theta$ is trained on can achieve maximal performance in $e_\\text{real}$:\n$$\n\\begin{aligned}\n&\\phi^* = \\arg\\min_{\\phi} \\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real}) \\\\\n\\text{where } &\\theta^*(\\phi) = \\arg\\min_\\theta \\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)}[\\mathcal{L}(\\pi_\\theta; e_\\xi)]\n\\end{aligned}\n$$\nwhere $\\mathcal{L}(\\pi; e)$ is the loss function of policy $\\pi$ evaluated in the environment $e$.\nAlthough randomization ranges are hand-picked in uniform DR, it often involves domain knowledge and a couple rounds of trial-and-error adjustment based on the transfer performance. Essentially this is a manual optimization process on tuning $\\phi$ for the optimal $\\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real})$.\nGuided domain randomization in the next section is largely inspired by this view, aiming to do bilevel optimization and learn the best parameter distribution automatically.\nDR as Meta-Learning\n#\nIn our learning dexterity project (\nOpenAI, 2018\n), we trained an LSTM policy to generalize across different environmental dynamics. We observed that once a robot achieved the first rotation, the time it needed for the following successes was much shorter. Also, a FF policy without memory was found not able to transfer to a physical robot. Both are evidence of the policy dynamically learning and adapting to a new environment.\nIn some ways, domain randomization composes a collection of different tasks. Memory in the recurrent network empowers the policy to achieve\nmeta-learning\nacross tasks and further work on a real-world setting.\nGuided Domain Randomization\n#\nThe vanilla DR assumes no access to the real data, and thus the randomization config is sampled as broadly and uniformly as possible in sim, hoping that the real environment could be covered under this broad distribution. It is reasonable to think of a more sophisticated strategy — replacing uniform sampling with guidance from\ntask performance\n,\nreal data\n, or\nsimulator\n.\nOne motivation for guided DR is to save computation resources by avoiding training models in unrealistic environments. Another is to avoid infeasible solutions that might arise from overly wide randomization distributions and thus might hinder successful policy learning.\nOptimization for Task Performance\n#\nSay we train a family of policies with different randomization parameters $\\xi \\sim P_\\phi(\\xi)$, where $P_\\xi$ is the distribution for $\\xi$ parameterized by $\\phi$. Later we decide to try every one of them on the downstream task in the target domain (i.e. control a robot in reality or evaluate on a validation set) to collect feedback. This feedback tells us how good a configuration $\\xi$ is and provides signals for optimizing $\\phi$.\nInspired by\nNAS\n,\nAutoAugment\n(\nCubuk, et al. 2018\n) frames the problem of learning best data augmentation operations (i.e.  shearing, rotation, invert, etc.) for image classification as an RL problem. Note that AutoAugment is not proposed for sim2real transfer, but falls in the bucket of DR guided by task performance. Individual augmentation configuration is tested on the evaluation set and the performance improvement is used as a reward to train a PPO policy. This policy outputs different augmentation strategies for different datasets; for example, for CIFAR-10 AutoAugment mostly  picks color-based transformations, while ImageNet prefers geometric based.\nRuiz (2019)\nconsidered the\ntask feedback\nas\nreward\nin RL problem and proposed a RL-based method, named “learning to simulate”, for adjusting $\\xi$. A policy is trained to predict $\\xi$ using performance metrics on the validation data of the main task as rewards, which is modeled as a multivariate Gaussian. Overall the idea is similar to AutoAugment, applying NAS on data generation. According to their experiments, even if the main task model is not converged, it still can provide a reasonable signal to the data generation policy.\nAn overview of the \"learning to simulate\" approach. (Image source:\nRuiz (2019)\n)\nEvolutionary algorithm is another way to go, where the\nfeedback\nis treated as\nfitness\nfor guiding evolution (\nYu et al, 2019\n). In this study, they used\nCMA-ES\n(covariance matrix adaptation evolution strategy) while fitness is the performance of a $\\xi$-conditional policy in target environment. In the appendix, they compared CMA-ES with other ways of modeling the dynamics of $\\xi$, including Bayesian optimization or a neural network. The main claim was those methods are not as stable or sample efficient as CMA-ES. Interestly, when modeling $P(\\xi)$ as a neural network, LSTM is found to notably outperform FF.\nSome believe that sim2real gap is a combination of appearance gap and content gap; i.e. most GAN-inspired DA models focus on appearance gap.\nMeta-Sim\n(\nKar, et al. 2019\n) aims to close the content gap by generating task-specific synthetic datasets. Meta-Sim uses self-driving car training as an example and thus the scene could be very complicated. In this case, the synthetic scenes are parameterized by a hierarchy of objects with properties (i.e., location, color) as well as relationships between objects. The hierarchy is specified by a probabilistic scene grammar akin to structure domain randomization (\nSDR\n;\nPrakash et al., 2018\n) and it is assumed to be known beforehand. A model $G$ is trained to augment the distribution of scene properties $s$ by following:\nLearn the prior first: pre-train $G$ to learn the identity function $G(s) = s$.\nMinimize MMD loss between the real and sim data distributions. This involves backpropagation through non-differentiable renderer. The paper computes it numerically by perturbing the attributes of $G(s)$.\nMinimize REINFORCE task loss when trained on synthetic data but evaluated on real data. Again, very similar to AutoAugment.\nUnfortunately, this family of methods are not suitable for sim2real case. Either an RL policy or an EA model requires a large number of real samples. And it is really expensive to include real-time feedback collection on a physical robot into the training loop. Whether you want to trade less computation resource for real data collection would depend on your task.\nMatch Real Data Distribution\n#\nUsing real data to guide domain randomization feels a lot like doing system identification or DA. The core idea behind DA is to improve the synthetic data to match the real data distribution. In the case of real-data-guided DR, we would like to learn the randomization parameters $\\xi$ that bring the state distribution in simulator close to the state distribution in the real world.\nThe\nSimOpt\nmodel (\nChebotar et al, 2019\n) is trained under an initial randomization distribution $P_\\phi(\\xi)$ first, getting a policy $\\pi_{\\theta, P_\\phi}$. Then this policy is deployed on both simulator and physical robot to collect trajectories $\\tau_\\xi$ and $\\tau_\\text{real}$ respectively. The optimization objective is to minimize the discrepancy between sim and real trajectories:\n$$\n\\phi^* = \\arg\\min_{\\phi}\\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)} [\\mathbb{E}_{\\pi_{\\theta, P_\\phi}} [D(\\tau_\\text{sim}, \\tau_\\text{real})]]\n$$\nwhere $D(.)$ is a trajectory-based discrepancy measure. Like the “Learning to simulate” paper, SimOpt also has to solve the tricky problem of how to propagate gradient through non-differentiable simulator. It used a method called\nrelative entropy policy search\n, see paper for more details.\nAn overview of the SimOpt framework. (Image source:\nChebotar et al, 2019\n)\nRCAN\n(\nJames et al., 2019\n), short for “Randomized-to-Canonical Adaptation Networks”, is a nice combination of DA and DR for end-to-end RL tasks. An image-conditional GAN (\ncGAN\n) is trained in sim to translate a domain-randomized image into a non-randomized version (aka “canonical version”). Later the same model is used to translate real images into corresponding simulated version so that the agent would consume consistent observation as what it has encountered in training. Still, the underlying assumption is that the distribution of domain-randomized sim images is broad enough to cover real-world samples.\nRCAN is an image-conditional generator that can convert a domain-randomized or real image into its corresponding non-randomized simulator version. (Image source:\nJames et al., 2019\n)\nThe RL model is trained end-to-end in a simulator to do vision-based robot arm grasping. Randomization is applied at each timestep, including the position of tray divider, objects to grasp, random textures, as well as the position, direction, and color of the lighting. The canonical version is the default simulator look. RCAN is trying to learn a generator\n$G$: randomized image $\\to$ {canonical image, segmentation, depth}\nwhere segmentation masks and depth images are used as auxiliary tasks. RCAN had a better zero-shot transfer compared to uniform DR, although both were shown to be worse than the model trained on only real images. Conceptually, RCAN operates in a reverse direction of\nGraspGAN\nwhich translates synthetic images into real ones by domain adaptation.\nGuided by Data in Simulator\n#\nNetwork-driven domain randomization (\nZakharov et al., 2019\n), also known as\nDeceptionNet\n,  is motivated by learning which randomizations are actually useful to bridge the domain gap for image classification tasks.\nRandomization is applied through a set of deception modules with encoder-decoder architecture. The deception modules are specifically designed to transform images; such as change backgrounds, add distortion, change lightings, etc. The other recognition network handles the main task by running classification on transformed images.\nThe training involves two steps:\nWith the recognition network fixed,\nmaximize the difference\nbetween the prediction and the labels by applying reversed gradients during backpropagation.  So that the deception module can learn the most confusing tricks.\nWith the deception modules fixed, train the recognition network with input images altered.\nHow DeceptionNet works. (Image source:\nZakharov et al., 2019\n)\nThe feedback for training deception modules is provided by the downstream classifier. But rather than trying to maximize the task performance like\nthe section\nabove, the randomization modules aim to create harder cases. One big disadvantage is you need to manually design different deception modules for different datasets or tasks, making it not easily scalable. Given the fact that it is zero-shot, the results are still worse than SOTA DA methods on MNIST and LineMOD.\nSimilarly, Active domain randomization (\nADR\n;\nMehta et al., 2019\n) also relies on sim data to create harder training samples. ADR searches for the\nmost informative\nenvironment variations within the given randomization ranges, where the\ninformativeness\nis measured as the discrepancies of policy rollouts in randomized and reference (original, non-randomized) environment instances. Sounds a bit like\nSimOpt\n? Well, noted that SimOpt measures the discrepancy between sim and real rollouts, while ADR measures between randomized and non-randomized sim, avoiding the expensive real data collection part.\nHow active domain randomization (ADR) works. (Image source:\nMehta et al., 2019\n)\nPrecisely the training happens as follows:\nGiven a policy, run it on both reference and randomized envs and collect two sets of trajectories respectively.\nTrain a discriminator model to tell whether a rollout trajectory is randomized apart from reference run. The predicted $\\log p$ (probability of being randomized) is used as reward. The more different randomized and reference rollouts, the easier the prediction, the higher the reward.\nThe intuition is that if an environment is easy, the same policy agent can produce similar trajectories as in the reference one. Then the model should reward and explore hard environments by encouraging different behaviors.\nThe reward by discriminator is fed into\nStein Variational Policy Gradient\n(\nSVPG\n) particles, outputting a diverse set of randomization configurations.\nThe idea of ADR is very appealing with two small concerns. The similarity between trajectories might not be a good way to measure the env difficulty when running a stochastic policy. The sim2real results look unfortunately not as exciting, but the paper pointed out the win being ADR explores a smaller range of randomization parameters.\nCited as:\n@article{weng2019DR,\n  title   = \"Domain Randomization for Sim2Real Transfer\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-05-05-domain-randomization/\"\n}\nOverall, after reading this post, I hope you like domain randomization as much as I do :).\nReferences\n#\n[1] Josh Tobin, et al.\n“Domain randomization for transferring deep neural networks from simulation to the real world.”\nIROS, 2017.\n[2] Fereshteh Sadeghi and Sergey Levine.\n“CAD2RL: Real single-image flight without a single real image.”\narXiv:1611.04201 (2016).\n[3] Xue Bin Peng, et al.\n“Sim-to-real transfer of robotic control with dynamics randomization.”\nICRA, 2018.\n[4] Nataniel Ruiz, et al.\n“Learning to Simulate.”\nICLR 2019\n[5] OpenAI.\n“Learning Dexterous In-Hand Manipulation.”\narXiv:1808.00177 (2018).\n[6] OpenAI Blog.\n“Learning dexterity”\nJuly 30, 2018.\n[7] Quan Vuong, et al.\n“How to pick the domain randomization parameters for sim-to-real transfer of reinforcement learning policies?.”\narXiv:1903.11774 (2019).\n[8] Ekin D. Cubuk, et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv:1805.09501 (2018).\n[9] Wenhao Yu et al.\n“Policy Transfer with Strategy Optimization.”\nICLR 2019\n[10] Yevgen Chebotar et al.\n“Closing the Sim-to-Real Loop: Adapting Simulation Randomization with Real World Experience.”\nArxiv: 1810.05687 (2019).\n[11] Stephen James et al.\n“Sim-to-real via sim-to-sim: Data-efficient robotic grasping via randomized-to-canonical adaptation networks”\nCVPR 2019.\n[12] Bhairav Mehta et al.\n“Active Domain Randomization”\narXiv:1904.04762\n[13] Sergey Zakharov,et al.\n“DeceptionNet: Network-Driven Domain Randomization.”\narXiv:1904.02750 (2019).\n[14] Amlan Kar, et al.\n“Meta-Sim: Learning to Generate Synthetic Datasets.”\narXiv:1904.11621 (2019).\n[15] Aayush Prakash, et al.\n“Structured Domain Randomization: Bridging the Reality Gap by Context-Aware Synthetic Data.”\narXiv:1810.10093 (2018).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:23Z",
            "title": "Domain Randomization for Sim2Real Transfer | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/4ceb83900555/code/body-000.txt",
                "chars": 247,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.06537",
                "bytes": 2845918,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6324fd866141c7ac81b8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ee4f3b9eabf9f86e46ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201.pdf",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/02a398f494ca43a2a527.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00177",
                "bytes": 4590851,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2d8f25b91674702104bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.11774",
                "bytes": 105818,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/456e2e12a35a28b26012.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.02513",
                "bytes": 4665551,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/dfcff6ef3a5e91c549e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11621",
                "bytes": 8958676,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bc0e2f30c9a21cc6e1d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.10093",
                "bytes": 6349645,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/27ba817b06ce2c0c5b10.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.05687",
                "bytes": 5492359,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5666402555506394cf09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.07252",
                "bytes": 11102844,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/26f2a2363d7689f5c25a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.07004",
                "bytes": 9323587,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/4ca4d0d250c09511b628.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.07857",
                "bytes": 6383296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/87d69e708982a5473230.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.02750",
                "bytes": 1752490,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f677145e4aa91af88479.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04762",
                "bytes": 1973875,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7ab63dc695e0b6ed4be5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": true,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907.pdf",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/18370e0f757f8e708185.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/fb94fedd3ee15e2dbb9d.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20048,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/4ceb83900555/pages/source.html",
            "local_html": "attachments/4ceb83900555/pages/article.html",
            "body_base_path": "attachments/4ceb83900555/pages/",
            "body_markdown_path": "attachments/4ceb83900555/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.06537",
                "label": "Peng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06907",
                "label": "Tobin et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.04201.pdf",
                "label": "Sadeghi et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00177",
                "label": "OpenAI, 2018",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/embed/DKe8FumoD4E",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://arxiv.org/abs/1903.11774",
                "label": "Vuong, et al, 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://ai.google/research/pubs/pub45826",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.02513",
                "label": "Ruiz (2019)",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=H1g6osRcFQ",
                "label": "Yu et al, 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11621",
                "label": "Kar, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.10093",
                "label": "Prakash et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.05687",
                "label": "Chebotar et al, 2019",
                "type": "a"
              },
              {
                "href": "https://www.aaai.org/ocs/index.php/AAAI/AAAI10/paper/viewFile/1851/2264",
                "label": "relative entropy policy search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.07252",
                "label": "James et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.07004",
                "label": "cGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.07857",
                "label": "GraspGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.02750",
                "label": "Zakharov et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04762",
                "label": "Mehta et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "SVPG",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06907.pdf",
                "label": "“Domain randomization for transferring deep neural networks from simulation to the real world.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04201",
                "label": "“CAD2RL: Real single-image flight without a single real image.”",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=HJgkx2Aqt7",
                "label": "“Learning to Simulate.”",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/learning-dexterity/",
                "label": "“Learning dexterity”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
          "status": "ok",
          "article_id": "475f6d363978",
          "local_path": "series-follow/1602/repair/878d50dab98b4b51cc5c.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
              "bytes": 176077,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/22a9e6438726d336ffe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
              "bytes": 852559,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a036ff1cba89bd8ca177.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
              "bytes": 189886,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/18722c930cf5c497d7b4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
              "bytes": 234856,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/68fbdff3da3a7b692d3a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
              "bytes": 405820,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/41e54ee7ec562394ded4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
              "bytes": 147376,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d6536618f786cd88a98d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
              "bytes": 82152,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e6b375e7ba5a5bff8ba1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
              "bytes": 157138,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f21c72c925e425e2c413.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
              "bytes": 227348,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/20cc8fbcc63711039176.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
              "bytes": 307054,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/844cb0884d62492c8431.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
              "bytes": 380120,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2beee1783718ce1e1233.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
              "bytes": 136228,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/841034ba340426dcc42f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
              "bytes": 403536,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/608e700d91e7d97d213c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
              "bytes": 359761,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/740a0454d4525705f3c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
              "bytes": 100940,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c04d9fc97a4006715831.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
              "bytes": 138999,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ebfcd764d9e484649bd7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
              "bytes": 266480,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ea47ad327c3e525d7680.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
              "bytes": 247091,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4bfe6aecad730ed414c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
              "bytes": 128766,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dc1c1909a9278b076020.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
              "bytes": 352267,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f40298ff01af8fc9e4dc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
              "bytes": 127977,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2453003154b5219dd230.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
              "bytes": 89862,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/94f6d5d4f164d466c4fb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
              "bytes": 144054,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/827f8fb6a1866bbd0478.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
              "bytes": 191620,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f86a63f93973014347b7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
              "bytes": 582897,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/52ae3de20af990c921e3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Neural Architecture Search",
            "keywords": "NAS,架构搜索,自动ML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "publish_date": "2020-08",
            "corpus_stage": "预训练/SFT",
            "notes": "神经架构搜索综述",
            "id": "475f6d363978",
            "collected_at": "2026-10-02T14:13:15",
            "title": "Neural Architecture Search | Lil'Log",
            "body_markdown": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.\nAutomatically learning and evolving network topologies is not a new idea (\nStanley & Miikkulainen, 2002\n). In recent years, the pioneering work by\nZoph & Le 2017\nand\nBaker et al. 2017\nhas attracted a lot of attention into the field of Neural Architecture Search (NAS), leading to many interesting ideas for better, faster and more cost-efficient NAS methods.\nAs I started looking into NAS, I found this nice survey very helpful by\nElsken, et al 2019\n. They characterize NAS as a system with three major components, which is clean & concise, and also commonly adopted in other NAS papers.\nSearch space\n: The NAS search space defines a set of operations (e.g. convolution, fully-connected, pooling) and how operations can be connected to form valid network architectures. The design of search space usually involves human expertise, as well as unavoidably human biases.\nSearch algorithm\n: A NAS search algorithm samples a population of network architecture candidates. It receives the child model performance metrics as rewards (e.g. high accuracy, low latency) and optimizes to generate high-performance architecture candidates.\nEvaluation strategy\n: We need to measure, estimate, or predict the performance of a large number of proposed child models in order to obtain feedback for the search algorithm to learn. The process of candidate evaluation could be very expensive and many new methods have been proposed to save time or computation resources.\nThree main components of Neural Architecture Search (NAS) models.  (Image source:\nElsken, et al. 2019\nwith customized annotation in red)\nSearch Space\n#\nThe NAS search space defines a set of basic network operations and how operations can be connected to construct valid network architectures.\nSequential Layer-wise Operations\n#\nThe most naive way to design the search space for neural network architectures is to depict network topologies, either CNN or RNN, with a list of\nsequential layer-wise operations\n, as seen in the early work of\nZoph & Le 2017\n&\nBaker et al. 2017\n. The serialization of network representation requires a decent amount of expert knowledge, since each operation is associated with different layer-specific parameters and such associations need to be hardcoded. For example, after predicting a\nconv\nop, the model should output kernel size, stride size, etc; or after predicting an\nFC\nop, we need to see the number of units as the next prediction.\n(Top) A sequential representation of CNN. (Bottom) A sequential representation of the tree structure of a recurrent cell. (Image source:\nZoph & Le 2017\n)\nTo make sure the generated architecture is valid, additional rules might be needed (\nZoph & Le 2017\n):\nIf a layer is not connected to any input layer then it is used as the input layer;\nAt the final layer, take all layer outputs that have not been connected and concatenate them;\nIf one layer has many input layers, then all input layers are concatenated in the depth dimension;\nIf input layers to be concatenated have different sizes, we pad the small layers with zeros so that the concatenated layers have the same sizes.\nThe skip connection can be predicted as well, using an\nattention\n-style mechanism. At layer $i$ , an anchor point is added with $i−1$ content-based sigmoids to indicate which of the previous layers to be connected. Each sigmoid takes as input the hidden states of the current node $h_i$ and $i-1$ previous nodes $h_j, j=1, \\dots, i-1$ .\n$$\nP(\\text{Layer j is an input to layer i}) = \\text{sigmoid}(v^\\top \\tanh(\\mathbf{W}_\\text{prev} h_j + \\mathbf{W}_\\text{curr} h_i))\n$$\nThe sequential search space has a lot of representation power, but it is very large and consumes a ton of computation resources to exhaustively cover the search space. In the experiments by\nZoph & Le 2017\n, they were running 800 GPUs in parallel for 28 days and\nBaker et al. 2017\nrestricted the search space to contain at most 2\nFC\nlayers.\nCell-based Representation\n#\nInspired by the design of using repeated modules in successful vision model architectures (e.g. Inception, ResNet), the\nNASNet search space\n(\nZoph et al. 2018\n) defines the architecture of a conv net as the same cell getting repeated multiple times and each cell contains several operations predicted by the NAS algorithm. A well-designed cell module enables transferability between datasets. It is also easy to scale down or up the model size by adjusting the number of cell repeats.\nPrecisely, the NASNet search space learns two types of cells for network construction:\nNormal Cell\n: The input and output feature maps have the same dimension.\nReduction Cell\n: The output feature map has its width and height reduced by half.\nThe NASNet search space constrains the architecture as a repeated stack of cells. The cell architecture is optimized via NAS algorithms. (Image source:\nZoph et al. 2018\n)\nThe predictions for each cell are grouped into $B$ blocks ($B=5$ in the NASNet paper), where each block has 5 prediction steps made by 5 distinct softmax classifiers corresponding to discrete choices of the elements of a block. Note that the NASNet search space does not have residual connections between cells and the model only learns skip connections on their own within blocks.\n(a) Each cell consists of $B$ blocks and each block is predicted by 5 discrete decisions. (b) An concrete example of what operations can be chosen in each decision step.\nDuring the experiments, they discovered that a modified version of\nDropPath\n, named\nScheduledDropPath\n, significantly improves the final performance of NASNet experiments. DropPath stochastically drops out paths (i.e. edges with operations attached in NASNet) with a fixed probability. ScheduledDropPath is DropPath with a linearly increasing probability of path dropping during training time.\nElsken, et al (2019)\npoint out three major advantages of the NASNet search space:\nThe search space size is reduced drastically;\nThe\nmotif\n-based architecture can be more easily transferred to different datasets.\nIt demonstrates a strong proof of a useful design pattern of repeatedly stacking modules in architecture engineering. For example, we can build strong models by stacking residual blocks in CNN or stacking multi-headed attention blocks in Transformer.\nHierarchical Structure\n#\nTo take advantage of already discovered well-designed network\nmotifs\n, the NAS search space can be constrained as a hierarchical structure, as in\nHierarchical NAS\n(\nHNAS\n; (\nLiu et al 2017\n)). It starts with a small set of primitives, including individual operations like convolution operation, pooling, identity, etc. Then small sub-graphs (or “motifs”) that consist of primitive operations are recursively used to form higher-level computation graphs.\nA computation motif at level $\\ell=1, \\dots, L$ can be represented by $(G^{(\\ell)}, \\mathcal{O}^{(\\ell)})$, where:\n$\\mathcal{O}^{(\\ell)}$ is a set of operations, $\\mathcal{O}^{(\\ell)} = \\{ o^{(\\ell)}_1, o^{(\\ell)}_2, \\dots \\}$\n$G^{(\\ell)}$ is an adjacency matrix, where the entry $G_{ij}=k$ indicates that operation $o^{(\\ell)}_k$ is placed between node $i$ and $j$. The node indices follow\ntopological ordering\nin DAG, where the index $1$ is the source and the maximal index is the sink node.\n(Top) Three level-1 primitive operations are composed into a level-2 motif. (Bottom) Three level-2 motifs are plugged into a base network structure and assembled into a level-3 motif. (Image source:\nLiu et al 2017\n)\nTo build a network according to the hierarchical structure, we start from the lowest level $\\ell=1$ and recursively define the $m$-th motif operation at level $\\ell$ as\n$$\no^{(\\ell)}_m = \\text{assemble}\\Big( G_m^{(\\ell)}, \\mathcal{O}^{(\\ell-1)} \\Big)\n$$\nA hierarchical representation becomes $\\Big( \\big\\{ \\{ G_m^{(\\ell)} \\}_{m=1}^{M_\\ell} \\big\\}_{\\ell=2}^L, \\mathcal{O}^{(1)} \\Big), \\forall \\ell=2, \\dots, L$, where $\\mathcal{O}^{(1)}$ contains a set of primitive operations.\nThe $\\text{assemble}()$ process is equivalent to sequentially compute the feature map of node $i$ by aggregating all the feature maps of its predecessor node $j$ following the topological ordering:\n$$\nx_i = \\text{merge} \\big[ \\{ o^{(\\ell)}_{G^{(\\ell)}_{ij}}(x_j) \\}_{j < i} \\big], i = 2, \\dots, \\vert G^{(\\ell)} \\vert\n$$\nwhere $\\text{merge}[]$ is implemented as depth-wise concatenation in the\npaper\n.\nSame as NASNet, experiments in\nLiu et al (2017)\nfocused on discovering good cell architecture within a predefined “macro” structure with repeated modules. They showed that the power of simple search methods (e.g. random search or evolutionary algorithms) can be substantially enhanced using well-designed search spaces.\nCai et al (2018b)\npropose a tree-structure search space using path-level network transformation. Each node in a tree structure defines an\nallocation\nscheme for splitting inputs for child nodes and a\nmerge\nscheme for combining results from child nodes. The path-level network transformation allows replacing a single layer with a multi-branch motif if its corresponding merge scheme is add or concat.\nAn illustration of transforming a single layer to a tree-structured motif via path-level transformation operations. (Image source:\nCai et al. 2018b\n)\nMemory-bank Representation\n#\nA memory-bank representation of feed-forward networks is proposed by\nBrock et al. (2017)\nin\nSMASH\n. Instead of a graph of operations, they view a neural network as a system with multiple memory blocks which can read and write. Each layer operation is designed to: (1) read from a subset of memory blocks; (2) computes results; finally (3) write the results into another subset of blocks. For example, in a sequential model, a single memory block would get read and overwritten consistently.\nMemory-bank representation of several popular network architecture blocks. (Image source:\nBrock et al. 2017\n)\nSearch Algorithms\n#\nNAS search algorithms sample a population of child networks. It receives the child models’ performance metrics as rewards and learns to generate high-performance architecture candidates. You may a lot in common with the field of hyperparameter search.\nRandom Search\n#\nRandom search is the most naive baseline. It samples a valid architecture candidate from the search space\nat random\nand no learning model is involved. Random search has proved to be quite useful in hyperparameter search (\nBergstra & Bengio 2012\n). With a well-designed search space, random search could be a very challenging baseline to beat.\nReinforcement Learning\n#\nThe initial design of\nNAS\n(\nZoph & Le 2017\n) involves a RL-based controller for proposing child model architectures for evaluation. The controller is implemented as a RNN, outputting a variable-length sequence of tokens used for configuring a network architecture.\nA high level overview of NAS, containing a RNN controller and a pipeline for evaluating child models. (Image source:\nZoph & Le 2017\n)\nThe controller is trained as a\nRL task\nusing\nREINFORCE\n.\nAction space\n: The action space is a list of tokens for defining a child network predicted by the controller (See more in the above\nsection\n). The controller outputs\naction\n, $a_{1:T}$, where $T$ is the total number of tokens.\nReward\n: The accuracy of a child network that can be achieved at convergence is the reward for training the controller, $R$.\nLoss\n: NAS optimizes the controller parameters $\\theta$ with a REINFORCE loss. We want to maximize the expected reward (high accuracy) with the gradient as follows. The nice thing here with policy gradient is that it works even when the reward is non-differentiable.\n$$\n\\nabla_{\\theta} J(\\theta) = \\sum_{t=1}^T \\mathbb{E}[\\nabla_{\\theta} \\log P(a_t \\vert a_{1:(t-1)}; \\theta) R ]\n$$\nMetaQNN\n(\nBaker et al. 2017\n) trains an agent to sequentially choose CNN layers using\nQ-learning\nwith an\n$\\epsilon$-greedy\nexploration strategy and experience replay. The reward is the validation accuracy as well.\n$$\nQ^{(t+1)}(s_t,  a_t) = (1 - \\alpha)Q^{(t)}(s_t, a_t) + \\alpha (R_t + \\gamma \\max_{a \\in \\mathcal{A}} Q^{(t)}(s_{t+1},  a'))\n$$\nwhere a state $s_t$ is a tuple of layer operation and related parameters. An action $a$ determines the connectivity between operations. The Q-value is proportional to how confident we are in two connected operations leading to high accuracy.\nOverview of MetaQNN - designing CNN models with Q-Learning. (Image source:\nBaker et al. 2017\n)\nEvolutionary Algorithms\n#\nNEAT\n(short for\nNeuroEvolution of Augmenting Topologies\n) is an approach for evolving neural network topologies with\ngenetic algorithm (GA)\n, proposed by\nStanley & Miikkulainen\nin 2002. NEAT evolves both connection weights and network topology together. Each gene encodes the full information for configuring a network, including node weights and edges. The population grows by applying mutation of both weights and connections, as well as crossover between two parent genes. For more in neuroevolution, please refer to the in-depth\nsurvey\nby Stanley et al. (2019).\nMutations in the NEAT algorithm. (Image source: Fig 3 & 4 in\nStanley & Miikkulainen, 2002\n)\nReal et al. (2018)\nadopt the evolutionary algorithms (EA) as a way to search for high-performance network architectures, named\nAmoebaNet\n. They apply the\ntournament selection\nmethod, which at each iteration picks a best candidate out of a random set of samples and places its mutated offspring back into the population. When the tournament size is $1$, it is equivalent to random selection.\nAmoebaNet modified the tournament selection to favor\nyounger\ngenotypes and always discard the oldest models within each cycle. Such an approach, named\naging evolution\n, allows AmoebaNet to cover and explore more search space, rather than to narrow down on good performance models too early.\nPrecisely, in every cycle of the tournament selection with aging regularization (See Figure 11):\nSample $S$ models from the population and the one with highest accuracy is chosen as\nparent\n.\nA\nchild\nmodel is produced by mutating\nparent\n.\nThen the child model is trained, evaluated and added back into the population.\nThe oldest model is removed from the population.\nThe algorithm of aging evolution. (Image source:\nReal et al. 2018\n)\nTwo types of mutations are applied:\nHidden state mutation\n: randomly chooses a pairwise combination and rewires a random end such that there is no loop in the graph.\nOperation mutation\n: randomly replaces an existing operation with a random one.\nTwo types of mutations in AmoebaNet. (Image source:\nReal et al. 2018\n)\nIn their experiments, EA and RL work equally well in terms of the final validation accuracy, but EA has better anytime performance and is able to find smaller models. Here using EA in NAS is still expensive in terms of computation, as each experiment took 7 days with 450 GPUs.\nHNAS\n(\nLiu et al 2017\n) also employs the evolutionary algorithms (the original tournament selection) as their search strategy. In the\nhierarchical structure\nsearch space, each edge is an operation. Thus genotype mutation in their experiments is applied by replacing a random edge with a different operation. The replacement set includes an\nnone\nop, so it can alter, remove and add an edge. The initial set of genotypes is created by applying a large number of random mutations on “trivial” motifs (all identity mappings).\nProgressive Decision Process\n#\nConstructing a model architecture is a sequential process. Every additional operator or layer brings extra complexity. If we guide the search model to start the investigation from simple models and gradually evolve to more complex architectures, it is like to introduce\n“curriculum”\ninto the search model’s learning process.\nProgressive NAS\n(\nPNAS\n;\nLiu, et al 2018\n) frames the problem of NAS as a progressive procedure for searching models of increasing complexity. Instead of RL or EA, PNAS adopts a Sequential Model-based Bayesian Optimization (SMBO) as the search strategy. PNAS works similar to A* search, as it searches for models from simple to hard while simultaneously learning a surrogate function to guide the search.\nA* search algorithm\n(“best-first search”) is a popular algorithm for path finding. The problem is framed as finding a path of smallest cost from a specific starting node to a given target node in a weighted graph. At each iteration, A* finds a path to extend by minimizing: $f(n)=g(n)+h(n)$, where $n$ is the next node, $g(n)$ is the cost from start to $n$, and $h(n)$ is the heuristic function that estimates the minimum cost of going from node $n$ to the goal.\nPNAS uses the\nNASNet\nsearch space. Each block is specified as a 5-element tuple and PNAS only considers the element-wise addition as the step 5 combination operator, no concatenation. Differently, instead of setting the number of blocks $B$ at a fixed number, PNAS starts with $B=1$, a model with only one block in a cell, and gradually increases $B$.\nThe performance on a validation set is used as feedback to train a\nsurrogate\nmodel for\npredicting\nthe performance of novel architectures. With this predictor, we can thus decide which models should be prioritized to be evaluated next. Since the performance predictor should be able to handle various-sized inputs, accuracy, and sample-efficient, they ended up using an RNN model.\nThe algorithm of Progressive NAS. (Image source:\nLiu, et al 2018\n)\nGradient descent\n#\nUsing gradient descent to update the architecture search model requires an effort to make the process of choosing discrete operations differentiable. These approaches usually combine the learning of both architecture parameters and network weights together into one model. See more in the\nsection\non the\n“one-shot”\napproach.\nEvaluation Strategy\n#\nWe need to measure, estimate or predict the performance of every child model in order to obtain feedback for optimizing the search algorithm. The process of candidate evaluation could be very expensive and many new evaluation methods have been proposed to save time or computation. When evaluating a child model, we mostly care about its performance measured as accuracy on a validation set. Recent work has started looking into other factors of a model, such as model size and latency, as certain devices may have limitations on memory or demand fast response time.\nTraining from Scratch\n#\nThe most naive approach is to train every child network independently from scratch until\nconvergence\nand then measure its accuracy on a validation set (\nZoph & Le 2017\n). It provides solid performance numbers, but one complete train-converge-evaluate loop only generates a single data sample for training the RL controller (let alone RL is known to be sample-inefficient in general). Thus it is very expensive in terms of computation consumption.\nProxy Task Performance\n#\nThere are several approaches for using a proxy task performance as the performance estimator of a child network, which is generally cheaper and faster to calculate:\nTrain on a smaller dataset.\nTrain for fewer epochs.\nTrain and evaluate a down-scaled model in the search stage. For example, once a cell structure is learned, we can play with the number of cell repeats or scale up the number of filters (\nZoph et al. 2018\n).\nPredict the learning curve.\nBaker et al (2018)\nmodel the prediction of validation accuracies as a time-series regression problem. The features for the regression model ($\\nu$-support vector machine regressions; $\\nu$-SVR) include the early sequences of accuracy per epoch, architecture parameters, and hyperparameters.\nParameter Sharing\n#\nInstead of training every child model independently from scratch. You may ask, ok, what if we fabricate dependency between them and find a way to reuse weights? Some researchers succeeded to make such approaches work.\nInspired by\nNet2net\ntransformation,\nCai et al (2017)\nproposed\nEfficient Architecture Search\n(\nEAS\n). EAS sets up an RL agent, known as a meta-controller, to predict function-preserving network transformation so as to grow the network depth or layer width. Because the network is growing incrementally, the weights of previously validated networks can be\nreused\nfor further exploration. With inherited weights, newly constructed networks only need some light-weighted training.\nA meta-controller learns to generate\nnetwork transformation actions\ngiven the current network architecture, which is specified with a variable-length string. In order to handle architecture configuration of a variable length, the meta-controller is implemented as a bi-directional recurrent network. Multiple actor networks output different transformation decisions:\nNet2WiderNet\noperation allows to replace a layer with a wider layer, meaning more units for fully-connected layers, or more filters for convolutional layers, while preserving the functionality.\nNet2DeeperNet\noperation allows to insert a new layer that is initialized as adding an identity mapping between two layers so as to preserve the functionality.\nOverview of the RL based meta-controller in Efficient Architecture Search (NAS). After encoding the architecture configuration, it outputs net2net transformation actions through two separate actor networks. (Image source:\nCai et al 2017\n)\nWith similar motivation,\nEfficient NAS\n(\nENAS\n;\nPham et al. 2018\n) speeds up NAS (i.e. 1000x less) by aggressively sharing parameters among child models. The core motivation behind ENAS is the observation that all of the sampled architecture graphs can be viewed as\nsub-graphs\nof a larger\nsupergraph\n. All the child networks are sharing weights of this supergraph.\n(Left) The graph represents the entire search space for a 4-node recurrent cell, but only connections in red are active. (Middle) An example of how the left active sub-graph can be translated into a child model architecture. (Right) The network parameters produced by an RNN controller for the architecture in the middle. (Image source:\nPham et al. 2018\n)\nENAS alternates between training the shared model weights $\\omega$ and training the controller $\\theta$:\nThe parameters of the controller LSTM $\\theta$ are trained with\nREINFORCE\n, where the reward $R(\\mathbf{m}, \\omega)$ is computed on the validation set.\nThe shared parameters of the child models $\\omega$ are trained with standard supervised learning loss. Note that different operators associated with the same node in the supergraph would have their own distinct parameters.\nPrediction-Based\n#\nA routine child model evaluation loop is to update model weights via standard gradient descent. SMASH (\nBrock et al. 2017\n) proposes a different and interesting idea:\nCan we predict the model weights directly based on the network architecture parameters?\nThey employ a\nHyperNet\n(\nHa et al 2016\n) to directly generate the weights of a model conditioned on an encoding of its architecture configuration. Then the model with HyperNet-generated weights is validated directly. Note that we don’t need extra training for every child model but we do need to train the HyperNet.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nThe correlation between model performance with SMASH-generated weights and true validation errors suggests that predicted weights can be used for model comparison, to some extent. We do need a HyperNet of large enough capacity, as the correlation would be corrupted if the HyperNet model is too small compared to the child model size.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nSMASH can be viewed as another way to implement the idea of\nparameter sharing\n. One problem of SMASH as pointed out by\nPham et al. (2018)\nis: The usage of HyperNet restricts the weights of SMASH child models to a\nlow-rank space\n, because weights are generated via tensor products. In comparison,\nENAS\nhas no such restrictions.\nOne-Shot Approach: Search + Evaluation\n#\nRunning search & evaluation independently for a large population of child models is expensive. We have seen promising approaches like\nBrock et al. (2017)\nor\nPham et al. (2018)\n, where training a single model is enough for emulating any child model in the search space.\nThe\none-shot\narchitecture search extends the idea of weight sharing and further combines the learning of architecture generation together with weight parameters. The following approaches all treat child architectures as different sub-graphs of a supergraph with shared weights between common edges in the supergraph.\nBender et al (2018)\nconstruct a single large over-parameterized network, known as the\nOne-Shot model\n, such that it contains every possible operation in the search space. With\nScheduledDropPath\n(the dropout rate is increased over time, which is $r^{1/k}$ at the end of training, where $0 < r < 1$ is a hyperparam and $k$ is the number of incoming paths) and some carefully designed tricks (e.g. ghost batch normalization, L2 regularization only on the active architecture), the training of such a giant model can be stabilized enough and used for evaluating any child model sampled from the supergraph.\nThe architecture of the One-Shot model in\nBender et al 2018\n. Each cell has $N$ choice blocks and each choice block can select up to 2 operations. Solid edges are used in every architecture, where dash lines are optional. (Image source:\nBender et al 2018\n)\nOnce the one-shot model is trained, it is used for evaluating the performance of many different architectures sampled at random by zeroing out or removing some operations. This sampling process can be replaced by RL or evolution.\nThey observed that the difference between the accuracy measured with the one-shot model and the accuracy of the same architecture after a small fine-tuning could be very large. Their hypothesis is that the one-shot model automatically learns to focus on the\nmost useful\noperations in the network and comes to\nrely on\nthese operations when they are available. Thus zeroing out useful operations lead to big reduction in model accuracy, while removing less important components only causes a small impact — Therefore, we see a larger variance in scores when using the one-shot model for evaluation.\nA stratified sample of models with different one-shot model accuracy versus their true validation accuracy as stand-alone models. (Image source:\nBender et al 2018\n)\nClearly designing such a search graph is not a trivial task, but it demonstrates a strong potential with the one-shot approach. It works well with only gradient descent and no additional algorithm like RL or EA is a must.\nSome believe that one main cause for inefficiency in NAS is to treat the architecture search as a\nblack-box optimization\nand thus we fall into methods like RL, evolution, SMBO, etc. If we shift to rely on standard gradient descent, we could potentially make the search process more effectively. As a result,\nLiu et al (2019)\npropose\nDifferentiable Architecture Search\n(\nDARTS\n). DARTS introduces a continuous relaxation on each path in the search supergraph, making it possible to jointly train architecture parameters and weights via gradient descent.\nLet’s use the directed acyclic graph (DAG) representation here. A cell is a DAG consisting of a topologically ordered sequence of $N$ nodes. Each node has a latent representation $x_i$ to be learned. Each edge $(i, j)$ is tied to some operation $o^{(i,j)} \\in \\mathcal{O}$ that transforms $x_j$ to compose $x_i$:\n$$\nx_i = \\sum_{j < i} o^{(i,j)}(x_j)\n$$\nTo make the search space continuous, DARTS relaxes the categorical choice of a particular operation as a softmax over all the operations and the task of architecture search is reduced to learn a set of mixing probabilities $\\alpha = \\{ \\alpha^{(i,j)} \\}$.\n$$\n\\bar{o}^{(i,j)}(x) = \\sum_{o\\in\\mathcal{O}} \\frac{\\exp(\\alpha_{ij}^o)}{\\sum_{o'\\in\\mathcal{O}} \\exp(\\alpha^{o'}_{ij})} o(x)\n$$\nwhere $\\alpha_{ij}$ is a vector of dimension $\\vert \\mathcal{O} \\vert$, containing weights between nodes $i$ and $j$ over different operations.\nThe bilevel optimization exists as we want to optimize both the network weights $w$ and the architecture representation $\\alpha$:\n$$\n\\begin{aligned}\n\\min_\\alpha & \\mathcal{L}_\\text{validate} (w^*(\\alpha), \\alpha) \\\\\n\\text{s.t.} & w^*(\\alpha) = \\arg\\min_w \\mathcal{L}_\\text{train} (w, \\alpha)\n\\end{aligned}\n$$\nAt step $k$, given the current architecture parameters $\\alpha_{k−1}$, we first optimize weights $w_k$ by moving $w_{k−1}$ in the direction of minimizing the training loss $\\mathcal{L}_\\text{train}(w_{k−1}, \\alpha_{k−1})$ with a learning rate $\\xi$. Next, while keeping the newly updated weights $w_k$ fixed, we update the mixing probabilities so as to minimize the validation loss\nafter a single step of gradient descent w.r.t. the weights\n:\n$$\nJ_\\alpha = \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1})\n$$\nThe motivation here is that we want to find an architecture with a low validation loss when its weights are optimized by gradient descent and the one-step unrolled weights serve as the\nsurrogate\nfor $w^∗(\\alpha)$.\nSide note: Earlier we have seen similar formulation in\nMAML\nwhere the two-step optimization happens between task losses and the meta-learner update, as well as framing\nDomain Randomization\nas a bilevel optimization for better transfer in the real environment.\nAn illustration of how DARTS applies continuous relaxation on edges in DAG supergraph and identifies the final model. (Image source:\nLiu et al 2019\n)\n$$\n\\begin{aligned}\n\\text{Let }w'_k &= w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}) & \\\\\nJ_\\alpha &= \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1}) = \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) & \\\\\n\\nabla_\\alpha J_\\alpha \n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\nabla_\\alpha \\alpha_{k-1} + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1})\\nabla_\\alpha w'_k & \\\\& \\text{; multivariable chain rule}\\\\\n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\big( - \\xi \\color{red}{\\nabla^2_{\\alpha, w} \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1})} \\big) & \\\\\n&\\approx \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) - \\xi \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\color{red}{\\frac{\\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^+, \\alpha_{k-1}) - \\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^-, \\alpha_{k-1}) }{2\\epsilon}} & \\\\\n& \\text{; apply numerical differentiation approximation}\n\\end{aligned}\n$$\nwhere the red part is using numerical differentiation approximation where $w_k^+ = w_k + \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$ and $w_k^- = w_k - \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$.\nThe algorithm overview of DARTS. (Image source:\nLiu et al 2019\n)\nAs another idea similar to DARTS, Stochastic NAS (\nXie et al., 2019\n) applies a continuous relaxation by employing the concrete distribution (CONCRETE = CONtinuous relaxations of disCRETE random variables;\nMaddison et al 2017\n) and reparametrization tricks. The goal is same as DARTS, to make the discrete distribution differentiable and thus enable optimization by gradient descent.\nDARTS is able to greatly reduce the cost of GPU hours. Their experiments for searching for CNN cells have $N=7$ and only took 1.5 days with a single GPU. However, it suffers from the high GPU memory consumption issue due to its continuous representation of network architecture. In order to fit the model into the memory of a single GPU, they picked a small $N$.\nTo constrain the GPU memory consumption,\nProxylessNAS\n(\nCai et al., 2019\n) views NAS as a path-level pruning process in DAG and binarizes the architecture parameters to force only one path to be active between two nodes at a time. The probabilities for an edge being either masked out or not are then learned by sampling a few binarized architectures and using\nBinaryConnect\n(\nCourbariaux et al., 2015\n) to update the corresponding probabilities. ProxylessNAS demonstrates a strong connection between NAS and model compression. By using path-level compression, it is able to save memory consumption by one order of magnitude.\nLet’s continue with the graph representation. In a DAG adjacency matrix $G$ where $G_{ij}$ represents an edge between node $i$ and $j$ and its value can be chosen from the set of $\\vert \\mathcal{O} \\vert$ candidate primitive operations, $\\mathcal{O} = \\{ o_1, \\dots \\}$. The One-Shot model, DARTS and ProxylessNAS all consider each edge as a mixture of operations, $m_\\mathcal{O}$, but with different tweaks.\nIn One-Shot, $m_\\mathcal{O}(x)$ is the sum of all the operations. In DARTS, it is a weighted sum where weights are softmax over a real-valued architecture weighting vector $\\alpha$ of length $\\vert \\mathcal{O} \\vert$. ProxylessNAS transforms the softmax probabilities of $\\alpha$ into a binary gate and uses the binary gate to keep only one operation active at a time.\n$$\n\\begin{aligned}\nm^\\text{one-shot}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} o_i(x) \\\\\nm^\\text{DARTS}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} p_i o_i(x) = \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\exp(\\alpha_i)}{\\sum_j \\exp(\\alpha_j)} o_i(x) \\\\\nm^\\text{binary}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} g_i o_i(x) = \\begin{cases}\no_1(x) & \\text{with probability }p_1, \\\\\n\\dots &\\\\\no_{\\vert \\mathcal{O} \\vert}(x) & \\text{with probability }p_{\\vert \\mathcal{O} \\vert}\n\\end{cases} \\\\\n\\text{ where } g &= \\text{binarize}(p_1, \\dots, p_N) = \\begin{cases}\n[1, 0, \\dots, 0] & \\text{with probability }p_1, \\\\\n\\dots & \\\\\n[0, 0, \\dots, 1] & \\text{with probability }p_N. \\\\\n\\end{cases}\n\\end{aligned}\n$$\nProxylessNAS has two training steps running alternatively. (Image source:\nCai et al., 2019\n)\nProxylessNAS runs two training steps alternatively:\nWhen training weight parameters $w$, it freezes the architecture parameters $\\alpha$ and stochastically samples binary gates $g$ according to the above $m^\\text{binary}_\\mathcal{O}(x)$. The weight parameters can be updated with standard gradient descent.\nWhen training architecture parameters $\\alpha$, it freezes $w$, resets the binary gates and then updates $\\alpha$ on the validation set. Following the idea of\nBinaryConnect\n,  the gradient w.r.t. architecture parameters can be approximately estimated using $\\partial \\mathcal{L} / \\partial g_i$ in replacement for $\\partial \\mathcal{L} / \\partial p_i$:\n$$\n\\begin{aligned}\n\\frac{\\partial \\mathcal{L}}{\\partial \\alpha_i} \n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial p_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n\\approx \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial \\frac{e^{\\alpha_j}}{\\sum_k e^{\\alpha_k}}}{\\partial \\alpha_i} \\\\\n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\sum_k e^{\\alpha_k} (\\mathbf{1}_{i=j} e^{\\alpha_j}) - e^{\\alpha_j} e^{\\alpha_i} }{(\\sum_k e^{\\alpha_k})^2}\n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} p_j (\\mathbf{1}_{i=j} -p_i)\n\\end{aligned}\n$$\nInstead of BinaryConnect, REINFORCE can also be used for parameter updates with the goal for maximizing the reward, while no RNN meta-controller is involved.\nComputing $\\partial \\mathcal{L} / \\partial g_i$ needs to calculate and store $o_i(x)$, which requires $\\vert \\mathcal{O} \\vert$ times GPU memory. To resolve this issue, they factorize the task of choosing one path out of $N$ into multiple binary selection tasks (Intuition: “if a path is the best choice, it should be better than any other path”). At every update step, only two paths are sampled while others are masked. These two selected paths are updated according to the above equation and then scaled properly so that other path weights are unchanged. After this process, one of the sampled paths is enhanced (path weight increases) and the other is attenuated (path weight decreases), while all other paths stay unaltered.\nBesides accuracy, ProxylessNAS also considers\nlatency\nas an important metric to optimize, as different devices might have very different requirements on inference time latency (e.g. GPU, CPU, mobile). To make latency differentiable, they model latency as a continuous function of the network dimensions. The expected latency of a mixed operation can be written as $\\mathbb{E}[\\text{latency}] = \\sum_j p_j F(o_j)$, where $F(.)$ is a latency prediction model:\nAdd a differentiable latency loss into the training of ProxylessNAS.  (Image source:\nCai et al., 2019\n)\nWhat’s the Future?\n#\nSo far we have seen many interesting new ideas on automating the network architecture engineering through neural architecture search and many have achieved very impressive performance. However, it is a bit hard to do inference on\nwhy\nsome architecture work well and how we can develop modules generalizable across tasks rather than being very dataset-specific.\nAs also noted in\nElsken, et al (2019)\n:\n“…, so far it provides little insights into why specific architectures work well and how similar the architectures derived in independent runs would be. Identifying common motifs, providing an understanding why those motifs are important for high performance, and investigating if these motifs generalize over different problems would be desirable.”\nIn the meantime, purely focusing on improvement over validation accuracy might not be enough (\nCai et al., 2019\n). Devices like mobile phones for daily usage in general have limited memory and computation power. While AI applications are on the way to affect our daily life, it is unavoidable to be more\ndevice-specific\n.\nAnother interesting investigation is to consider\nunlabelled dataset\nand\nself-supervised learning\nfor NAS. The size of labelled dataset is always limited and it is not easy to tell whether such a dataset has biases or big deviation from the real world data distribution.\nLiu et al (2020)\ndelve into the question\n“Can we find high-quality neural architecture without human-annotated labels?”\nand proposed a new setup called\nUnsupervised Neural Architecture Search\n(\nUnNAS\n). The quality of the architecture needs to be estimated in an unsupervised fashion during the search phase. The paper experimented with three unsupervised\npretext tasks\n: image rotation prediction, colorization, and solving the jigsaw puzzle.\nThey observed in a set of UnNAS experiments that:\nHigh rank correlation between supervised accuracy and pretext accuracy\non the same dataset\n. Typically the rank correlation is higher than 0.8, regardless of the dataset, the search space, and the pretext task.\nHigh rank correlation between supervised accuracy and pretext accuracy\nacross datasets\n.\nBetter pretext accuracy translates to better supervised accuracy.\nPerformance of UnNAS architecture is comparable to supervised counterparts, though not better yet.\nOne hypothesis is that the architecture quality is correlated with image statistics. Because CIFAR-10 and ImageNet are all on the natural images, they are comparable and the results are transferable. UnNAS could potentially enable a much larger amount of unlabelled data into the search phase which captures image statistics better.\nHyperparameter search is a long-standing topic in the ML community. And NAS automates architecture engineering. Gradually we are trying to automate processes in ML which usually demand a lot of human efforts. Taking even one more step further, is it possible to automatically discover ML algorithms?\nAutoML-Zero\n(\nReal et al 2020\n) investigates this idea. Using\naging evolutionary algorithms\n, AutoML-Zero automatically searches for whole ML algorithms using little restriction on the form with only simple mathematical operations as building blocks.\nIt learns three component functions. Each function only adopts very basic operations.\nSetup\n: initialize memory variables (weights).\nLearn\n: modify memory variables\nPredict\n: make a prediction from an input $x$.\nAlgorithm evaluation on one task (Image source:\nReal et al 2020\n)\nThree types of operations are considered when mutating a parent genotype:\nInsert a random instruction or remove an instruction at a random location in a component function;\nRandomize all the instructions in a component function;\nModify one of the arguments of an instruction by replacing it with a random choice (e.g. “swap the output address” or “change the value of a constant”)\nAn illustration of evolutionary progress on projected binary CIFAR-10 with example code. (Image source:\nReal et al 2020\n)\nAppendix: Summary of NAS Papers\n#\nModel name\nSearch space\nSearch algorithms\nChild model evaluation\nNEAT (2002)\n-\nEvolution (Genetic algorithm)\n-\nNAS (2017)\nSequential layer-wise ops\nRL (REINFORCE)\nTrain from scratch until convergence\nMetaQNN (2017)\nSequential layer-wise ops\nRL (Q-learning with $\\epsilon$-greedy)\nTrain for 20 epochs\nHNAS (2017)\nHierarchical structure\nEvolution (Tournament selection)\nTrain for a fixed number of iterations\nNASNet (2018)\nCell-based\nRL (PPO)\nTrain for 20 epochs\nAmoebaNet (2018)\nNASNet search space\nEvolution (Tournament selection with aging regularization)\nTrain for 25 epochs\nEAS (2018a)\nNetwork transformation\nRL (REINFORCE)\n2-stage training\nPNAS (2018)\nReduced version of NASNet search space\nSMBO; Progressive search for architectures of increasing complexity\nTrain for 20 epochs\nENAS (2018)\nBoth sequential and cell-based search space\nRL (REINFORCE)\nTrain one model with shared weights\nSMASH (2017)\nMemory-bank representation\nRandom search\nHyperNet predicts weights of evaluated architectures.\nOne-Shot (2018)\nAn over-parameterized one-shot model\nRandom search (zero out some paths at random)\nTrain the one-shot model\nDARTS (2019)\nNASNet search space\nGradient descent (Softmax weights over operations)\nProxylessNAS (2019)\nTree structure architecture\nGradient descent (BinaryConnect) or REINFORCE\nSNAS (2019)\nNASNet search space\nGradient descent (concrete distribution)\nCitation\n#\nCited as:\nWeng, Lilian. (Aug 2020). Neural architecture search. Lil’Log. https://lilianweng.github.io/posts/2020-08-06-nas/.\nOr\n@article{weng2020nas,\n  title   = \"Neural Architecture Search\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Aug\",\n  url     = \"https://lilianweng.github.io/posts/2020-08-06-nas/\"\n}\nReference\n#\n[1] Thomas Elsken, Jan Hendrik Metzen, Frank Hutter.\n“Neural Architecture Search: A Survey”\nJMLR 20 (2019) 1-21.\n[2] Kenneth O. Stanley, et al.\n“Designing neural networks through neuroevolution”\nNature Machine Intelligence volume 1, pages 24–35 (2019).\n[3] Kenneth O. Stanley & Risto Miikkulainen.\n“Evolving Neural Networks through Augmenting Topologies”\nEvolutionary Computation 10(2): 99-127 (2002).\n[4] Barret Zoph, Quoc V. Le.\n“Neural architecture search with reinforcement learning”\nICLR 2017.\n[5] Bowen Baker, et al.\n“Designing Neural Network Architectures using Reinforcement Learning”\nICLR 2017.\n[6] Bowen Baker, et al.\n“Accelerating neural architecture search using performance prediction”\nICLR Workshop 2018.\n[7] Barret Zoph, et al.\n“Learning transferable architectures for scalable image recognition”\nCVPR 2018.\n[8] Hanxiao Liu, et al.\n“Hierarchical representations for efficient architecture search.”\nICLR 2018.\n[9] Esteban Real, et al.\n“Regularized Evolution for Image Classifier Architecture Search”\narXiv:1802.01548 (2018).\n[10] Han Cai, et al. [“Efficient architecture search by network transformation”] AAAI 2018a.\n[11] Han Cai, et al.\n“Path-Level Network Transformation for Efficient Architecture Search”\nICML 2018b.\n[12] Han Cai, Ligeng Zhu & Song Han.\n“ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware”\nICLR 2019.\n[13] Chenxi Liu, et al.\n“Progressive neural architecture search”\nECCV 2018.\n[14] Hieu Pham, et al.\n“Efficient neural architecture search via parameter sharing”\nICML 2018.\n[15] Andrew Brock, et al.\n“SMASH: One-shot model architecture search through hypernetworks.”\nICLR 2018.\n[16] Gabriel Bender, et al.\n“Understanding and simplifying one-shot architecture search.”\nICML 2018.\n[17] Hanxiao Liu, Karen Simonyan, Yiming Yang.\n“DARTS: Differentiable Architecture Search”\nICLR 2019.\n[18] Sirui Xie, Hehui Zheng, Chunxiao Liu, Liang Lin.\n“SNAS: Stochastic Neural Architecture Search”\nICLR 2019.\n[19] Chenxi Liu et al.\n“Are Labels Necessary for Neural Architecture Search?”\nECCV 2020.\n[20] Esteban Real, et al.\n“AutoML-Zero: Evolving Machine Learning Algorithms From Scratch”\nICML 2020.",
            "metadata": {
              "title": "Neural Architecture Search | Lil'Log",
              "description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "keywords": "architecture, reinforcement-learning, evolution, auto-ML",
              "author": "Lilian Weng",
              "og:title": "Neural Architecture Search",
              "og:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
              "twitter:card": "summary",
              "twitter:title": "Neural Architecture Search",
              "twitter:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "article:section": "posts",
              "article:published_time": "2020-08-06T00:00:00+00:00",
              "article:modified_time": "2020-08-06T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/475f6d363978/code/body-000.txt",
                "chars": 234,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "bytes": 176077,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-22a9e6438726d336ffe1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "bytes": 852559,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-a036ff1cba89bd8ca177.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "bytes": 189886,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-18722c930cf5c497d7b4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "bytes": 234856,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-68fbdff3da3a7b692d3a.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "bytes": 405820,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-41e54ee7ec562394ded4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "bytes": 147376,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-d6536618f786cd88a98d.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "bytes": 82152,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-e6b375e7ba5a5bff8ba1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "bytes": 157138,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f21c72c925e425e2c413.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "bytes": 227348,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-20cc8fbcc63711039176.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "bytes": 307054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-844cb0884d62492c8431.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "bytes": 380120,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2beee1783718ce1e1233.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "bytes": 136228,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-841034ba340426dcc42f.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "bytes": 403536,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-608e700d91e7d97d213c.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "bytes": 359761,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-740a0454d4525705f3c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "bytes": 100940,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-c04d9fc97a4006715831.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "bytes": 138999,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ebfcd764d9e484649bd7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "bytes": 266480,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ea47ad327c3e525d7680.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "bytes": 247091,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-4bfe6aecad730ed414c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "bytes": 128766,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-dc1c1909a9278b076020.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "bytes": 352267,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f40298ff01af8fc9e4dc.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "bytes": 127977,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2453003154b5219dd230.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "bytes": 89862,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-94f6d5d4f164d466c4fb.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "bytes": 144054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-827f8fb6a1866bbd0478.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "bytes": 191620,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f86a63f93973014347b7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "bytes": 582897,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-52ae3de20af990c921e3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "label": "Stanley & Miikkulainen, 2002",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.01578",
                "label": "Zoph & Le 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02167",
                "label": "Baker et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.05377",
                "label": "Elsken, et al 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.07012",
                "label": "Zoph et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.07648",
                "label": "DropPath",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Network_motif",
                "label": "motif",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00436",
                "label": "Liu et al 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Topological_sorting",
                "label": "topological ordering",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.02639",
                "label": "Cai et al (2018b)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.05344",
                "label": "Brock et al. (2017)",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "label": "Bergstra & Bengio 2012",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Q-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$\\epsilon$-greedy",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Genetic_algorithm",
                "label": "genetic algorithm (GA)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/s42256-018-0006-z",
                "label": "survey",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01548",
                "label": "Real et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tournament_selection",
                "label": "tournament selection",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
                "label": "“curriculum”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.00559",
                "label": "Liu, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/A*_search_algorithm",
                "label": "A* search algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.10823",
                "label": "Baker et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05641",
                "label": "Net2net",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04873",
                "label": "Cai et al (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03268",
                "label": "Pham et al. 2018",
                "type": "a"
              },
              {
                "href": "https://blog.otoro.net/2016/09/28/hyper-networks/",
                "label": "HyperNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.09106",
                "label": "Ha et al 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "label": "Bender et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09055",
                "label": "Liu et al (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "Domain Randomization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.09926",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.00712",
                "label": "Maddison et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.00332",
                "label": "Cai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.00363",
                "label": "Courbariaux et al., 2015",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.12056",
                "label": "Liu et al (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.03384",
                "label": "Real et al 2020",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a.html",
                "label": "One-Shot (2018)",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:31Z",
            "source_url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "papers": [
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "bytes": 455683,
                "reused": false,
                "local_path": "papers/repair/805499a4b371ca736e62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01578",
                "bytes": 733204,
                "reused": false,
                "local_path": "papers/repair/a111656177a4c8876b48.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02167",
                "bytes": 2766423,
                "reused": false,
                "local_path": "papers/repair/760094c3d304751da217.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.05377",
                "bytes": 513920,
                "reused": false,
                "local_path": "papers/repair/97142d15c75389ec1783.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.07012",
                "bytes": 8223935,
                "reused": false,
                "local_path": "papers/repair/263d4aa0ef18300727e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.07648",
                "bytes": 301203,
                "reused": false,
                "local_path": "papers/repair/3c2d2df24de01e01fbd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00436",
                "bytes": 625718,
                "reused": false,
                "local_path": "papers/repair/eb6cf4cb96b16ab6e4ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.02639",
                "bytes": 4382572,
                "reused": false,
                "local_path": "papers/repair/680796c56d03bb0724c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05344",
                "bytes": 3204919,
                "reused": false,
                "local_path": "papers/repair/e88c3d4c693981e49fce.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "bytes": 728274,
                "reused": false,
                "local_path": "papers/repair/8a459dcd765c190d80b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01548",
                "bytes": 719617,
                "reused": false,
                "local_path": "papers/repair/65805c891aedf369ff37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.00559",
                "bytes": 1201540,
                "reused": false,
                "local_path": "papers/repair/609e6dc18e9ec4f12c8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.10823",
                "bytes": 696064,
                "reused": false,
                "local_path": "papers/repair/0fe98a08286c39292e71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05641",
                "bytes": 514031,
                "reused": false,
                "local_path": "papers/repair/92e6dc487fb58180dcc6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04873",
                "bytes": 1963936,
                "reused": false,
                "local_path": "papers/repair/ed8c0c59198f186976bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03268",
                "bytes": 437408,
                "reused": false,
                "local_path": "papers/repair/385bdb4f3e6008bec0cf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.09106",
                "bytes": 3125291,
                "reused": false,
                "local_path": "papers/repair/9a50e3e16a9ac5be3fd1.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "bytes": 608254,
                "reused": false,
                "local_path": "papers/repair/3a859646e6c029ea003e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09055",
                "bytes": 636787,
                "reused": false,
                "local_path": "papers/repair/40e69415044afc05d599.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.09926",
                "bytes": 711882,
                "reused": false,
                "local_path": "papers/repair/35befec5995034ad4bfd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.00712",
                "bytes": 858710,
                "reused": false,
                "local_path": "papers/repair/27fa0ebf79e9f6aa3132.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.00332",
                "bytes": 2325253,
                "reused": false,
                "local_path": "papers/repair/61f9a157fe986680a3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.00363",
                "bytes": 1297364,
                "reused": false,
                "local_path": "papers/repair/1bc5305341828713b8ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.12056",
                "bytes": 1315976,
                "reused": false,
                "local_path": "papers/repair/05573f22fe71d2abefb7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.03384",
                "bytes": 1781766,
                "reused": false,
                "local_path": "papers/repair/daabc7af10551ec97ee1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 44902,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/475f6d363978/pages/source.html",
            "local_html": "attachments/475f6d363978/pages/article.html",
            "body_base_path": "attachments/475f6d363978/pages/",
            "body_markdown_path": "attachments/475f6d363978/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
          "status": "ok",
          "article_id": "45444954e783",
          "local_path": "series-follow/1602/repair/0adb702ae2c07335adbf.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
              "bytes": 221077,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/aa28a4cc1b3516c1be46.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
              "bytes": 157401,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4199969ec35e7360ae98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
              "bytes": 101972,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/95c24c614030b59aff01.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
              "bytes": 447186,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c2ebec0990753f6d5a87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
              "bytes": 736874,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f32623608491cb056216.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
              "bytes": 529052,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/54028801a0ddfc354538.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
              "bytes": 86758,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/501aa5d6dea1582e9385.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
              "bytes": 32150,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7301ab34ef06aa0e487d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
              "bytes": 313647,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bacb4aa725276c994c68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
              "bytes": 3106088,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f670e3a31b7940e1d8ef.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "From GAN to WGAN",
            "keywords": "GAN,WGAN,生成模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "publish_date": "2017-08",
            "corpus_stage": "预训练/SFT",
            "notes": "GAN到WGAN的演进综述",
            "id": "45444954e783",
            "collected_at": "2026-10-02T14:13:27",
            "title": "From GAN to WGAN | Lil'Log",
            "body_markdown": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in\nKorean\n!]\n[Updated on 2019-04-18: this post is also available on\narXiv\n.]\nGenerative adversarial network\n(GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.\nHere I would like to explain the maths behind the generative adversarial network framework,  why it is hard to be trained, and finally introduce a modified version of GAN intended to solve the training difficulties.\nKullback–Leibler and Jensen–Shannon Divergence\n#\nBefore we start examining GANs closely, let us first review two metrics for quantifying the similarity between two probability distributions.\n(1)\nKL (Kullback–Leibler) divergence\nmeasures how one probability distribution $p$ diverges from a second expected probability distribution $q$.\n$$\nD_{KL}(p \\| q) = \\int_x p(x) \\log \\frac{p(x)}{q(x)} dx\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nIt is noticeable according to the formula that KL divergence is asymmetric. In cases where $p(x)$ is close to zero, but $q(x)$ is significantly non-zero, the $q$’s effect is disregarded. It could cause buggy results when we just want to measure the similarity between two equally important distributions.\n(2)\nJensen–Shannon Divergence\nis another measure of similarity between two probability distributions, bounded by $[0, 1]$. JS divergence is symmetric (yay!) and more smooth. Check this\nQuora post\nif you are interested in reading more about the comparison between KL divergence and JS divergence.\n$$\nD_{JS}(p \\| q) = \\frac{1}{2} D_{KL}(p \\| \\frac{p + q}{2}) + \\frac{1}{2} D_{KL}(q \\| \\frac{p + q}{2})\n$$\nGiven two Gaussian distribution, $p$ with mean=0 and std=1 and $q$ with mean=1 and std=1. The average of two distributions is labelled as $m=(p+q)/2$. KL divergence $D_{KL}$ is asymmetric but JS divergence $D_{JS}$ is symmetric.\nSome believe (\nHuszar, 2015\n) that one reason behind GANs’ big success is switching the loss function from asymmetric KL divergence in traditional maximum-likelihood approach to symmetric JS divergence. We will discuss more on this point in the next section.\nGenerative Adversarial Network (GAN)\n#\nGAN consists of two models:\nA discriminator $D$ estimates the probability of a given sample coming from the real dataset. It works as a critic and is optimized to tell the fake samples from the real ones.\nA generator $G$ outputs synthetic samples given a noise variable input $z$ ($z$ brings in potential output diversity). It is trained to capture the real data distribution so that its generative samples can be as real as possible, or in other words, can trick the discriminator to offer a high probability.\nArchitecture of a generative adversarial network. (Image source:\nwww.kdnuggets.com/2017/01/generative-...-learning.html\n)\nThese two models compete against each other during the training process: the generator $G$ is trying hard to trick the discriminator, while the critic model $D$ is trying hard not to be cheated. This interesting zero-sum game between two models motivates both to improve their functionalities.\nGiven,\nSymbol\nMeaning\nNotes\n$p_{z}$\nData distribution over noise input $z$\nUsually, just uniform.\n$p_{g}$\nThe generator’s distribution over data $x$\n$p_{r}$\nData distribution over real sample $x$\nOn one hand, we want to make sure the discriminator $D$’s decisions over real data are accurate by maximizing $\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$. Meanwhile, given a fake sample $G(z), z \\sim p_z(z)$, the discriminator is expected to output a probability, $D(G(z))$, close to zero by maximizing $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nOn the other hand, the generator is trained to increase the chances of $D$ producing a high probability for a fake example, thus to minimize $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nWhen combining both aspects together, $D$ and $G$ are playing a\nminimax game\nin which we should optimize the following loss function:\n$$\n\\begin{aligned}\n\\min_G \\max_D L(D, G) \n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{z \\sim p_z(z)} [\\log(1 - D(G(z)))] \\\\\n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{x \\sim p_g(x)} [\\log(1 - D(x)]\n\\end{aligned}\n$$\n($\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$ has no impact on $G$ during gradient descent updates.)\nWhat is the optimal value for D?\n#\nNow we have a well-defined loss function. Let’s first examine what is the best value for $D$.\n$$\nL(G, D) = \\int_x \\bigg( p_{r}(x) \\log(D(x)) + p_g (x) \\log(1 - D(x)) \\bigg) dx\n$$\nSince we are interested in what is the best value of $D(x)$ to maximize $L(G, D)$, let us label\n$$\n\\tilde{x} = D(x), \nA=p_{r}(x), \nB=p_g(x)\n$$\nAnd then what is inside the integral (we can safely ignore the integral because $x$ is sampled over all the possible values) is:\n$$\n\\begin{aligned}\nf(\\tilde{x}) \n& = A log\\tilde{x} + B log(1-\\tilde{x}) \\\\\n\\frac{d f(\\tilde{x})}{d \\tilde{x}}\n& = A \\frac{1}{ln10} \\frac{1}{\\tilde{x}} - B \\frac{1}{ln10} \\frac{1}{1 - \\tilde{x}} \\\\\n& = \\frac{1}{ln10} (\\frac{A}{\\tilde{x}} - \\frac{B}{1-\\tilde{x}}) \\\\\n& = \\frac{1}{ln10} \\frac{A - (A + B)\\tilde{x}}{\\tilde{x} (1 - \\tilde{x})} \\\\\n\\end{aligned}\n$$\nThus, set $\\frac{d f(\\tilde{x})}{d \\tilde{x}} = 0$, we get the best value of the discriminator: $D^*(x) = \\tilde{x}^* = \\frac{A}{A + B} = \\frac{p_{r}(x)}{p_{r}(x) + p_g(x)} \\in [0, 1]$.\nOnce the generator is trained to its optimal, $p_g$ gets very close to $p_{r}$. When $p_g = p_{r}$, $D^*(x)$ becomes $1/2$.\nWhat is the global optimal?\n#\nWhen both $G$ and $D$ are at their optimal values, we have $p_g = p_{r}$ and $D^*(x) = 1/2$ and the loss function becomes:\n$$\n\\begin{aligned}\nL(G, D^*) \n&= \\int_x \\bigg( p_{r}(x) \\log(D^*(x)) + p_g (x) \\log(1 - D^*(x)) \\bigg) dx \\\\\n&= \\log \\frac{1}{2} \\int_x p_{r}(x) dx + \\log \\frac{1}{2} \\int_x p_g(x) dx \\\\\n&= -2\\log2\n\\end{aligned}\n$$\nWhat does the loss function represent?\n#\nAccording to the formula listed in the\nprevious section\n, JS divergence between $p_{r}$ and $p_g$ can be computed as:\n$$\n\\begin{aligned}\nD_{JS}(p_{r} \\| p_g) \n=& \\frac{1}{2} D_{KL}(p_{r} || \\frac{p_{r} + p_g}{2}) + \\frac{1}{2} D_{KL}(p_{g} || \\frac{p_{r} + p_g}{2}) \\\\\n=& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_{r}(x) \\log \\frac{p_{r}(x)}{p_{r} + p_g(x)} dx \\bigg) + \\\\& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_g(x) \\log \\frac{p_g(x)}{p_{r} + p_g(x)} dx \\bigg) \\\\\n=& \\frac{1}{2} \\bigg( \\log4 + L(G, D^*) \\bigg)\n\\end{aligned}\n$$\nThus,\n$$\nL(G, D^*) = 2D_{JS}(p_{r} \\| p_g) - 2\\log2\n$$\nEssentially the loss function of GAN quantifies the similarity between the generative data distribution $p_g$ and the real sample distribution $p_{r}$ by JS divergence when the discriminator is optimal. The best $G^*$ that replicates the real data distribution leads to the minimum $L(G^*, D^*) = -2\\log2$ which is aligned with equations above.\nOther Variations of GAN\n: There are many variations of GANs in different contexts or designed for different tasks. For example, for semi-supervised learning, one idea is to update the discriminator to output real class labels, $1, \\dots, K-1$, as well as one fake class label $K$. The generator model aims to trick the discriminator to output a classification label smaller than $K$.\nTensorflow Implementation\n:\ncarpedm20/DCGAN-tensorflow\nProblems in GANs\n#\nAlthough GAN has shown great success in the realistic image generation, the training is not easy; The process is known to be slow and unstable.\nHard to achieve Nash equilibrium\n#\nSalimans et al. (2016)\ndiscussed the problem with GAN’s gradient-descent-based training procedure. Two models are trained simultaneously to find a\nNash equilibrium\nto a two-player non-cooperative game. However, each model updates its cost independently with no respect to another player in the game. Updating the gradient of both models concurrently cannot guarantee a convergence.\nLet’s check out a simple example to better understand why it is difficult to find a Nash equilibrium in an non-cooperative game. Suppose one player takes control of $x$ to minimize $f_1(x) = xy$, while at the same time the other player constantly updates $y$ to minimize $f_2(y) = -xy$.\nBecause $\\frac{\\partial f_1}{\\partial x} = y$ and $\\frac{\\partial f_2}{\\partial y} = -x$, we update $x$ with $x-\\eta \\cdot y$ and $y$ with $y+ \\eta \\cdot x$ simulitanously in one iteration, where $\\eta$ is the learning rate. Once $x$ and $y$ have different signs, every following gradient update causes huge oscillation and the instability gets worse in time, as shown in\nA simulation of our example for updating $x$ to minimize $xy$ and updating $y$ to minimize $-xy$. The learning rate $\\eta = 0.1$. With more iterations, the oscillation grows more and more unstable.\nLow dimensional supports\n#\nTerm\nExplanation\nManifold\nA topological space that locally resembles Euclidean space near each point. Precisely, when this Euclidean space is of\ndimension $n$\n, the manifold is referred as\n$n$-manifold\n.\nSupport\nA real-valued function $f$ is the subset of the domain containing those elements which are not mapped to\nzero\n.\nArjovsky and Bottou (2017)\ndiscussed the problem of the\nsupports\nof $p_r$ and $p_g$ lying on low dimensional\nmanifolds\nand how it contributes to the instability of GAN training thoroughly in a very theoretical paper\n“Towards principled methods for training generative adversarial networks”\n.\nThe dimensions of many real-world datasets, as represented by $p_r$, only appear to be\nartificially high\n. They have been found to concentrate in a lower dimensional manifold. This is actually the fundamental assumption for\nManifold Learning\n. Thinking of the real world images, once the theme or the contained object is fixed, the images have a lot of restrictions to follow, i.e., a dog should have two ears and a tail, and a skyscraper should have a straight and tall body, etc. These restrictions keep images aways from the possibility of having a high-dimensional free form.\n$p_g$ lies in a low dimensional manifolds, too. Whenever the generator is asked to a much larger image like 64x64 given a small dimension, such as 100, noise variable input $z$, the distribution of colors over these 4096 pixels has been defined by the small 100-dimension random number vector and can hardly fill up the whole high dimensional space.\nBecause both $p_g$ and $p_r$ rest in low dimensional manifolds, they are almost certainly gonna be disjoint (See Fig. 4). When they have disjoint supports, we are always capable of finding a perfect discriminator that separates real and fake samples 100% correctly. Check the\npaper\nif you are curious about the proof.\nLow dimensional manifolds in high dimension space can hardly have overlaps. (Left) Two lines in a three-dimension space. (Right) Two surfaces in a three-dimension space.\nVanishing gradient\n#\nWhen the discriminator is perfect, we are guaranteed with $D(x) = 1, \\forall x \\in p_r$ and $D(x) = 0, \\forall x \\in p_g$. Therefore the loss function $L$ falls to zero and we end up with no gradient to update the loss during learning iterations. Fig. 5 demonstrates an experiment when the discriminator gets better, the gradient vanishes fast.\nFirst, a DCGAN is trained for 1, 10 and 25 epochs. Then, with the **generator fixed**, a discriminator is trained from scratch and measure the gradients with the original cost function. We see the gradient norms **decay quickly** (in log scale), in the best case 5 orders of magnitude after 4000 discriminator iterations. (Image source:\nArjovsky and Bottou, 2017\n)\nAs a result, training a GAN faces a\ndilemma\n:\nIf the discriminator behaves badly, the generator does not have accurate feedback and the loss function cannot represent the reality.\nIf the discriminator does a great job, the gradient of the loss function drops down to close to zero and the learning becomes super slow or even jammed.\nThis dilemma clearly is capable to make the GAN training very tough.\nMode collapse\n#\nDuring the training, the generator may collapse to a setting where it always produces same outputs. This is a common failure case for GANs, commonly referred to as\nMode Collapse\n. Even though the generator might be able to trick the corresponding discriminator, it fails to learn to represent the complex real-world data distribution and gets stuck in a small space with extremely low variety.\nA DCGAN model is trained with an MLP network with 4 layers, 512 units and ReLU activation function, configured to lack a strong inductive bias for image generation. The results shows a significant degree of mode collapse. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nLack of a proper evaluation metric\n#\nGenerative adversarial networks are not born with a good objection function that can inform us the training progress. Without a good evaluation metric, it is like working in the dark. No good sign to tell when to stop; No good indicator to compare the performance of multiple models.\nImproved GAN Training\n#\nThe following suggestions are proposed to help stabilize and improve the training of GANs.\nFirst five methods are practical techniques to achieve faster convergence of GAN training, proposed in\n“Improve Techniques for Training GANs”\n.\nThe last two are proposed in\n“Towards principled methods for training generative adversarial networks”\nto solve the problem of disjoint distributions.\n(1)\nFeature Matching\nFeature matching suggests to optimize the discriminator to inspect whether the generator’s output matches expected statistics of the real samples. In such a scenario, the new loss function is defined as $| \\mathbb{E}_{x \\sim p_r} f(x) - \\mathbb{E}_{z \\sim p_z(z)}f(G(z)) |_2^2 $, where $f(x)$ can be any computation of statistics of features, such as mean or median.\n(2)\nMinibatch Discrimination\nWith minibatch discrimination, the discriminator is able to digest the relationship between training data points in one batch, instead of processing each point independently.\nIn one minibatch, we approximate the closeness between every pair of samples, $c(x_i, x_j)$, and get the overall summary of one data point by summing up how close it is to other samples in the same batch, $o(x_i) = \\sum_{j} c(x_i, x_j)$. Then $o(x_i)$ is explicitly added to the input of the model.\n(3)\nHistorical Averaging\nFor both models, add $ | \\Theta - \\frac{1}{t} \\sum_{i=1}^t \\Theta_i |^2 $ into the loss function, where $\\Theta$ is the model parameter and $\\Theta_i$ is how the parameter is configured at the past training time $i$. This addition piece penalizes the training speed when $\\Theta$ is changing too dramatically in time.\n(4)\nOne-sided Label Smoothing\nWhen feeding the discriminator, instead of providing 1 and 0 labels, use soften values such as 0.9 and 0.1. It is shown to reduce the networks’ vulnerability.\n(5)\nVirtual Batch Normalization\n(VBN)\nEach data sample is normalized based on a fixed batch (\n“reference batch”\n) of data rather than within its minibatch. The reference batch is chosen once at the beginning and stays the same through the training.\nTheano Implementation\n:\nopenai/improved-gan\n(6)\nAdding Noises\n.\nBased on the discussion in the\nprevious section\n, we now know $p_r$ and $p_g$ are disjoint in a high dimensional space and it causes the problem of vanishing gradient. To artificially “spread out” the distribution and to create higher chances for two probability distributions to have overlaps, one solution is to add continuous noises onto the inputs of the discriminator $D$.\n(7)\nUse Better Metric of Distribution Similarity\nThe loss function of the vanilla GAN measures the JS divergence between the distributions of $p_r$ and $p_g$. This metric fails to provide a meaningful value when two distributions are disjoint.\nWasserstein metric\nis proposed to replace JS divergence because it has a much smoother value space. See more in the next section.\nWasserstein GAN (WGAN)\n#\nWhat is Wasserstein distance?\n#\nWasserstein Distance\nis a measure of the distance between two probability distributions.\nIt is also called\nEarth Mover’s distance\n, short for EM distance, because informally it can be interpreted as the minimum energy cost of moving and transforming a pile of dirt in the shape of one probability distribution to the shape of the other distribution. The cost is quantified by: the amount of dirt moved x the moving distance.\nLet us first look at a simple case where the probability domain is\ndiscrete\n. For example, suppose we have two distributions $P$ and $Q$, each has four piles of dirt and both have ten shovelfuls of dirt in total. The numbers of shovelfuls in each dirt pile are assigned as follows:\n$$\n\\begin{aligned}\n& P_1 = 3, P_2 = 2, P_3 = 1, P_4 = 4\\\\\n& Q_1 = 1, Q_2 = 2, Q_3 = 4, Q_4 = 3\n\\end{aligned}\n$$\nIn order to change $P$ to look like $Q$, as illustrated in Fig. 7, we:\nFirst move 2 shovelfuls from $P_1$ to $P_2$ => $(P_1, Q_1)$ match up.\nThen move 2 shovelfuls from $P_2$ to $P_3$ => $(P_2, Q_2)$ match up.\nFinally move 1 shovelfuls from $Q_3$ to $Q_4$ => $(P_3, Q_3)$ and $(P_4, Q_4)$ match up.\nIf we label the cost to pay to make $P_i$ and $Q_i$ match as $\\delta_i$, we would have $\\delta_{i+1} = \\delta_i + P_i - Q_i$ and in the example:\n$$\n\\begin{aligned}\n\\delta_0 &= 0\\\\\n\\delta_1 &= 0 + 3 - 1 = 2\\\\\n\\delta_2 &= 2 + 2 - 2 = 2\\\\\n\\delta_3 &= 2 + 1 - 4 = -1\\\\\n\\delta_4 &= -1 + 4 - 3 = 0\n\\end{aligned}\n$$\nFinally the Earth Mover’s distance is $W = \\sum \\vert \\delta_i \\vert = 5$.\nStep-by-step plan of moving dirt between piles in $P$ and $Q$ to make them match.\nWhen dealing with the continuous probability domain, the distance formula becomes:\n$$\nW(p_r, p_g) = \\inf_{\\gamma \\sim \\Pi(p_r, p_g)} \\mathbb{E}_{(x, y) \\sim \\gamma}[\\| x-y \\|]\n$$\nIn the formula above, $\\Pi(p_r, p_g)$ is the set of all possible joint probability distributions between $p_r$ and $p_g$. One joint distribution $\\gamma \\in \\Pi(p_r, p_g)$ describes one dirt transport plan, same as the discrete example above, but in the continuous probability space. Precisely $\\gamma(x, y)$ states the percentage of dirt should be transported from point $x$ to $y$ so as to make $x$ follows the same probability distribution of $y$. That’s why the marginal distribution over $x$ adds up to $p_g$, $\\sum_{x} \\gamma(x, y) = p_g(y)$ (Once we finish moving the planned amount of dirt from every possible $x$ to the target $y$, we end up with exactly what $y$ has according to $p_g$.) and vice versa $\\sum_{y} \\gamma(x, y) = p_r(x)$.\nWhen treating $x$ as the starting point and $y$ as the destination, the total amount of dirt moved is $\\gamma(x, y)$ and the travelling distance is $| x-y |$ and thus the cost is $\\gamma(x, y) \\cdot | x-y |$. The expected cost averaged across all the $(x,y)$ pairs can be easily computed as:\n$$\n\\sum_{x, y} \\gamma(x, y) \\| x-y \\| \n= \\mathbb{E}_{x, y \\sim \\gamma} \\| x-y \\|\n$$\nFinally, we take the minimum one among the costs of all dirt moving solutions as the EM distance. In the definition of Wasserstein distance, the $\\inf$ (\ninfimum\n, also known as\ngreatest lower bound\n) indicates that we are only interested in the smallest cost.\nWhy Wasserstein is better than JS or KL divergence?\n#\nEven when two distributions are located in lower dimensional manifolds without overlaps, Wasserstein distance can still provide a meaningful and smooth representation of the distance in-between.\nThe WGAN paper exemplified the idea with a simple example.\nSuppose we have two probability distributions, $P$ and $Q$:\n$$\n\\forall (x, y) \\in P, x = 0 \\text{ and } y \\sim U(0, 1)\\\\\n\\forall (x, y) \\in Q, x = \\theta, 0 \\leq \\theta \\leq 1 \\text{ and } y \\sim U(0, 1)\\\\\n$$\nThere is no overlap between $P$ and $Q$ when $\\theta \\neq 0$.\nWhen $\\theta \\neq 0$:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{KL}(Q \\| P) &= \\sum_{x=\\theta, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{JS}(P, Q) &= \\frac{1}{2}(\\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2} + \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2}) = \\log 2\\\\\nW(P, Q) &= |\\theta|\n\\end{aligned}\n$$\nBut when $\\theta = 0$, two distributions are fully overlapped:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= D_{KL}(Q \\| P) = D_{JS}(P, Q) = 0\\\\\nW(P, Q) &= 0 = \\lvert \\theta \\rvert\n\\end{aligned}\n$$\n$D_{KL}$ gives us inifity when two distributions are disjoint. The value of $D_{JS}$ has sudden jump, not differentiable at $\\theta = 0$. Only Wasserstein metric provides a smooth measure, which is super helpful for a stable learning process using gradient descents.\nUse Wasserstein distance as GAN loss function\n#\nIt is intractable to exhaust all the possible joint distributions in $\\Pi(p_r, p_g)$ to compute $\\inf_{\\gamma \\sim \\Pi(p_r, p_g)}$. Thus the authors proposed a smart transformation of the formula based on the Kantorovich-Rubinstein duality to:\n$$\nW(p_r, p_g) = \\frac{1}{K} \\sup_{\\| f \\|_L \\leq K} \\mathbb{E}_{x \\sim p_r}[f(x)] - \\mathbb{E}_{x \\sim p_g}[f(x)]\n$$\nwhere $\\sup$ (\nsupremum\n) is the opposite of $inf$ (infimum); we want to measure the least upper bound or, in even simpler words, the maximum value.\nLipschitz continuity?\nThe function $f$ in the new form of Wasserstein metric is demanded to satisfy $| f |_L \\leq K$, meaning it should be\nK-Lipschitz continuous\n.\nA real-valued function $f: \\mathbb{R} \\rightarrow \\mathbb{R}$ is called $K$-Lipschitz continuous if there exists a real constant $K \\geq 0$ such that, for all $x_1, x_2 \\in \\mathbb{R}$,\n$$\n\\lvert f(x_1) - f(x_2) \\rvert \\leq K \\lvert x_1 - x_2 \\rvert\n$$\nHere $K$ is known as a Lipschitz constant for function $f(.)$. Functions that are everywhere continuously differentiable is Lipschitz continuous, because the derivative, estimated as $\\frac{\\lvert f(x_1) - f(x_2) \\rvert}{\\lvert x_1 - x_2 \\rvert}$, has bounds. However, a Lipschitz continuous function may not be everywhere differentiable, such as $f(x) = \\lvert x \\rvert$.\nExplaining how the transformation happens on the Wasserstein distance formula is worthy of a long post by itself, so I skip the details here. If you are interested in how to compute Wasserstein metric using linear programming, or how to transfer Wasserstein metric into its dual form according to the Kantorovich-Rubinstein Duality, read this\nawesome post\n.\nSuppose this function $f$ comes from a family of K-Lipschitz continuous functions, $\\{ f_w \\}_{w \\in W}$, parameterized by $w$. In the modified Wasserstein-GAN, the “discriminator” model is used to learn $w$ to find a good $f_w$ and the loss function is configured as measuring the Wasserstein distance between $p_r$ and $p_g$.\n$$\nL(p_r, p_g) = W(p_r, p_g) = \\max_{w \\in W} \\mathbb{E}_{x \\sim p_r}[f_w(x)] - \\mathbb{E}_{z \\sim p_r(z)}[f_w(g_\\theta(z))]\n$$\nThus the “discriminator” is not a direct critic of telling the fake samples apart from the real ones anymore. Instead, it is trained to learn a $K$-Lipschitz continuous function to help compute Wasserstein distance. As the loss function decreases in the training, the Wasserstein distance gets smaller and the generator model’s output grows closer to the real data distribution.\nOne big problem is to maintain the $K$-Lipschitz continuity of $f_w$ during the training in order to make everything work out. The paper presents a simple but very practical trick: After every gradient update, clamp the weights $w$ to a small window, such as $[-0.01, 0.01]$, resulting in a compact parameter space $W$ and thus $f_w$ obtains its lower and upper bounds to preserve the Lipschitz continuity.\nAlgorithm of Wasserstein generative adversarial network. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nCompared to the original GAN algorithm, the WGAN undertakes the following changes:\nAfter every gradient update on the critic function, clamp the weights to a small fixed range, $[-c, c]$.\nUse a new loss function derived from the Wasserstein distance, no logarithm anymore. The “discriminator” model does not play as a direct critic but a helper for estimating the Wasserstein metric between real and generated data distribution.\nEmpirically the authors recommended\nRMSProp\noptimizer on the critic, rather than a momentum based optimizer such as\nAdam\nwhich could cause instability in the model training. I haven’t seen clear theoretical explanation on this point through.\nSadly, Wasserstein GAN is not perfect. Even the authors of the original WGAN paper mentioned that\n“Weight clipping is a clearly terrible way to enforce a Lipschitz constraint”\n(Oops!). WGAN still suffers from unstable training, slow convergence after weight clipping (when clipping window is too large), and vanishing gradients (when clipping window is too small).\nSome improvement, precisely replacing weight clipping with\ngradient penalty\n, has been discussed in\nGulrajani et al. 2017\n. I will leave this to a future post.\nExample: Create New Pokemons!\n#\nJust for fun, I tried out\ncarpedm20/DCGAN-tensorflow\non a tiny dataset,\nPokemon sprites\n. The dataset only has 900-ish pokemon images, including different levels of same pokemon species.\nLet’s check out what types of new pokemons the model is able to create.\nUnfortunately due to the tiny training data, the new pokemons only have rough shapes without details. The shapes and colors do look better with more training epoches! Hooray!\nTrain\ncarpedm20/DCGAN-tensorflow\non a set of Pokemon sprite images. The sample outputs are listed after training epoches = 7, 21, 49.\nIf you are interested in a commented version of\ncarpedm20/DCGAN-tensorflow\nand how to modify it to train WGAN and WGAN with gradient penalty, check\nlilianweng/unified-gan-tensorflow\n.\nCited as:\n@article{weng2017gan,\n  title   = \"From GAN to WGAN\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-08-20-gan/\"\n}\nOR\n@misc{weng2019gan,\n    title={From GAN to WGAN},\n    author={Lilian Weng},\n    year={2019},\n    eprint={1904.08994},\n    archivePrefix={arXiv},\n    primaryClass={cs.LG}\n}\nReferences\n#\n[1] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.\n[2] Tim Salimans, et al.\n“Improved techniques for training gans.”\nNIPS 2016.\n[3] Martin Arjovsky and Léon Bottou.\n“Towards principled methods for training generative adversarial networks.”\narXiv preprint arXiv:1701.04862 (2017).\n[4] Martin Arjovsky, Soumith Chintala, and Léon Bottou.\n“Wasserstein GAN.”\narXiv preprint arXiv:1701.07875 (2017).\n[5] Ishaan Gulrajani, Faruk Ahmed, Martin Arjovsky, Vincent Dumoulin, Aaron Courville.\nImproved training of wasserstein gans.\narXiv preprint arXiv:1704.00028 (2017).\n[6]\nComputing the Earth Mover’s Distance under Transformations\n[7]\nWasserstein GAN and the Kantorovich-Rubinstein Duality\n[8]\nzhuanlan.zhihu.com/p/25071913\n[9] Ferenc Huszár.\n“How (not) to Train your Generative Model: Scheduled Sampling, Likelihood, Adversary?.”\narXiv preprint arXiv:1511.05101 (2015).",
            "metadata": {
              "title": "From GAN to WGAN | Lil'Log",
              "description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "keywords": "gan, long-read, generative-model, image-generation, math-heavy",
              "author": "Lilian Weng",
              "og:title": "From GAN to WGAN",
              "og:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
              "twitter:card": "summary",
              "twitter:title": "From GAN to WGAN",
              "twitter:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "article:section": "posts",
              "article:published_time": "2017-08-20T00:00:00+00:00",
              "article:modified_time": "2017-08-20T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/45444954e783/code/body-000.txt",
                "chars": 205,
                "language": "text"
              },
              {
                "file": "attachments/45444954e783/code/body-001.txt",
                "chars": 171,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "bytes": 221077,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-aa28a4cc1b3516c1be46.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "bytes": 157401,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-4199969ec35e7360ae98.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "bytes": 101972,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-95c24c614030b59aff01.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "bytes": 447186,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-c2ebec0990753f6d5a87.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "bytes": 736874,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f32623608491cb056216.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "bytes": 529052,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-54028801a0ddfc354538.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "bytes": 86758,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-501aa5d6dea1582e9385.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "bytes": 32150,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-7301ab34ef06aa0e487d.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "bytes": 313647,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-bacb4aa725276c994c68.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "bytes": 3106088,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f670e3a31b7940e1d8ef.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/yjucho1/articles/blob/master/fromGANtoWGAN/readme.md",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.08994",
                "label": "arXiv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL (Kullback–Leibler) divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence",
                "label": "Jensen–Shannon Divergence",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/Why-isnt-the-Jensen-Shannon-divergence-used-more-often-than-the-Kullback-Leibler-since-JS-is-symmetric-thus-possibly-a-better-indicator-of-distance",
                "label": "Quora post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.05101.pdf",
                "label": "Huszar, 2015",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "www.kdnuggets.com/2017/01/generative-...-learning.html",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "previous section",
                "type": "a"
              },
              {
                "href": "https://github.com/carpedm20/DCGAN-tensorflow",
                "label": "carpedm20/DCGAN-tensorflow",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "label": "Salimans et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nash_equilibrium",
                "label": "Nash equilibrium",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Manifold",
                "label": "Manifold",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Support_(mathematics)",
                "label": "Support",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.04862.pdf",
                "label": "Arjovsky and Bottou (2017)",
                "type": "a"
              },
              {
                "href": "http://scikit-learn.org/stable/modules/manifold.html",
                "label": "Manifold Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07875.pdf",
                "label": "Arjovsky, Chintala, & Bottou, 2017.",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/improved-gan",
                "label": "openai/improved-gan",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wasserstein_metric",
                "label": "Wasserstein metric",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Infimum_and_supremum",
                "label": "infimum",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lipschitz_continuity",
                "label": "K-Lipschitz continuous",
                "type": "a"
              },
              {
                "href": "https://vincentherrmann.github.io/blog/wasserstein/",
                "label": "awesome post",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "label": "RMSProp",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6980v8",
                "label": "Adam",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1704.00028.pdf",
                "label": "Gulrajani et al. 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/PokeAPI/sprites/",
                "label": "Pokemon sprites",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/unified-gan-tensorflow",
                "label": "lilianweng/unified-gan-tensorflow",
                "type": "a"
              },
              {
                "href": "http://robotics.stanford.edu/~scohen/research/emdg/emdg.html",
                "label": "Computing the Earth Mover’s Distance under Transformations",
                "type": "a"
              },
              {
                "href": "https://zhuanlan.zhihu.com/p/25071913",
                "label": "zhuanlan.zhihu.com/p/25071913",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.08994",
                "bytes": 2372969,
                "reused": false,
                "local_path": "papers/repair/a08caad93b55901c5b6f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": false,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05101.pdf",
                "bytes": 505788,
                "reused": false,
                "local_path": "papers/repair/057d39e637c6097bcd7a.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "bytes": 2639054,
                "reused": false,
                "local_path": "papers/repair/762153e376c22f644d34.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.04862.pdf",
                "bytes": 566179,
                "reused": false,
                "local_path": "papers/repair/e9832d130ee863bb324f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07875.pdf",
                "bytes": 8834587,
                "reused": false,
                "local_path": "papers/repair/941e1ba609c7c19a8af8.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "bytes": 546843,
                "reused": false,
                "local_path": "papers/repair/7b52598737bfafc8deab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6980v8",
                "bytes": 619544,
                "reused": false,
                "local_path": "papers/repair/0a612e9d0294ad8485d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00028.pdf",
                "bytes": 6187582,
                "reused": false,
                "local_path": "papers/repair/e6aa0075133ef9410890.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 27088,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/45444954e783/pages/source.html",
            "local_html": "attachments/45444954e783/pages/article.html",
            "body_base_path": "attachments/45444954e783/pages/",
            "body_markdown_path": "attachments/45444954e783/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
          "status": "partial",
          "article_id": "cd59f7ee3fdb",
          "local_path": "series-follow/1602/repair/8804f3f0e1a2da8b46c4.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
              "bytes": 137292,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/db59b90d279b037a97d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
              "bytes": 256981,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ab7006570b99c84db1b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
              "bytes": 26225,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1c83c8f4d8be7a5b4c49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
              "bytes": 1878475,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2e93bdc2c46162899b3f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
              "bytes": 151943,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/13d9a58c515022883c19.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
              "bytes": 482588,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ee2f9d9fbcd3aed80f31.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
              "bytes": 188866,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2351ecad009ac2895562.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
              "bytes": 274889,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/fae191e6a32c13b2540d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
              "bytes": 806890,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9610ae1d4a5d7cbb7454.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
              "bytes": 943633,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e326acd6fdf8195c78b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
              "bytes": 594737,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/91ba8add21dff9815090.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
              "bytes": 207374,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7020e37618b19a5457cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
              "bytes": 946267,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/da329904d7433579a338.png"
            }
          ],
          "article": {
            "id": "cd59f7ee3fdb",
            "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "source_excel_row": 1600,
            "source_url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "bytes": 137292,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-db59b90d279b037a97d1.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "bytes": 256981,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ab7006570b99c84db1b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "bytes": 26225,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-1c83c8f4d8be7a5b4c49.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "bytes": 1878475,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2e93bdc2c46162899b3f.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "bytes": 151943,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-13d9a58c515022883c19.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "bytes": 482588,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ee2f9d9fbcd3aed80f31.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "bytes": 188866,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2351ecad009ac2895562.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "bytes": 274889,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-fae191e6a32c13b2540d.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "bytes": 806890,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-9610ae1d4a5d7cbb7454.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "bytes": 943633,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-e326acd6fdf8195c78b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "bytes": 594737,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-91ba8add21dff9815090.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "bytes": 207374,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-7020e37618b19a5457cc.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "bytes": 946267,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-da329904d7433579a338.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "src": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/cd59f7ee3fdb/videos/repair-9zKuYvjFFS8.mp4",
                "bytes": 119566312,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "905.001000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-07-18: add a section on\nVQ-VAE & VQ-VAE-2\n.]\n[Updated on 2019-07-26: add a section on\nTD-VAE\n.]\nAutocoder is invented to reconstruct high-dimensional data using a neural network model with a narrow bottleneck layer in the middle (oops, this is probably not true for\nVariational Autoencoder\n, and we will investigate it in details in later sections). A nice byproduct is dimension reduction: the bottleneck layer captures a compressed latent encoding. Such a low-dimensional representation can be used as en embedding vector in various applications (i.e. search), help data compression, or reveal the underlying data generative factors.\nNotation\n#\nSymbol\nMean\n$\\mathcal{D}$\nThe dataset, $\\mathcal{D} = \\{ \\mathbf{x}^{(1)}, \\mathbf{x}^{(2)}, \\dots, \\mathbf{x}^{(n)} \\}$, contains $n$ data samples; $\\vert\\mathcal{D}\\vert =n $.\n$\\mathbf{x}^{(i)}$\nEach data point is a vector of $d$ dimensions, $\\mathbf{x}^{(i)} = [x^{(i)}_1, x^{(i)}_2, \\dots, x^{(i)}_d]$.\n$\\mathbf{x}$\nOne data sample from the dataset, $\\mathbf{x} \\in \\mathcal{D}$.\n$\\mathbf{x}’$\nThe reconstructed version of $\\mathbf{x}$.\n$\\tilde{\\mathbf{x}}$\nThe corrupted version of $\\mathbf{x}$.\n$\\mathbf{z}$\nThe compressed code learned in the bottleneck layer.\n$a_j^{(l)}$\nThe activation function for the $j$-th neuron in the $l$-th hidden layer.\n$g_{\\phi}(.)$\nThe\nencoding\nfunction parameterized by $\\phi$.\n$f_{\\theta}(.)$\nThe\ndecoding\nfunction parameterized by $\\theta$.\n$q_{\\phi}(\\mathbf{z}\\vert\\mathbf{x})$\nEstimated posterior probability function, also known as\nprobabilistic encoder\n.\n$p_{\\theta}(\\mathbf{x}\\vert\\mathbf{z})$\nLikelihood of generating true data sample given the latent code, also known as\nprobabilistic decoder\n.\nAutoencoder\n#\nAutoencoder\nis a neural network designed to learn an identity function in an unsupervised way  to reconstruct the original input while compressing the data in the process so as to discover a more efficient and compressed representation. The idea was originated in\nthe 1980s\n, and later promoted by the seminal paper by\nHinton & Salakhutdinov, 2006\n.\nIt consists of two networks:\nEncoder\nnetwork: It translates the original high-dimension input into the latent low-dimensional code. The input size is larger than the output size.\nDecoder\nnetwork: The decoder network recovers the data from the code, likely with larger and larger output layers.\nIllustration of autoencoder model architecture.\nThe encoder network essentially accomplishes the\ndimensionality reduction\n, just like how we would use Principal Component Analysis (PCA) or Matrix Factorization (MF) for. In addition, the autoencoder is explicitly optimized for the data reconstruction from the code. A good intermediate representation not only can capture latent variables, but also benefits a full\ndecompression\nprocess.\nThe model contains an encoder function $g(.)$ parameterized by $\\phi$ and a decoder function $f(.)$ parameterized by $\\theta$. The low-dimensional code learned for input $\\mathbf{x}$ in the bottleneck layer is $\\mathbf{z} = g_\\phi(\\mathbf{x})$ and the reconstructed input is $\\mathbf{x}’ = f_\\theta(g_\\phi(\\mathbf{x}))$.\nThe parameters $(\\theta, \\phi)$ are learned together to output a reconstructed data sample same as the original input, $\\mathbf{x} \\approx f_\\theta(g_\\phi(\\mathbf{x}))$, or in other words, to learn an identity function. There are various metrics to quantify the difference between two vectors, such as cross entropy when the activation function is sigmoid, or as simple as MSE loss:\n$$\nL_\\text{AE}(\\theta, \\phi) = \\frac{1}{n}\\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\mathbf{x}^{(i)})))^2\n$$\nDenoising Autoencoder\n#\nSince the autoencoder learns the identity function, we are facing the risk of “overfitting” when there are more network parameters than the number of data points.\nTo avoid overfitting and improve the robustness,\nDenoising Autoencoder\n(Vincent et al. 2008) proposed a modification to the basic autoencoder. The input is partially corrupted by adding noises to or masking some values of the input vector in a stochastic manner, $\\tilde{\\mathbf{x}} \\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$. Then the model is trained to recover the original input (note: not the corrupt one).\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{x}}^{(i)} &\\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}}^{(i)} \\vert \\mathbf{x}^{(i)})\\\\\nL_\\text{DAE}(\\theta, \\phi) &= \\frac{1}{n} \\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\tilde{\\mathbf{x}}^{(i)})))^2\n\\end{aligned}\n$$\nwhere $\\mathcal{M}_\\mathcal{D}$ defines the mapping from the true data samples to the noisy or corrupted ones.\nIllustration of denoising autoencoder model architecture.\nThis design is motivated by the fact that humans can easily recognize an object or a scene even the view is partially occluded or corrupted. To “repair” the partially destroyed input, the denoising autoencoder has to discover and capture relationship between dimensions of input in order to infer missing pieces.\nFor high dimensional input with high redundancy, like images, the model is likely to depend on evidence gathered from a combination of many input dimensions to recover the denoised version rather than to overfit one dimension. This builds up a good foundation for learning\nrobust\nlatent representation.\nThe noise is controlled by a stochastic mapping $\\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$, and it is not specific to a particular type of corruption process (i.e. masking noise, Gaussian noise, salt-and-pepper noise, etc.). Naturally the corruption process can be equipped with prior knowledge\nIn the experiment of the original DAE paper, the noise is applied in this way: a fixed proportion of input dimensions are selected at random and their values are forced to 0. Sounds a lot like dropout, right? Well, the denoising autoencoder was proposed in 2008, 4 years before the dropout paper (\nHinton, et al. 2012\n) ;)\nSparse Autoencoder\n#\nSparse Autoencoder\napplies a “sparse” constraint on the hidden unit activation to avoid overfitting and improve robustness. It forces the model to only have a small number of hidden units being activated at the same time, or in other words, one hidden neuron should be inactivate most of time.\nRecall that common\nactivation functions\ninclude sigmoid, tanh, relu, leaky relu, etc. A neuron is activated when the value is close to 1 and inactivate with a value close to 0.\nLet’s say there are $s_l$ neurons in the $l$-th hidden layer and the activation function for the $j$-th neuron in this layer is labelled as $a^{(l)}_j(.)$, $j=1, \\dots, s_l$. The fraction of activation of this neuron $\\hat{\\rho}_j$ is expected to be a small number $\\rho$, known as\nsparsity parameter\n; a common config is $\\rho = 0.05$.\n$$\n\\hat{\\rho}_j^{(l)} = \\frac{1}{n} \\sum_{i=1}^n [a_j^{(l)}(\\mathbf{x}^{(i)})] \\approx \\rho\n$$\nThis constraint is achieved by adding a penalty term into the loss function. The KL-divergence $D_\\text{KL}$ measures the difference between two Bernoulli distributions, one with mean $\\rho$ and the other with mean $\\hat{\\rho}_j^{(l)}$. The hyperparameter $\\beta$ controls how strong the penalty we want to apply on the sparsity loss.\n$$\n\\begin{aligned}\nL_\\text{SAE}(\\theta) \n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} D_\\text{KL}(\\rho \\| \\hat{\\rho}_j^{(l)}) \\\\\n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} \\rho\\log\\frac{\\rho}{\\hat{\\rho}_j^{(l)}} + (1-\\rho)\\log\\frac{1-\\rho}{1-\\hat{\\rho}_j^{(l)}}\n\\end{aligned}\n$$\nThe KL divergence between a Bernoulli distribution with mean $\\rho=0.25$ and a Bernoulli distribution with mean $0 \\leq \\hat{\\rho} \\leq 1$.\n$k$-Sparse Autoencoder\nIn $k$-Sparse Autoencoder (\nMakhzani and Frey, 2013\n), the sparsity is enforced by only keeping the top k highest activations in the bottleneck layer with linear activation function.\nFirst we run feedforward through the encoder network to get the compressed code: $\\mathbf{z} = g(\\mathbf{x})$.\nSort the values  in the code vector $\\mathbf{z}$. Only the k largest values are kept while other neurons are set to 0. This can be done in a ReLU layer with an adjustable threshold too. Now we have a sparsified code: $\\mathbf{z}’ = \\text{Sparsify}(\\mathbf{z})$.\nCompute the output and the loss from the sparsified code, $L = |\\mathbf{x} - f(\\mathbf{z}’) |_2^2$.\nAnd, the back-propagation only goes through the top k activated hidden units!\nFilters of the k-sparse autoencoder for different sparsity levels k, learnt from MNIST with 1000 hidden units.. (Image source:\nMakhzani and Frey, 2013\n)\nContractive Autoencoder\n#\nSimilar to sparse autoencoder,\nContractive Autoencoder\n(\nRifai, et al, 2011\n) encourages the learned representation to stay in a contractive space for better robustness.\nIt adds a term in the loss function to penalize the representation being too sensitive to the input,  and thus improve the robustness to small perturbations around the training data points. The sensitivity is measured by the Frobenius norm of the Jacobian matrix of the encoder activations with respect to the input:\n$$\n\\|J_f(\\mathbf{x})\\|_F^2 = \\sum_{ij} \\Big( \\frac{\\partial h_j(\\mathbf{x})}{\\partial x_i} \\Big)^2\n$$\nwhere $h_j$ is one unit output in the compressed code $\\mathbf{z} = f(x)$.\nThis penalty term is the sum of squares of all partial derivatives of the learned encoding with respect to input dimensions. The authors claimed that empirically this penalty was found to  carve a representation that corresponds to a lower-dimensional non-linear manifold, while staying more invariant to majority directions orthogonal to the manifold.\nVAE: Variational Autoencoder\n#\nThe idea of\nVariational Autoencoder\n(\nKingma & Welling, 2014\n), short for\nVAE\n, is actually less similar to all the autoencoder models above, but deeply rooted in the methods of variational bayesian and graphical model.\nInstead of mapping the input into a\nfixed\nvector, we want to map it into a distribution. Let’s label this distribution as $p_\\theta$, parameterized by $\\theta$.  The relationship between the data input $\\mathbf{x}$ and the latent encoding vector $\\mathbf{z}$ can be fully defined by:\nPrior $p_\\theta(\\mathbf{z})$\nLikelihood $p_\\theta(\\mathbf{x}\\vert\\mathbf{z})$\nPosterior $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$\nAssuming that we know the real parameter $\\theta^{*}$ for this distribution. In order to generate a sample that looks like a real data point $\\mathbf{x}^{(i)}$, we follow these steps:\nFirst, sample a $\\mathbf{z}^{(i)}$ from a prior distribution $p_{\\theta^*}(\\mathbf{z})$.\nThen a value $\\mathbf{x}^{(i)}$ is generated from a conditional distribution $p_{\\theta^*}(\\mathbf{x} \\vert \\mathbf{z} = \\mathbf{z}^{(i)})$.\nThe optimal parameter $\\theta^{*}$ is the one that maximizes the probability of generating real data samples:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\prod_{i=1}^n p_\\theta(\\mathbf{x}^{(i)})\n$$\nCommonly we use the log probabilities to convert the product on RHS to a sum:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\sum_{i=1}^n \\log p_\\theta(\\mathbf{x}^{(i)})\n$$\nNow let’s update the equation to better demonstrate the data generation process so as to involve the encoding vector:\n$$\np_\\theta(\\mathbf{x}^{(i)}) = \\int p_\\theta(\\mathbf{x}^{(i)}\\vert\\mathbf{z}) p_\\theta(\\mathbf{z}) d\\mathbf{z} \n$$\nUnfortunately it is not easy to compute $p_\\theta(\\mathbf{x}^{(i)})$ in this way, as it is very expensive to check all the possible values of $\\mathbf{z}$ and sum them up. To narrow down the value space to facilitate faster search, we would like to introduce a new approximation function to output what is a likely code given an input $\\mathbf{x}$, $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$, parameterized by $\\phi$.\nThe graphical model involved in Variational Autoencoder.  Solid lines denote the generative distribution $p\\_\\theta(.)$ and dashed lines denote the distribution $q\\_\\phi (\\mathbf{z}\\vert\\mathbf{x})$ to approximate the intractable posterior $p\\_\\theta (\\mathbf{z}\\vert\\mathbf{x})$.\nNow the structure looks a lot like an autoencoder:\nThe conditional probability $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ defines a generative model, similar to the decoder $f_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ introduced above. $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ is also known as\nprobabilistic decoder\n.\nThe approximation function $q_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ is the\nprobabilistic encoder\n, playing a similar role as $g_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ above.\nLoss Function: ELBO\n#\nThe estimated posterior $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ should be very close to the real one $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$. We can use\nKullback-Leibler divergence\nto quantify the distance between these two distributions. KL divergence $D_\\text{KL}(X|Y)$ measures how much information is lost if the distribution Y is used to represent X.\nIn our case we want to minimize $D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) | p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )$ with respect to $\\phi$.\nBut why use $D_\\text{KL}(q_\\phi | p_\\theta)$ (reversed KL) instead of $D_\\text{KL}(p_\\theta | q_\\phi)$ (forward KL)? Eric Jang has a great explanation in his\npost\non Bayesian Variational methods. As a quick recap:\nForward and reversed KL divergence have different demands on how to match two distributions. (Image source:\nblog.evjang.com/2016/08/variational-bayes.html\n)\nForward KL divergence: $D_\\text{KL}(P|Q) = \\mathbb{E}_{z\\sim P(z)} \\log\\frac{P(z)}{Q(z)}$; we have to ensure that Q(z)>0 wherever P(z)>0. The optimized variational distribution $q(z)$ has to cover over the entire $p(z)$.\nReversed KL divergence: $D_\\text{KL}(Q|P) = \\mathbb{E}_{z\\sim Q(z)} \\log\\frac{Q(z)}{P(z)}$; minimizing the reversed KL divergence squeezes the $Q(z)$ under $P(z)$.\nLet’s now expand the equation:\n$$\n\\begin{aligned}\n& D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z} \\vert \\mathbf{x})} d\\mathbf{z} & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})p_\\theta(\\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z \\vert x) = p(z, x) / p(x)} \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\big( \\log p_\\theta(\\mathbf{x}) + \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} \\big) d\\mathbf{z} & \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }\\int q(z \\vert x) dz = 1}\\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{x}\\vert\\mathbf{z})p_\\theta(\\mathbf{z})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z, x) = p(x \\vert z) p(z)} \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}[\\log \\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z})} - \\log p_\\theta(\\mathbf{x} \\vert \\mathbf{z})] &\\\\\n&=\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) &\n\\end{aligned}\n$$\nSo we have:\n$$\nD_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) =\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})\n$$\nOnce rearrange the left and right hand side of the equation,\n$$\n\\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) = \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}))\n$$\nThe LHS of the equation is exactly what we want to maximize when learning the true distributions: we want to maximize the (log-)likelihood of generating real data (that is $\\log p_\\theta(\\mathbf{x})$) and also minimize the difference between the real and estimated posterior distributions (the term $D_\\text{KL}$ works like a regularizer).  Note that $p_\\theta(\\mathbf{x})$ is fixed with respect to $q_\\phi$.\nThe negation of the above defines our loss function:\n$$\n\\begin{aligned}\nL_\\text{VAE}(\\theta, \\phi) \n&= -\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )\\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}) ) \\\\\n\\theta^{*}, \\phi^{*} &= \\arg\\min_{\\theta, \\phi} L_\\text{VAE}\n\\end{aligned}\n$$\nIn Variational Bayesian methods, this loss function is known as the\nvariational lower bound\n, or\nevidence lower bound\n. The “lower bound” part in the name comes from the fact that KL divergence is always non-negative and thus $-L_\\text{VAE}$ is the lower bound of $\\log p_\\theta (\\mathbf{x})$.\n$$\n-L_\\text{VAE} = \\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) \\leq \\log p_\\theta(\\mathbf{x})\n$$\nTherefore by minimizing the loss, we are maximizing the lower bound of the probability of generating real data samples.\nReparameterization Trick\n#\nThe expectation term in the loss function invokes generating samples from $\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$. Sampling is a stochastic process and therefore we cannot backpropagate the gradient. To make it trainable, the reparameterization trick is introduced: It is often possible to express the random variable $\\mathbf{z}$ as a deterministic variable $\\mathbf{z} = \\mathcal{T}_\\phi(\\mathbf{x}, \\boldsymbol{\\epsilon})$, where $\\boldsymbol{\\epsilon}$ is an auxiliary independent random variable, and the transformation function $\\mathcal{T}_\\phi$ parameterized by $\\phi$ converts $\\boldsymbol{\\epsilon}$ to $\\mathbf{z}$.\nFor example, a common choice of the form of $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ is a multivariate Gaussian with a diagonal covariance structure:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x}^{(i)}) = \\mathcal{N}(\\mathbf{z}; \\boldsymbol{\\mu}^{(i)}, \\boldsymbol{\\sigma}^{2(i)}\\boldsymbol{I}) & \\\\\n\\mathbf{z} &= \\boldsymbol{\\mu} + \\boldsymbol{\\sigma} \\odot \\boldsymbol{\\epsilon} \\text{, where } \\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I}) & \\scriptstyle{\\text{; Reparameterization trick.}}\n\\end{aligned}\n$$\nwhere $\\odot$ refers to element-wise product.\nIllustration of how the reparameterization trick makes the $\\mathbf{z}$ sampling process trainable.(Image source: Slide 12 in Kingma’s NIPS 2015 workshop\ntalk\n)\nThe reparameterization trick works for other types of distributions too, not only Gaussian.\nIn the multivariate Gaussian case, we make the model trainable by learning the mean and variance of the distribution, $\\mu$ and $\\sigma$, explicitly using the reparameterization trick, while the stochasticity remains in the random variable $\\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I})$.\nIllustration of variational autoencoder model with the multivariate Gaussian assumption.\nBeta-VAE\n#\nIf each variable in the inferred latent representation $\\mathbf{z}$ is only sensitive to one single generative factor and relatively invariant to other factors, we will say this representation is disentangled or factorized. One benefit that often comes with disentangled representation is\ngood interpretability\nand easy generalization to a variety of tasks.\nFor example, a model trained on photos of human faces might capture the gentle, skin color, hair color, hair length, emotion, whether wearing a pair of glasses and many other relatively independent factors in separate dimensions. Such a disentangled representation is very beneficial to facial image generation.\nβ-VAE (\nHiggins et al., 2017\n) is a modification of Variational Autoencoder with a special emphasis to discover disentangled latent factors. Following the same incentive in VAE, we want to maximize the probability of generating real data, while keeping the distance between the real and estimated posterior distributions small (say, under a small constant $\\delta$):\n$$\n\\begin{aligned}\n&\\max_{\\phi, \\theta} \\mathbb{E}_{\\mathbf{x}\\sim\\mathcal{D}}[\\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})]\\\\\n&\\text{subject to } D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) < \\delta\n\\end{aligned}\n$$\nWe can rewrite it as a Lagrangian with a Lagrangian multiplier $\\beta$ under the\nKKT condition\n. The above optimization problem with only one inequality constraint is equivalent to maximizing the following equation $\\mathcal{F}(\\theta, \\phi, \\beta)$:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta, \\phi, \\beta) &= \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta(D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) - \\delta) & \\\\\n& = \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) + \\beta \\delta & \\\\\n& \\geq \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) & \\scriptstyle{\\text{; Because }\\beta,\\delta\\geq 0}\n\\end{aligned}\n$$\nThe loss function of $\\beta$-VAE is defined as:\n$$\nL_\\text{BETA}(\\phi, \\beta) = - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z}))\n$$\nwhere the Lagrangian multiplier $\\beta$ is considered as a hyperparameter.\nSince the negation of $L_\\text{BETA}(\\phi, \\beta)$ is the lower bound of the Lagrangian $\\mathcal{F}(\\theta, \\phi, \\beta)$. Minimizing the loss is equivalent to maximizing the Lagrangian and thus works for our initial optimization problem.\nWhen $\\beta=1$, it is same as VAE. When $\\beta > 1$, it applies a stronger constraint on the latent bottleneck and limits the representation capacity of $\\mathbf{z}$. For some conditionally independent generative factors, keeping them disentangled is the most efficient representation. Therefore a higher $\\beta$ encourages more efficient latent encoding and further encourages the disentanglement. Meanwhile, a higher $\\beta$ may create a trade-off between reconstruction quality and the extent of disentanglement.\nBurgess, et al. (2017)\ndiscussed the distentangling in $\\beta$-VAE in depth with an inspiration by the\ninformation bottleneck theory\nand further proposed a modification to $\\beta$-VAE to better control the encoding representation capacity.\nVQ-VAE and VQ-VAE-2\n#\nThe\nVQ-VAE\n(“Vector Quantised-Variational AutoEncoder”;\nvan den Oord, et al. 2017\n) model learns a discrete latent variable by the encoder, since discrete representations may be a more natural fit for problems like language, speech, reasoning, etc.\nVector quantisation (VQ) is a method to map $K$-dimensional vectors into a finite set of “code” vectors. The process is very much similar to\nKNN\nalgorithm. The optimal centroid code vector that a sample should be mapped to is the one with minimum euclidean distance.\nLet $\\mathbf{e} \\in \\mathbb{R}^{K \\times D}, i=1, \\dots, K$ be the latent embedding space (also known as “codebook”) in VQ-VAE, where $K$ is the number of latent variable categories and $D$ is the embedding size. An individual embedding vector is $\\mathbf{e}_i \\in \\mathbb{R}^{D}, i=1, \\dots, K$.\nThe encoder output $E(\\mathbf{x}) = \\mathbf{z}_e$ goes through a nearest-neighbor lookup to match to one of $K$ embedding vectors and then this matched code vector becomes the input for the decoder $D(.)$:\n$$\n\\mathbf{z}_q(\\mathbf{x}) = \\text{Quantize}(E(\\mathbf{x})) = \\mathbf{e}_k \\text{ where } k = \\arg\\min_i \\|E(\\mathbf{x}) - \\mathbf{e}_i \\|_2\n$$\nNote that the discrete latent variables can have different shapes in differnet applications; for example, 1D for speech, 2D for image and 3D for video.\nThe architecture of VQ-VAE (Image source:\nvan den Oord, et al. 2017\n)\nBecause argmin() is non-differentiable on a discrete space, the gradients $\\nabla_z L$ from decoder input $\\mathbf{z}_q$ is copied to the encoder output $\\mathbf{z}_e$. Other than reconstruction loss, VQ-VAE also optimizes:\nVQ loss\n: The L2 error between the embedding space and the encoder outputs.\nCommitment loss\n: A measure to encourage the encoder output to stay close to the embedding space and to prevent it from fluctuating too frequently from one code vector to another.\n$$\nL = \\underbrace{\\|\\mathbf{x} - D(\\mathbf{e}_k)\\|_2^2}_{\\textrm{reconstruction loss}} + \n\\underbrace{\\|\\text{sg}[E(\\mathbf{x})] - \\mathbf{e}_k\\|_2^2}_{\\textrm{VQ loss}} + \n\\underbrace{\\beta \\|E(\\mathbf{x}) - \\text{sg}[\\mathbf{e}_k]\\|_2^2}_{\\textrm{commitment loss}}\n$$\nwhere $\\text{sg}[.]$ is the\nstop_gradient\noperator.\nThe embedding vectors in the codebook is updated through EMA (exponential moving average). Given a code vector $\\mathbf{e}_i$, say we have $n_i$ encoder output vectors, $\\{\\mathbf{z}_{i,j}\\}_{j=1}^{n_i}$, that are quantized to $\\mathbf{e}_i$:\n$$\nN_i^{(t)} = \\gamma N_i^{(t-1)} + (1-\\gamma)n_i^{(t)}\\;\\;\\;\n\\mathbf{m}_i^{(t)} = \\gamma \\mathbf{m}_i^{(t-1)} + (1-\\gamma)\\sum_{j=1}^{n_i^{(t)}}\\mathbf{z}_{i,j}^{(t)}\\;\\;\\;\n\\mathbf{e}_i^{(t)} = \\mathbf{m}_i^{(t)} / N_i^{(t)}\n$$\nwhere $(t)$ refers to batch sequence in time. $N_i$ and $\\mathbf{m}_i$ are accumulated vector count and volume, respectively.\nVQ-VAE-2 (\nAli Razavi, et al. 2019\n) is a two-level hierarchical VQ-VAE combined with self-attention autoregressive model.\nStage 1 is to\ntrain a hierarchical VQ-VAE\n: The design of hierarchical latent variables intends to separate local patterns (i.e., texture) from global information (i.e., object shapes). The training of the larger bottom level codebook is conditioned on the smaller top level code too, so that it does not have to learn everything from scratch.\nStage 2 is to\nlearn a prior over the latent discrete codebook\nso that we sample from it and generate images. In this way, the decoder can receive input vectors sampled from a similar distribution as the one in training. A powerful autoregressive model enhanced with multi-headed self-attention layers is used to capture the prior distribution (like\nPixelSNAIL; Chen et al 2017\n).\nConsidering that VQ-VAE-2 depends on discrete latent variables configured in a simple hierarchical setting, the quality of its generated images are pretty amazing.\nArchitecture of hierarchical VQ-VAE and multi-stage image generation. (Image source:\nAli Razavi, et al. 2019\n)\nThe VQ-VAE-2 algorithm. (Image source:\nAli Razavi, et al. 2019\n)\nTD-VAE\n#\nTD-VAE\n(“Temporal Difference VAE”;\nGregor et al., 2019\n) works with sequential data. It relies on three main ideas, described below.\nState-space model as a Markov Chain model.\n1. State-Space Models\nIn (latent) state-space models, a sequence of unobserved hidden states $\\mathbf{z} = (z_1, \\dots, z_T)$ determine the observation states $\\mathbf{x} = (x_1, \\dots, x_T)$. Each time step in the Markov chain model in Fig. 13 can be trained in a similar manner as in Fig. 6, where the intractable posterior $p(z \\vert x)$ is approximated by a function $q(z \\vert x)$.\n2. Belief State\nAn agent should learn to encode all the past states to reason about the future, named as\nbelief state\n, $b_t = belief(x_1, \\dots, x_t) = belief(b_{t-1}, x_t)$. Given this, the distribution of future states conditioned on the past can be written as $p(x_{t+1}, \\dots, x_T \\vert x_1, \\dots, x_t) \\approx p(x_{t+1}, \\dots, x_T \\vert b_t)$. The hidden states in a recurrent policy are used as the agent’s belief state in TD-VAE. Thus we have $b_t = \\text{RNN}(b_{t-1}, x_t)$.\n3. Jumpy Prediction\nFurther, an agent is expected to imagine distant futures based on all the information gathered so far, suggesting the capability of making jumpy predictions, that is, predicting states several steps further into the future.\nRecall what we have learned from the variance lower bound\nabove\n:\n$$\n\\begin{aligned}\n\\log p(x) \n&\\geq \\log p(x) - D_\\text{KL}(q(z|x)\\|p(z|x)) \\\\\n&= \\mathbb{E}_{z\\sim q} \\log p(x|z) - D_\\text{KL}(q(z|x)\\|p(z)) \\\\\n&= \\mathbb{E}_{z \\sim q} \\log p(x|z) - \\mathbb{E}_{z \\sim q} \\log \\frac{q(z|x)}{p(z)} \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x|z) -\\log q(z|x) + \\log p(z)] \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)] \\\\\n\\log p(x) \n&\\geq \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)]\n\\end{aligned}\n$$\nNow let’s model the distribution of the state $x_t$ as a probability function conditioned on all the past states $x_{<t}$ and two latent variables, $z_t$ and $z_{t-1}$, at current time step and one step back:\n$$\n\\log p(x_t|x_{<{t}}) \\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})]\n$$\nContinue expanding the equation:\n$$\n\\begin{aligned}\n& \\log p(x_t|x_{<{t}}) \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|\\color{red}{z_{t-1}}, z_{t}, \\color{red}{x_{<{t}}}) + \\color{blue}{\\log p(z_{t-1}, z_{t}|x_{<{t}})} -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\color{blue}{\\log p(z_{t-1}|x_{<{t}})} + \\color{blue}{\\log p(z_{t}|z_{t-1})} - \\color{green}{\\log q(z_{t-1}, z_t|x_{\\leq t})}] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\log p(z_{t-1}|x_{<{t}}) + \\log p(z_{t}|z_{t-1}) - \\color{green}{\\log q(z_t|x_{\\leq t})} - \\color{green}{\\log q(z_{t-1}|z_t, x_{\\leq t})}]\n\\end{aligned}\n$$\nNotice two things:\nThe\nred\nterms can be ignored according to Markov assumptions.\nThe\nblue\nterm is expanded according to Markov assumptions.\nThe\ngreen\nterm is expanded to include an one-step prediction back to the past as a smoothing distribution.\nPrecisely, there are four types of distributions to learn:\n$p_D(.)$ is the\ndecoder\ndistribution:\n$p(x_t \\mid z_t)$ is the encoder by the common definition;\n$p(x_t \\mid z_t) \\to p_D(x_t \\mid z_t)$;\n$p_T(.)$ is the\ntransition\ndistribution:\n$p(z_t \\mid z_{t-1})$ captures the sequential dependency between latent variables;\n$p(z_t \\mid z_{t-1}) \\to p_T(z_t \\mid z_{t-1})$;\n$p_B(.)$ is the\nbelief\ndistribution:\nBoth $p(z_{t-1} \\mid x_{<t})$ and $q(z_t \\mid x_{\\leq t})$ can use the belief states to predict the latent variables;\n$p(z_{t-1} \\mid x_{<t}) \\to p_B(z_{t-1} \\mid b_{t-1})$;\n$q(z_{t} \\mid x_{\\leq t}) \\to p_B(z_t \\mid b_t)$;\n$p_S(.)$ is the\nsmoothing\ndistribution:\nThe back-to-past smoothing term $q(z_{t-1} \\mid z_t, x_{\\leq t})$ can be rewritten to be dependent of belief states too;\n$q(z_{t-1} \\mid z_t, x_{\\leq t}) \\to  p_S(z_{t-1} \\mid z_t, b_{t-1}, b_t)$;\nTo incorporate the idea of jumpy prediction, the sequential ELBO has to not only work on $t, t+1$, but also two distant timestamp $t_1 < t_2$. Here is the final TD-VAE objective function to maximize:\n$$\nJ_{t_1, t_2} = \\mathbb{E}[\n  \\log p_D(x_{t_2}|z_{t_2}) \n  + \\log p_B(z_{t_1}|b_{t_1}) \n  + \\log p_T(z_{t_2}|z_{t_1}) \n  - \\log p_B(z_{t_2}|b_{t_2}) \n  - \\log p_S(z_{t_1}|z_{t_2}, b_{t_1}, b_{t_2})]\n$$\nA detailed overview of TD-VAE architecture, very nicely done. (Image source:\nTD-VAE paper\n)\nCited as:\n@article{weng2018VAE,\n  title   = \"From Autoencoder to Beta-VAE\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-08-12-vae/\"\n}\nReferences\n#\n[1] Geoffrey E. Hinton, and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nScience 313.5786 (2006): 504-507.\n[2] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[3] Pascal Vincent, et al.\n“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”\n. Journal of machine learning research 11.Dec (2010): 3371-3408.\n[4] Geoffrey E. Hinton, Nitish Srivastava, Alex Krizhevsky, Ilya Sutskever, and Ruslan R. Salakhutdinov. “Improving neural networks by preventing co-adaptation of feature detectors.” arXiv preprint arXiv:1207.0580 (2012).\n[5]\nSparse Autoencoder\nby Andrew Ng.\n[6] Alireza Makhzani, Brendan Frey (2013).\n“k-sparse autoencoder”\n. ICLR 2014.\n[7] Salah Rifai, et al.\n“Contractive auto-encoders: Explicit invariance during feature extraction.”\nICML, 2011.\n[8] Diederik P. Kingma, and Max Welling.\n“Auto-encoding variational bayes.”\nICLR 2014.\n[9]\nTutorial - What is a variational autoencoder?\non jaan.io\n[10] Youtube tutorial:\nVariational Autoencoders\nby Arxiv Insights\n[11]\n“A Beginner’s Guide to Variational Methods: Mean-Field Approximation”\nby Eric Jang.\n[12] Carl Doersch.\n“Tutorial on variational autoencoders.”\narXiv:1606.05908, 2016.\n[13] Irina Higgins, et al.\n\"$\\beta$-VAE: Learning basic visual concepts with a constrained variational framework.\"\nICLR 2017.\n[14] Christopher P. Burgess, et al.\n“Understanding disentangling in beta-VAE.”\nNIPS 2017.\n[15] Aaron van den Oord, et al.\n“Neural Discrete Representation Learning”\nNIPS 2017.\n[16] Ali Razavi, et al.\n“Generating Diverse High-Fidelity Images with VQ-VAE-2”\n. arXiv preprint arXiv:1906.00446 (2019).\n[17] Xi Chen, et al.\n“PixelSNAIL: An Improved Autoregressive Generative Model.”\narXiv preprint arXiv:1712.09763 (2017).\n[18] Karol Gregor, et al.\n“Temporal Difference Variational Auto-Encoder.”\nICLR 2019.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:30Z",
            "title": "From Autoencoder to Beta-VAE | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/cd59f7ee3fdb/code/body-000.txt",
                "chars": 217,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "bytes": 2880250,
                "reused": true,
                "local_path": "papers/repair/d99773f380c6f82310b0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.5663",
                "bytes": 706768,
                "reused": true,
                "local_path": "papers/repair/e1b2d4f9537bfbb215c7.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "bytes": 267801,
                "reused": true,
                "local_path": "papers/repair/6d5b1a69e0c9e22de627.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6114",
                "bytes": 3926758,
                "reused": true,
                "local_path": "papers/repair/24a95827202f9fab26f8.pdf"
              },
              {
                "status": "http_404",
                "url": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "retried_at": "2026-10-20T17:54:22Z"
              },
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "bytes": 259807,
                "reused": true,
                "local_path": "papers/repair/ae05bcdf53e441d54399.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599.pdf",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/ed1564965a62d0f95223.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "bytes": 3122746,
                "reused": true,
                "local_path": "papers/repair/dff42138c902f52546e6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00446",
                "bytes": 6893777,
                "reused": true,
                "local_path": "papers/repair/68bf92a125a336073fe6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.09763",
                "bytes": 1060212,
                "reused": true,
                "local_path": "papers/repair/19837883f1a7b093c101.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03107",
                "bytes": 1744116,
                "reused": true,
                "local_path": "papers/repair/7421e1d74410b7ee80f1.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "retried_at": "2026-10-20T17:54:23Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": true,
                "local_path": "papers/repair/ba774392059407ff35bb.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "bytes": 1392544,
                "reused": true,
                "local_path": "papers/repair/13ac6bde4ea85d886602.pdf"
              },
              {
                "status": "ok",
                "url": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "bytes": 596707,
                "reused": true,
                "local_path": "papers/repair/7c5b86e9a0f9c9cfd6a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.05908",
                "bytes": 880152,
                "reused": true,
                "local_path": "papers/repair/673de34731baf973c156.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/cecf133ac21e33fa774b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00937",
                "bytes": 3174661,
                "reused": true,
                "local_path": "papers/repair/6daef1429a7c6c36146a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33692,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404",
            "raw_html": "attachments/cd59f7ee3fdb/pages/source.html",
            "local_html": "attachments/cd59f7ee3fdb/pages/article.html",
            "body_base_path": "attachments/cd59f7ee3fdb/pages/",
            "body_markdown_path": "attachments/cd59f7ee3fdb/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Autoencoder",
                "label": "the 1980s",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.459.3788&rep=rep1&type=pdf",
                "label": "Hinton & Salakhutdinov, 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dimensionality_reduction",
                "label": "dimensionality reduction",
                "type": "a"
              },
              {
                "href": "https://ai.googleblog.com/2016/09/image-compression-with-neural-networks.html",
                "label": "decompression",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "label": "Hinton, et al. 2012",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/neural-networks-1/",
                "label": "activation functions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.5663",
                "label": "Makhzani and Frey, 2013",
                "type": "a"
              },
              {
                "href": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "label": "Rifai, et al, 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.6114",
                "label": "Kingma & Welling, 2014",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback-Leibler divergence",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2016/08/variational-bayes.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=Sy2fzU9gl",
                "label": "Higgins et al., 2017",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "label": "KKT condition",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.03599.pdf",
                "label": "Burgess, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "information bottleneck theory",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "label": "van den Oord, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "KNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00446",
                "label": "Ali Razavi, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.09763",
                "label": "PixelSNAIL; Chen et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03107",
                "label": "Gregor et al., 2019",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "label": "“Reducing the dimensionality of data with neural networks.”",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "“Extracting and composing robust features with denoising autoencoders.”",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "label": "“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "label": "Sparse Autoencoder",
                "type": "a"
              },
              {
                "href": "https://jaan.io/what-is-variational-autoencoder-vae-tutorial/",
                "label": "Tutorial - What is a variational autoencoder?",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "label": "Variational Autoencoders",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.05908",
                "label": "“Tutorial on variational autoencoders.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.03599",
                "label": "“Understanding disentangling in beta-VAE.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00937",
                "label": "“Neural Discrete Representation Learning”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
          "status": "ok",
          "article_id": "95e296d541c5",
          "local_path": "series-follow/1602/repair/0131ab3df6b3801717f6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
              "bytes": 378234,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/42322906964d7eff1651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
              "bytes": 283407,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f9b6ebe483799e46cae4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
              "bytes": 228747,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0ea74210b7f6fad038ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
              "bytes": 213880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9dbbde4fd84a2ab2174a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
              "bytes": 499620,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b1980ce4c249a0e87c8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
              "bytes": 104570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a4dc57fb545108aefd87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
              "bytes": 302909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3165312c8d71a60275e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
              "bytes": 317756,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9c33dac85d8f8acfff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
              "bytes": 836105,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/54a750cb98f126791091.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
              "bytes": 457704,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/822dbc554a0a4c217494.png"
            }
          ],
          "article": {
            "id": "95e296d541c5",
            "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "bytes": 378234,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-42322906964d7eff1651.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "bytes": 283407,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-f9b6ebe483799e46cae4.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "bytes": 228747,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-0ea74210b7f6fad038ef.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "bytes": 213880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9dbbde4fd84a2ab2174a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "bytes": 499620,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-b1980ce4c249a0e87c8a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "bytes": 104570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-a4dc57fb545108aefd87.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "bytes": 302909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-3165312c8d71a60275e1.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "bytes": 317756,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9c33dac85d8f8acfff22.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "bytes": 836105,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-54a750cb98f126791091.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "bytes": 457704,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-822dbc554a0a4c217494.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "So far, I’ve written about two types of generative models,\nGAN\nand\nVAE\n. Neither of them explicitly learns the probability density function of real data, $p(\\mathbf{x})$ (where $\\mathbf{x} \\in \\mathcal{D}$) — because it is really hard! Taking the generative model with latent variables as an example, $p(\\mathbf{x}) = \\int p(\\mathbf{x}\\vert\\mathbf{z})p(\\mathbf{z})d\\mathbf{z}$ can hardly be calculated as it is intractable to go through all possible values of the latent code $\\mathbf{z}$.\nFlow-based deep generative models conquer this hard problem with the help of\nnormalizing flows\n, a powerful statistics tool for density estimation. A good estimation of $p(\\mathbf{x})$ makes it possible to efficiently complete many downstream tasks: sample unobserved but realistic new data points (data generation), predict the rareness of future events (density estimation), infer latent variables, fill in incomplete data samples, etc.\nTypes of Generative Models\n#\nHere is a quick summary of the difference between GAN, VAE, and flow-based generative models:\nGenerative adversarial networks: GAN provides a smart solution to model the data generation, an unsupervised learning problem, as a supervised one. The discriminator model learns to distinguish the real data from the fake samples that are produced by the generator model. Two models are trained as they are playing a\nminimax\ngame.\nVariational autoencoders: VAE inexplicitly optimizes the log-likelihood of the data by maximizing the evidence lower bound (ELBO).\nFlow-based generative models: A flow-based generative model is constructed by a sequence of invertible transformations. Unlike other two, the model explicitly learns the data distribution $p(\\mathbf{x})$ and therefore the loss function is simply the negative log-likelihood.\nComparison of three categories of generative models.\nLinear Algebra Basics Recap\n#\nWe should understand two key concepts before getting into the flow-based generative model: the Jacobian determinant and the change of variable rule. Pretty basic, so feel free to skip.\nJacobian Matrix and Determinant\n#\nGiven a function of mapping a $n$-dimensional input vector $\\mathbf{x}$ to a $m$-dimensional output vector, $\\mathbf{f}: \\mathbb{R}^n \\mapsto \\mathbb{R}^m$, the matrix of all first-order partial derivatives of this function is called the\nJacobian matrix\n, $\\mathbf{J}$ where one entry on the i-th row and j-th column is $\\mathbf{J}_{ij} = \\frac{\\partial f_i}{\\partial x_j}$.\n$$\n\\mathbf{J} = \\begin{bmatrix}\n\\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\[6pt]\n\\vdots & \\ddots & \\vdots \\\\[6pt]\n\\frac{\\partial f_m}{\\partial x_1} & \\dots & \\frac{\\partial f_m}{\\partial x_n} \\\\[6pt]\n\\end{bmatrix}\n$$\nThe determinant is one real number computed as a function of all the elements in a squared matrix. Note that the determinant\nonly exists for\nsquare\nmatrices\n. The absolute value of the determinant can be thought of as a measure of\n“how much multiplication by the matrix expands or contracts space”.\nThe determinant of a nxn matrix $M$ is:\n$$\n\\det M = \\det \\begin{bmatrix}\na_{11} & a_{12} & \\dots & a_{1n} \\\\\na_{21} & a_{22} & \\dots & a_{2n} \\\\\n\\vdots & \\vdots & & \\vdots \\\\\na_{n1} & a_{n2} & \\dots & a_{nn} \\\\\n\\end{bmatrix} = \\sum_{j_1 j_2 \\dots j_n} (-1)^{\\tau(j_1 j_2 \\dots j_n)} a_{1j_1} a_{2j_2} \\dots a_{nj_n}\n$$\nwhere the subscript under the summation $j_1 j_2 \\dots j_n$ are all permutations of the set {1, 2, …, n}, so there are $n!$ items in total; $\\tau(.)$ indicates the\nsignature\nof a permutation.\nThe determinant of a square matrix $M$ detects whether it is invertible: If $\\det(M)=0$ then $M$ is not invertible (a\nsingular\nmatrix with linearly dependent rows or columns; or any row or column is all 0); otherwise, if $\\det(M)\\neq 0$, $M$ is invertible.\nThe determinant of the product is equivalent to the product of the determinants: $\\det(AB) = \\det(A)\\det(B)$. (\nproof\n)\nChange of Variable Theorem\n#\nLet’s review the change of variable theorem specifically in the context of probability density estimation, starting with a single variable case.\nGiven a random variable $z$ and its known probability density function $z \\sim \\pi(z)$, we would like to construct a new random variable using a 1-1 mapping function $x = f(z)$. The function $f$ is invertible, so $z=f^{-1}(x)$. Now the question is\nhow to infer the unknown probability density function of the new variable\n, $p(x)$?\n$$\n\\begin{aligned}\n& \\int p(x)dx = \\int \\pi(z)dz = 1 \\scriptstyle{\\text{   ; Definition of probability distribution.}}\\\\\n& p(x) = \\pi(z) \\left\\vert\\frac{dz}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\left\\vert\\frac{d f^{-1}}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\vert (f^{-1})'(x) \\vert\n\\end{aligned}\n$$\nBy definition, the integral $\\int \\pi(z)dz$ is the sum of an infinite number of rectangles of infinitesimal width $\\Delta z$. The height of such a rectangle at position $z$ is the value of the density function $\\pi(z)$. When we substitute the variable, $z = f^{-1}(x)$ yields $\\frac{\\Delta z}{\\Delta x} = (f^{-1}(x))’$ and $\\Delta z =  (f^{-1}(x))’ \\Delta x$. Here $\\vert(f^{-1}(x))’\\vert$ indicates the ratio between the area of rectangles defined in two different coordinate of variables $z$ and $x$ respectively.\nThe multivariable version has a similar format:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim \\pi(\\mathbf{z}), \\mathbf{x} = f(\\mathbf{z}), \\mathbf{z} = f^{-1}(\\mathbf{x}) \\\\\np(\\mathbf{x}) \n&= \\pi(\\mathbf{z}) \\left\\vert \\det \\dfrac{d \\mathbf{z}}{d \\mathbf{x}} \\right\\vert  \n= \\pi(f^{-1}(\\mathbf{x})) \\left\\vert \\det \\dfrac{d f^{-1}}{d \\mathbf{x}} \\right\\vert\n\\end{aligned}\n$$\nwhere $\\det \\frac{\\partial f}{\\partial\\mathbf{z}}$ is the Jacobian determinant of the function $f$. The full proof of the multivariate version is out of the scope of this post; ask Google if interested ;)\nWhat is Normalizing Flows?\n#\nBeing able to do good density estimation has direct applications in many machine learning problems, but it is very hard. For example, since we need to run backward propagation in deep learning models, the embedded probability distribution (i.e. posterior $p(\\mathbf{z}\\vert\\mathbf{x})$) is expected to be simple enough to calculate the derivative easily and efficiently. That is why Gaussian distribution is often used in latent variable generative models, even though most of real world distributions are much more complicated than Gaussian.\nHere comes a\nNormalizing Flow\n(NF) model for better and more powerful distribution approximation. A normalizing flow transforms a simple distribution into a complex one by applying a sequence of invertible transformation functions. Flowing through a chain of transformations, we repeatedly substitute the variable for the new one according to the change of variables theorem and eventually obtain a probability distribution of the final target variable.\nIllustration of a normalizing flow model, transforming a simple distribution $p\\_0(\\mathbf{z}\\_0)$ to a complex one $p\\_K(\\mathbf{z}\\_K)$ step by step.\nAs defined in Fig. 2,\n$$\n\\begin{aligned}\n\\mathbf{z}_{i-1} &\\sim p_{i-1}(\\mathbf{z}_{i-1}) \\\\\n\\mathbf{z}_i &= f_i(\\mathbf{z}_{i-1})\\text{, thus }\\mathbf{z}_{i-1} = f_i^{-1}(\\mathbf{z}_i) \\\\\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert\n\\end{aligned}\n$$\nThen let’s convert the equation to be a function of $\\mathbf{z}_i$ so that we can do inference with the base distribution.\n$$\n\\begin{aligned}\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\left\\vert \\det \\color{red}{\\Big(\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\Big)^{-1}} \\right\\vert & \\scriptstyle{\\text{; According to the inverse func theorem.}} \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\color{red}{\\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert^{-1}} & \\scriptstyle{\\text{; According to a property of Jacobians of invertible func.}} \\\\\n\\log p_i(\\mathbf{z}_i) &= \\log p_{i-1}(\\mathbf{z}_{i-1}) - \\log \\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert\n\\end{aligned}\n$$\n(*) A note on the\n“inverse function theorem”\n: If $y=f(x)$ and $x=f^{-1}(y)$, we have:\n$$\n\\dfrac{df^{-1}(y)}{dy} = \\dfrac{dx}{dy} = (\\dfrac{dy}{dx})^{-1} = (\\dfrac{df(x)}{dx})^{-1}\n$$\n(*) A note on\n“Jacobians of invertible function”\n: The determinant of the inverse of an invertible matrix is the inverse of the determinant: $\\det(M^{-1}) = (\\det(M))^{-1}$,\nbecause\n$\\det(M)\\det(M^{-1}) = \\det(M \\cdot M^{-1}) = \\det(I) = 1$.\nGiven such a chain of probability density functions, we know the relationship between each pair of consecutive variables. We can expand the equation of the output $\\mathbf{x}$ step by step until tracing back to the initial distribution $\\mathbf{z}_0$.\n$$\n\\begin{aligned}\n\\mathbf{x} = \\mathbf{z}_K &= f_K \\circ f_{K-1} \\circ \\dots \\circ f_1 (\\mathbf{z}_0) \\\\\n\\log p(\\mathbf{x}) = \\log \\pi_K(\\mathbf{z}_K) \n&= \\log \\pi_{K-1}(\\mathbf{z}_{K-1}) - \\log\\left\\vert\\det\\dfrac{d f_K}{d \\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\log \\pi_{K-2}(\\mathbf{z}_{K-2}) - \\log\\left\\vert\\det\\dfrac{d f_{K-1}}{d\\mathbf{z}_{K-2}}\\right\\vert - \\log\\left\\vert\\det\\dfrac{d f_K}{d\\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\dots \\\\\n&= \\log \\pi_0(\\mathbf{z}_0) - \\sum_{i=1}^K \\log\\left\\vert\\det\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\right\\vert\n\\end{aligned}\n$$\nThe path traversed by the random variables $\\mathbf{z}_i = f_i(\\mathbf{z}_{i-1})$ is the\nflow\nand the full chain formed by the successive distributions $\\pi_i$ is called a\nnormalizing flow\n. Required by the computation in the equation, a transformation function $f_i$ should satisfy two properties:\nIt is easily invertible.\nIts Jacobian determinant is easy to compute.\nModels with Normalizing Flows\n#\nWith normalizing flows in our toolbox, the exact log-likelihood of input data $\\log p(\\mathbf{x})$ becomes tractable. As a result, the training criterion of flow-based generative model is simply the negative log-likelihood (NLL) over the training dataset $\\mathcal{D}$:\n$$\n\\mathcal{L}(\\mathcal{D}) = - \\frac{1}{\\vert\\mathcal{D}\\vert}\\sum_{\\mathbf{x} \\in \\mathcal{D}} \\log p(\\mathbf{x})\n$$\nRealNVP\n#\nThe\nRealNVP\n(Real-valued Non-Volume Preserving;\nDinh et al., 2017\n) model implements a normalizing flow by stacking a sequence of invertible bijective transformation functions. In each bijection $f: \\mathbf{x} \\mapsto \\mathbf{y}$, known as\naffine coupling layer\n,  the input dimensions are split into two parts:\nThe first $d$ dimensions stay same;\nThe second part, $d+1$ to $D$ dimensions, undergo an affine transformation (“scale-and-shift”) and both the scale and shift parameters are functions of the first $d$ dimensions.\n$$\n\\begin{aligned}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{aligned}\n$$\nwhere $s(.)$ and $t(.)$ are\nscale\nand\ntranslation\nfunctions and both map $\\mathbb{R}^d \\mapsto \\mathbb{R}^{D-d}$. The $\\odot$ operation is the element-wise product.\nNow let’s check whether this transformation satisfy two basic properties  for a flow transformation.\nCondition 1\n: “It is easily invertible.”\nYes and it is fairly straightforward.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= (\\mathbf{y}_{d+1:D} - t(\\mathbf{y}_{1:d})) \\odot \\exp(-s(\\mathbf{y}_{1:d}))\n\\end{cases}\n$$\nCondition 2\n: “Its Jacobian determinant is easy to compute.”\nYes. It is not hard to get the Jacobian matrix and determinant of this transformation. The Jacobian is a lower triangular matrix.\n$$\n\\mathbf{J} = \n\\begin{bmatrix}\n  \\mathbb{I}_d & \\mathbf{0}_{d\\times(D-d)} \\\\[5pt]\n  \\frac{\\partial \\mathbf{y}_{d+1:D}}{\\partial \\mathbf{x}_{1:d}} & \\text{diag}(\\exp(s(\\mathbf{x}_{1:d})))\n\\end{bmatrix}\n$$\nHence the determinant is simply the product of terms on the diagonal.\n$$\n\\det(\\mathbf{J}) \n= \\prod_{j=1}^{D-d}\\exp(s(\\mathbf{x}_{1:d}))_j\n= \\exp(\\sum_{j=1}^{D-d} s(\\mathbf{x}_{1:d})_j)\n$$\nSo far, the affine coupling layer looks perfect for constructing a normalizing flow :)\nEven better, since (i) computing $f^-1$ does not require computing the inverse of $s$ or $t$ and (ii) computing the Jacobian determinant does not involve computing the Jacobian of $s$ or $t$, those functions can be\narbitrarily complex\n; i.e. both $s$ and $t$ can be modeled by deep neural networks.\nIn one affine coupling layer, some dimensions (channels) remain unchanged. To make sure all the inputs have a chance to be altered, the model reverses the ordering in each layer so that different components are left unchanged. Following such an alternating pattern, the set of units which remain identical in one transformation layer are always modified in the next. Batch normalization is found to help training models with a very deep stack of coupling layers.\nFurthermore, RealNVP can work in a multi-scale architecture to build a more efficient model for large inputs. The multi-scale architecture applies several “sampling” operations to normal affine layers, including spatial checkerboard pattern masking, squeezing operation, and channel-wise masking. Read the\npaper\nfor more details on the multi-scale architecture.\nNICE\n#\nThe\nNICE\n(Non-linear Independent Component Estimation;\nDinh, et al. 2015\n) model is a predecessor of\nRealNVP\n. The transformation in NICE is the affine coupling layer without the scale term, known as\nadditive coupling layer\n.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} + m(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= \\mathbf{y}_{d+1:D} - m(\\mathbf{y}_{1:d})\n\\end{cases}\n$$\nGlow\n#\nThe\nGlow\n(\nKingma and Dhariwal, 2018\n) model extends the previous reversible generative models, NICE and RealNVP, and simplifies the architecture by replacing the reverse permutation operation on the channel ordering with invertible 1x1 convolutions.\nOne step of flow in the Glow model. (Image source:\nKingma and Dhariwal, 2018\n)\nThere are three substeps in one step of flow in Glow.\nSubstep 1:\nActivation normalization\n(short for “actnorm”)\nIt performs an affine transformation using a scale and bias parameter per channel, similar to batch normalization, but works for mini-batch size 1. The parameters are trainable but initialized so that the first minibatch of data have mean 0 and standard deviation 1 after actnorm.\nSubstep 2:\nInvertible 1x1 conv\nBetween layers of the RealNVP flow, the ordering of channels is reversed so that all the data dimensions have a chance to be altered. A 1×1 convolution with equal number of input and output channels is\na generalization of any permutation\nof the channel ordering.\nSay, we have an invertible 1x1 convolution of an input $h \\times w \\times c$ tensor $\\mathbf{h}$ with a weight matrix $\\mathbf{W}$ of size $c \\times c$. The output is a $h \\times w \\times c$ tensor, labeled as $f = \\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})$. In order to apply the change of variable rule, we need to compute the Jacobian determinant $\\vert \\det\\partial f / \\partial\\mathbf{h}\\vert$.\nBoth the input and output of 1x1 convolution here can be viewed as a matrix of size $h \\times w$. Each entry $\\mathbf{x}_{ij}$ ($i=1,\\dots,h, j=1,\\dots,w$) in $\\mathbf{h}$ is a vector of $c$ channels and each entry is multiplied by the weight matrix $\\mathbf{W}$ to obtain the corresponding entry $\\mathbf{y}_{ij}$ in the output matrix respectively. The derivative of each entry is $\\partial \\mathbf{x}_{ij} \\mathbf{W} / \\partial\\mathbf{x}_{ij} = \\mathbf{W}$ and there are $h \\times w$ such entries in total:\n$$\n\\log \\left\\vert\\det \\frac{\\partial\\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})}{\\partial\\mathbf{h}}\\right\\vert\n= \\log (\\vert\\det\\mathbf{W}\\vert^{h \\cdot w}\\vert) = h \\cdot w \\cdot \\log \\vert\\det\\mathbf{W}\\vert\n$$\nThe inverse 1x1 convolution depends on the inverse matrix $\\mathbf{W}^{-1}$. Since the weight matrix is relatively small, the amount of computation for the matrix determinant (\ntf.linalg.det\n) and inversion (\ntf.linalg.inv\n) is still under control.\nSubstep 3:\nAffine coupling layer\nThe design is same as in RealNVP.\nThree substeps in one step of flow in Glow. (Image source:\nKingma and Dhariwal, 2018\n)\nModels with Autoregressive Flows\n#\nThe\nautoregressive\nconstraint is a way to model sequential data, $\\mathbf{x} = [x_1, \\dots, x_D]$: each output only depends on the data observed in the past, but not on the future ones. In other words, the probability of observing $x_i$ is conditioned on $x_1, \\dots, x_{i-1}$ and the product of these conditional probabilities gives us the probability of observing the full sequence:\n$$\np(\\mathbf{x}) = \\prod_{i=1}^{D} p(x_i\\vert x_1, \\dots, x_{i-1}) = \\prod_{i=1}^{D} p(x_i\\vert x_{1:i-1})\n$$\nHow to model the conditional density is of your choice. It can be a univariate Gaussian with mean and standard deviation computed as a function of $x_{1:i-1}$, or a multilayer neural network with $x_{1:i-1}$ as the input.\nIf a flow transformation in a normalizing flow is framed as an autoregressive model — each dimension in a vector variable is conditioned on the previous dimensions — this is an\nautoregressive flow\n.\nThis section starts with several classic autoregressive models (MADE, PixelRNN, WaveNet) and then we dive into autoregressive flow models (MAF and IAF).\nMADE\n#\nMADE\n(Masked Autoencoder for Distribution Estimation;\nGermain et al., 2015\n) is a specially designed architecture to enforce the autoregressive property in the autoencoder\nefficiently\n. When using an autoencoder to predict the conditional probabilities, rather than feeding the autoencoder with input of different observation windows $D$ times, MADE removes the contribution from certain hidden units by multiplying binary mask matrices so that each input dimension is reconstructed only from previous dimensions in a\ngiven\nordering in a\nsingle pass\n.\nIn a multilayer fully-connected neural network, say, we have $L$ hidden layers with weight matrices $\\mathbf{W}^1, \\dots, \\mathbf{W}^L$ and an output layer with weight matrix $\\mathbf{V}$. The output $\\hat{\\mathbf{x}}$ has each dimension $\\hat{x}_i = p(x_i\\vert x_{1:i-1})$.\nWithout any mask, the computation through layers looks like the following:\n$$\n\\begin{aligned}\n\\mathbf{h}^0 &= \\mathbf{x} \\\\\n\\mathbf{h}^l &= \\text{activation}^l(\\mathbf{W}^l\\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma(\\mathbf{V}\\mathbf{h}^L + \\mathbf{c})\n\\end{aligned}\n$$\nDemonstration of how MADE works in a three-layer feed-forward neural network. (Image source:\nGermain et al., 2015\n)\nTo zero out some connections between layers, we can simply element-wise multiply every weight matrix by a binary mask matrix. Each hidden node is assigned with a random “connectivity integer” between $1$ and $D-1$; the assigned value for the $k$-th unit in the $l$-th layer is denoted by $m^l_k$. The binary mask matrix is determined by element-wise comparing values of two nodes in two layers.\n$$\n\\begin{aligned}\n\\mathbf{h}^l &= \\text{activation}^l((\\mathbf{W}^l \\color{red}{\\odot \\mathbf{M}^{\\mathbf{W}^l}}) \\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma((\\mathbf{V} \\color{red}{\\odot \\mathbf{M}^{\\mathbf{V}}}) \\mathbf{h}^L + \\mathbf{c}) \\\\\nM^{\\mathbf{W}^l}_{k', k} \n&= \\mathbf{1}_{m^l_{k'} \\geq m^{l-1}_k} \n= \\begin{cases}\n    1, & \\text{if } m^l_{k'} \\geq m^{l-1}_k\\\\\n    0, & \\text{otherwise}\n\\end{cases} \\\\\nM^{\\mathbf{V}}_{d, k} \n&= \\mathbf{1}_{d \\geq m^L_k} \n= \\begin{cases}\n    1, & \\text{if } d > m^L_k\\\\\n    0, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nA unit in the current layer can only be connected to other units with equal or smaller numbers in the previous layer and this type of dependency easily propagates through the network up to the output layer. Once the numbers are assigned to all the units and layers, the ordering of input dimensions is fixed and the conditional probability is produced with respect to it.  See a great illustration in To make sure all the hidden units are connected to the input and output layers through some paths, the $m^l_k$ is sampled to be equal or greater than the minimal connectivity integer in the previous layer, $\\min_{k’} m_{k’}^{l-1}$.\nMADE training can be further facilitated by:\nOrder-agnostic training\n: shuffle the input dimensions, so that MADE is able to model any arbitrary ordering; can create an ensemble of autoregressive models at the runtime.\nConnectivity-agnostic training\n: to avoid a model being tied up to a specific connectivity pattern constraints, resample $m^l_k$ for each training minibatch.\nPixelRNN\n#\nPixelRNN (\nOord et al, 2016\n) is a deep generative model for images. The image is generated one pixel at a time and each new pixel is sampled conditional on the pixels that have been seen before.\nLet’s consider an image of size $n \\times n$, $\\mathbf{x} = \\{x_1, \\dots, x_{n^2}\\}$, the model starts generating pixels from the top left corner, from left to right and top to bottom (See Fig. 6).\nThe context for generating one pixel in PixelRNN. (Image source:\nOord et al, 2016\n)\nEvery pixel $x_i$ is sampled from a probability distribution conditional over the the past context: pixels above it or on the left of it when in the same row. The definition of such context looks pretty arbitrary, because how visual\nattention\nis attended to an image is more flexible. Somehow magically a generative model with such a strong assumption works.\nOne implementation that could capture the entire context is the\nDiagonal BiLSTM\n. First, apply the\nskewing\noperation by offsetting each row of the input feature map by one position with respect to the previous row, so that computation for each row can be parallelized. Then the LSTM states are computed with respect to the current pixel and the pixels on the left.\n(a) PixelRNN with diagonal BiLSTM. (b) Skewing operation that offsets each row in the feature map by one with regards to the row above. (Image source:\nOord et al, 2016\n)\n$$\n\\begin{aligned}\n\\lbrack \\mathbf{o}_i, \\mathbf{f}_i, \\mathbf{i}_i, \\mathbf{g}_i \\rbrack &= \\sigma(\\mathbf{K}^{ss} \\circledast \\mathbf{h}_{i-1} + \\mathbf{K}^{is} \\circledast \\mathbf{x}_i) & \\scriptstyle{\\text{; }\\sigma\\scriptstyle{\\text{ is tanh for g, but otherwise sigmoid; }}\\circledast\\scriptstyle{\\text{ is convolution operation.}}} \\\\\n\\mathbf{c}_i &= \\mathbf{f}_i \\odot \\mathbf{c}_{i-1} + \\mathbf{i}_i \\odot \\mathbf{g}_i & \\scriptstyle{\\text{; }}\\odot\\scriptstyle{\\text{ is elementwise product.}}\\\\\n\\mathbf{h}_i &= \\mathbf{o}_i \\odot \\tanh(\\mathbf{c}_i)\n\\end{aligned}\n$$\nwhere $\\circledast$ denotes the convolution operation and $\\odot$ is the element-wise multiplication. The input-to-state component $\\mathbf{K}^{is}$ is a 1x1 convolution, while the state-to-state recurrent component is computed with a column-wise convolution $\\mathbf{K}^{ss}$ with a kernel of size 2x1.\nThe diagonal BiLSTM layers are capable of processing an unbounded context field, but expensive to compute due to the sequential dependency between states. A faster implementation uses multiple convolutional layers without pooling to define a bounded context box. The convolution kernel is masked so that the future context is not seen, similar to\nMADE\n. This convolution version is called\nPixelCNN\n.\nPixelCNN with masked convolution constructed by an elementwise product of a mask tensor and the convolution kernel before applying it. (Image source: http://slazebni.cs.illinois.edu/spring17/lec13_advanced.pdf)\nWaveNet\n#\nWaveNet\n(\nVan Den Oord, et al. 2016\n) is very similar to PixelCNN but applied to 1-D audio signals. WaveNet consists of a stack of\ncausal convolution\nwhich is a convolution operation designed to respect the ordering: the prediction at a certain timestamp can only consume the data observed in the past, no dependency on the future. In PixelCNN, the causal convolution is implemented by masked convolution kernel. The causal convolution in WaveNet is simply to shift the output by a number of timestamps to the future so that the output is aligned with the last input element.\nOne big drawback of convolution layer is a very limited size of receptive field. The output can hardly depend on the input hundreds or thousands of timesteps ago, which can be a crucial requirement for modeling long sequences. WaveNet therefore adopts\ndilated convolution\n(\nanimation\n), where the kernel is applied to an evenly-distributed subset of samples in a much larger receptive field of the input.\nVisualization of WaveNet models with a stack of (top) causal convolution layers and (bottom) dilated convolution layers. (Image source:\nVan Den Oord, et al. 2016\n)\nWaveNet uses the gated activation unit as the non-linear layer, as it is found to work significantly better than ReLU for modeling 1-D audio data. The residual connection is applied after the gated activation.\n$$\n\\mathbf{z} = \\tanh(\\mathbf{W}_{f,k}\\circledast\\mathbf{x})\\odot\\sigma(\\mathbf{W}_{g,k}\\circledast\\mathbf{x})\n$$\nwhere $\\mathbf{W}_{f,k}$ and $\\mathbf{W}_{g,k}$ are convolution filter and gate weight matrix of the $k$-th layer, respectively; both are learnable.\nMasked Autoregressive Flow\n#\nMasked Autoregressive Flow\n(\nMAF\n;\nPapamakarios et al., 2017\n) is a type of normalizing flows, where the transformation layer is built as an autoregressive neural network. MAF is very similar to\nInverse Autoregressive Flow\n(IAF) introduced later. See more discussion on the relationship between MAF and IAF in the next section.\nGiven two random variables, $\\mathbf{z} \\sim \\pi(\\mathbf{z})$ and $\\mathbf{x} \\sim p(\\mathbf{x})$ and the probability density function $\\pi(\\mathbf{z})$ is known, MAF aims to learn $p(\\mathbf{x})$. MAF generates each $x_i$ conditioned on the past dimensions $\\mathbf{x}_{1:i-1}$.\nPrecisely the conditional probability is an affine transformation of $\\mathbf{z}$, where the scale and shift terms are functions of the observed part of $\\mathbf{x}$.\nData generation, producing a new $\\mathbf{x}$:\n$x_i \\sim p(x_i\\vert\\mathbf{x}_{1:i-1}) = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})\\text{, where }\\mathbf{z} \\sim \\pi(\\mathbf{z})$\nDensity estimation, given a known $\\mathbf{x}$:\n$p(\\mathbf{x}) = \\prod_{i=1}^D p(x_i\\vert\\mathbf{x}_{1:i-1})$\nThe generation procedure is sequential, so it is slow by design. While density estimation only needs one pass the network using architecture like\nMADE\n. The transformation function is trivial to inverse and the Jacobian determinant is easy to compute too.\nInverse Autoregressive Flow\n#\nSimilar to MAF,\nInverse autoregressive flow\n(\nIAF\n;\nKingma et al., 2016\n) models the conditional probability of the target variable as an autoregressive model too, but with a reversed flow, thus achieving a much efficient sampling process.\nFirst, let’s reverse the affine transformation in MAF:\n$$\nz_i = \\frac{x_i - \\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} + x_i \\odot \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n$$\nIf let:\n$$\n\\begin{aligned}\n& \\tilde{\\mathbf{x}} = \\mathbf{z}\\text{, }\\tilde{p}(.) = \\pi(.)\\text{, }\\tilde{\\mathbf{x}} \\sim \\tilde{p}(\\tilde{\\mathbf{x}}) \\\\\n& \\tilde{\\mathbf{z}} = \\mathbf{x} \\text{, }\\tilde{\\pi}(.) = p(.)\\text{, }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\\\\\n& \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\mu}_i(\\mathbf{x}_{1:i-1}) = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} \\\\\n& \\tilde{\\sigma}(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\sigma}(\\mathbf{x}_{1:i-1}) = \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n\\end{aligned}\n$$\nThen we would have,\n$$\n\\tilde{x}_i \\sim p(\\tilde{x}_i\\vert\\tilde{\\mathbf{z}}_{1:i}) = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})\n\\text{, where }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\n$$\nIAF intends to estimate the probability density function of $\\tilde{\\mathbf{x}}$ given that $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$ is already known. The inverse flow is an autoregressive affine transformation too, same as in MAF, but the scale and shift terms are autoregressive functions of observed variables from the known distribution $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$. See the comparison between MAF and IAF in\nComparison of MAF and IAF.  The variable with known density is in green while the unknown one is in red.\nComputations of the individual elements $\\tilde{x}_i$ do not depend on each other, so they are easily parallelizable (only one pass using MADE). The density estimation for a known $\\tilde{\\mathbf{x}}$ is not efficient, because we have to recover the value of $\\tilde{z}_i$ in a sequential order, $\\tilde{z}_i = (\\tilde{x}_i - \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})) / \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1})$, thus D times in total.\nBase distribution\nTarget distribution\nModel\nData generation\nDensity estimation\nMAF\n$\\mathbf{z}\\sim\\pi(\\mathbf{z})$\n$\\mathbf{x}\\sim p(\\mathbf{x})$\n$x_i = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})$\nSequential; slow\nOne pass; fast\nIAF\n$\\tilde{\\mathbf{z}}\\sim\\tilde{\\pi}(\\tilde{\\mathbf{z}})$\n$\\tilde{\\mathbf{x}}\\sim\\tilde{p}(\\tilde{\\mathbf{x}})$\n$\\tilde{x}_i  = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})$\nOne pass; fast\nSequential; slow\n———-\n———-\n———-\n———-\n———-\n———-\nVAE + Flows\n#\nIn\nVariational Autoencoder\n, if we want to model the posterior $p(\\mathbf{z}\\vert\\mathbf{x})$ as a more complicated distribution rather than simple Gaussian. Intuitively we can use normalizing flow to transform the base Gaussian for better density approximation. The encoder then would predict a set of scale and shift terms $(\\mu_i, \\sigma_i)$ which are all functions of input $\\mathbf{x}$. Read the\npaper\nfor more details if interested.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be very happy to correct them right away!\nSee you in the next post :D\nCited as:\n@article{weng2018flow,\n  title   = \"Flow-based Deep Generative Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-10-13-flow-models/\"\n}\nReference\n#\n[1] Danilo Jimenez Rezende, and Shakir Mohamed.\n“Variational inference with normalizing flows.”\nICML 2015.\n[2]\nNormalizing Flows Tutorial, Part 1: Distributions and Determinants\nby Eric Jang.\n[3]\nNormalizing Flows Tutorial, Part 2: Modern Normalizing Flows\nby Eric Jang.\n[4]\nNormalizing Flows\nby Adam Kosiorek.\n[5] Laurent Dinh, Jascha Sohl-Dickstein, and Samy Bengio.\n“Density estimation using Real NVP.”\nICLR 2017.\n[6] Laurent Dinh, David Krueger, and Yoshua Bengio.\n“NICE: Non-linear independent components estimation.”\nICLR 2015 Workshop track.\n[7] Diederik P. Kingma, and Prafulla Dhariwal.\n“Glow: Generative flow with invertible 1x1 convolutions.”\narXiv:1807.03039 (2018).\n[8] Germain, Mathieu, Karol Gregor, Iain Murray, and Hugo Larochelle.\n“Made: Masked autoencoder for distribution estimation.”\nICML 2015.\n[9] Aaron van den Oord, Nal Kalchbrenner, and Koray Kavukcuoglu.\n“Pixel recurrent neural networks.”\nICML 2016.\n[10] Diederik P. Kingma, et al.\n“Improved variational inference with inverse autoregressive flow.”\nNIPS. 2016.\n[11] George Papamakarios, Iain Murray, and Theo Pavlakou.\n“Masked autoregressive flow for density estimation.”\nNIPS 2017.\n[12] Jianlin Su, and Guang Wu.\n“f-VAEs: Improve VAEs with Conditional Flows.”\narXiv:1809.05861 (2018).\n[13] Van Den Oord, Aaron, et al.\n“WaveNet: A generative model for raw audio.”\nSSW. 2016.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:34Z",
            "title": "Flow-based Deep Generative Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/95e296d541c5/code/body-000.txt",
                "chars": 231,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05770",
                "bytes": 2901553,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c19a421df88d3d936d27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.08803",
                "bytes": 6681321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d6519de2f9580e55b379.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.8516",
                "bytes": 1717618,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d7013f82bf2a7683aad3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03039",
                "bytes": 13250301,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/60e8d214f8d5c367d55c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03509",
                "bytes": 489445,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5ef7ea5346faa12be094.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06759",
                "bytes": 3015028,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1d8f65c736afa61a5395.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.03499",
                "bytes": 2853802,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/12ed4e68449a6f887358.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.07057",
                "bytes": 1200941,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/298c9ccb8266e330a2f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04934",
                "bytes": 1454651,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7688fe8fd3ce3cbcf849.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.05861",
                "bytes": 9321181,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/8971f265a9c20bb39bab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31712,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/95e296d541c5/pages/source.html",
            "local_html": "attachments/95e296d541c5/pages/article.html",
            "body_base_path": "attachments/95e296d541c5/pages/",
            "body_markdown_path": "attachments/95e296d541c5/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05770",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimax",
                "label": "minimax",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parity_of_a_permutation",
                "label": "signature",
                "type": "a"
              },
              {
                "href": "https://proofwiki.org/wiki/Determinant_of_Matrix_Product",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.08803",
                "label": "Dinh et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.8516",
                "label": "Dinh, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03039",
                "label": "Kingma and Dhariwal, 2018",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/det",
                "label": "tf.linalg.det",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/inv",
                "label": "tf.linalg.inv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03509",
                "label": "Germain et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1601.06759",
                "label": "Oord et al, 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.03499",
                "label": "Van Den Oord, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://github.com/vdumoulin/conv_arithmetic",
                "label": "animation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.07057",
                "label": "Papamakarios et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04934",
                "label": "Kingma et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.05861",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf1.html",
                "label": "Normalizing Flows Tutorial, Part 1: Distributions and Determinants",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf2.html",
                "label": "Normalizing Flows Tutorial, Part 2: Modern Normalizing Flows",
                "type": "a"
              },
              {
                "href": "http://akosiorek.github.io/ml/2018/04/03/norm_flows.html",
                "label": "Normalizing Flows",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/",
          "status": "partial",
          "article_id": "93e53a97f2e3",
          "local_path": "series-follow/1602/repair/2c863d90fb165ef5161e.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/generative-overview.png",
              "bytes": 525595,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/41a09a8696808ecce0b1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM.png",
              "bytes": 839600,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e78e0ba4b34cda911aa0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-example.png",
              "bytes": 4019404,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9f58f5472b55d74decc4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM-algo.png",
              "bytes": 280949,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8f6527c6c3694c587d18.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-beta.png",
              "bytes": 128389,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ea3831d82b483995f8de.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/improved-DDPM-nll.png",
              "bytes": 461423,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2a1b7652ba6cc48a1275.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/conditioned-DDPM.png",
              "bytes": 1535460,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/457cd3bc047052c18add.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDIM-results.png",
              "bytes": 136690,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7b1d616dab0a8609f18b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation.png",
              "bytes": 139161,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/feaad52a803d77f9d89b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation-algo.png",
              "bytes": 337076,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d3eae5a72206efa4852f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models.png",
              "bytes": 531125,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f63895c8c6c047926f5f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models-exp.png",
              "bytes": 701014,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cf193ab727b4044922a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/image-distortion-rate.png",
              "bytes": 858306,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7865196e2489fc001d22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/latent-diffusion-arch.png",
              "bytes": 338942,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/364a0fd3015ab3fcaca4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/cascaded-diffusion.png",
              "bytes": 428232,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/34e80819222058397d52.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/unCLIP.png",
              "bytes": 750479,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/92f9487fb8e9f97c5122.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/U-net.png",
              "bytes": 173159,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7726aba941acd21dd196.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/ControlNet.png",
              "bytes": 96971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7ca77e5b5a81baabf985.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DiT.png",
              "bytes": 106505,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b56eeacd975c4881227f.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "What are Diffusion Models?",
            "keywords": "扩散模型,DDPM,生成模型",
            "domain": "图像处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/",
            "publish_date": "2021-07",
            "corpus_stage": "预训练/SFT",
            "notes": "扩散模型经典入门，被广泛引用为Diffusion必读材料",
            "id": "93e53a97f2e3",
            "collected_at": "2026-10-02T14:12:39",
            "title": "What are Diffusion Models? | Lil'Log",
            "body_markdown": "[Updated on 2021-09-19: Highly recommend this blog post on\nscore-based generative modeling\nby Yang Song (author of several key papers in the references)].\n[Updated on 2022-08-27: Added\nclassifier-free guidance\n,\nGLIDE\n,\nunCLIP\nand\nImagen\n.\n[Updated on 2022-08-31: Added\nlatent diffusion model\n.\n[Updated on 2024-04-13: Added\nprogressive distillation\n,\nconsistency models\n, and the\nModel Architecture section\n.\nSo far, I’ve written about three types of generative models,\nGAN\n,\nVAE\n, and\nFlow-based\nmodels. They have shown great success in generating high-quality samples, but each has some limitations of its own. GAN models are known for potentially unstable training and less diversity in generation due to their adversarial training nature. VAE relies on a surrogate loss. Flow models have to use specialized architectures to construct reversible transform.\nDiffusion models are inspired by non-equilibrium thermodynamics. They define a Markov chain of diffusion steps to slowly add random noise to data and then learn to reverse the diffusion process to construct desired data samples from the noise. Unlike VAE or flow models, diffusion models are learned with a fixed procedure and the latent variable has high dimensionality (same as the original data).\nOverview of different types of generative models.\nWhat are Diffusion Models?\n#\nSeveral diffusion-based generative models have been proposed with similar ideas underneath, including\ndiffusion probabilistic models\n(\nSohl-Dickstein et al., 2015\n),\nnoise-conditioned score network\n(\nNCSN\n;\nYang & Ermon, 2019\n), and\ndenoising diffusion probabilistic models\n(\nDDPM\n;\nHo et al. 2020\n).\nForward diffusion process\n#\nGiven a data point sampled from a real data distribution $\\mathbf{x}_0 \\sim q(\\mathbf{x})$, let us define a\nforward diffusion process\nin which we add small amount of Gaussian noise to the sample in $T$ steps, producing a sequence of noisy samples $\\mathbf{x}_1, \\dots, \\mathbf{x}_T$. The step sizes are controlled by a variance schedule $\\{\\beta_t \\in (0, 1)\\}_{t=1}^T$.\n$$\nq(\\mathbf{x}_t \\vert \\mathbf{x}_{t-1}) = \\mathcal{N}(\\mathbf{x}_t; \\sqrt{1 - \\beta_t} \\mathbf{x}_{t-1}, \\beta_t\\mathbf{I}) \\quad\nq(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_0) = \\prod^T_{t=1} q(\\mathbf{x}_t \\vert \\mathbf{x}_{t-1})\n$$\nThe data sample $\\mathbf{x}_0$ gradually loses its distinguishable features as the step $t$ becomes larger. Eventually when $T \\to \\infty$, $\\mathbf{x}_T$ is equivalent to an isotropic Gaussian distribution.\nThe Markov chain of forward (reverse) diffusion process of generating a sample by slowly adding (removing) noise. (Image source:\nHo et al. 2020\nwith a few additional annotations)\nA nice property of the above process is that we can sample $\\mathbf{x}_t$ at any arbitrary time step $t$ in a closed form using\nreparameterization trick\n. Let $\\alpha_t = 1 - \\beta_t$ and $\\bar{\\alpha}_t = \\prod_{i=1}^t \\alpha_i$:\n$$\n\\begin{aligned}\n\\mathbf{x}_t \n&= \\sqrt{\\alpha_t}\\mathbf{x}_{t-1} + \\sqrt{1 - \\alpha_t}\\boldsymbol{\\epsilon}_{t-1} & \\text{ ;where } \\boldsymbol{\\epsilon}_{t-1}, \\boldsymbol{\\epsilon}_{t-2}, \\dots \\sim \\mathcal{N}(\\mathbf{0}, \\mathbf{I}) \\\\\n&= \\sqrt{\\alpha_t \\alpha_{t-1}} \\mathbf{x}_{t-2} + \\sqrt{1 - \\alpha_t \\alpha_{t-1}} \\bar{\\boldsymbol{\\epsilon}}_{t-2} & \\text{ ;where } \\bar{\\boldsymbol{\\epsilon}}_{t-2} \\text{ merges two Gaussians (*).} \\\\\n&= \\dots \\\\\n&= \\sqrt{\\bar{\\alpha}_t}\\mathbf{x}_0 + \\sqrt{1 - \\bar{\\alpha}_t}\\boldsymbol{\\epsilon} \\\\\nq(\\mathbf{x}_t \\vert \\mathbf{x}_0) &= \\mathcal{N}(\\mathbf{x}_t; \\sqrt{\\bar{\\alpha}_t} \\mathbf{x}_0, (1 - \\bar{\\alpha}_t)\\mathbf{I})\n\\end{aligned}\n$$\n(*) Recall that when we merge two Gaussians  with different variance, $\\mathcal{N}(\\mathbf{0}, \\sigma_1^2\\mathbf{I})$ and $\\mathcal{N}(\\mathbf{0}, \\sigma_2^2\\mathbf{I})$, the new distribution is $\\mathcal{N}(\\mathbf{0}, (\\sigma_1^2 + \\sigma_2^2)\\mathbf{I})$. Here the merged standard deviation is $\\sqrt{(1 - \\alpha_t) + \\alpha_t (1-\\alpha_{t-1})} = \\sqrt{1 - \\alpha_t\\alpha_{t-1}}$.\nUsually, we can afford a larger update step when the sample gets noisier, so $\\beta_1 < \\beta_2 < \\dots < \\beta_T$ and therefore $\\bar{\\alpha}_1 > \\dots > \\bar{\\alpha}_T$.\nConnection with stochastic gradient Langevin dynamics\n#\nLangevin dynamics is a concept from physics, developed for statistically modeling molecular systems. Combined with stochastic gradient descent,\nstochastic gradient Langevin dynamics\n(\nWelling & Teh 2011\n) can produce samples from a probability density $p(\\mathbf{x})$ using only the gradients $\\nabla_\\mathbf{x} \\log p(\\mathbf{x})$ in a Markov chain of updates:\n$$\n\\mathbf{x}_t = \\mathbf{x}_{t-1} + \\frac{\\delta}{2} \\nabla_\\mathbf{x} \\log p(\\mathbf{x}_{t-1}) + \\sqrt{\\delta} \\boldsymbol{\\epsilon}_t\n,\\quad\\text{where }\n\\boldsymbol{\\epsilon}_t \\sim \\mathcal{N}(\\mathbf{0}, \\mathbf{I})\n$$\nwhere $\\delta$ is the step size. When $T \\to \\infty, \\epsilon \\to 0$, $\\mathbf{x}_T$ equals to the true probability density $p(\\mathbf{x})$.\nCompared to standard SGD, stochastic gradient Langevin dynamics injects Gaussian noise into the parameter updates to avoid collapses into local minima.\nReverse diffusion process\n#\nIf we can reverse the above process and sample from $q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t)$, we will be able to recreate the true sample from a Gaussian noise input, $\\mathbf{x}_T \\sim \\mathcal{N}(\\mathbf{0}, \\mathbf{I})$. Note that if $\\beta_t$ is small enough, $q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t)$ will also be Gaussian. Unfortunately, we cannot easily estimate $q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t)$ because it needs to use the entire dataset and therefore we need to learn a model $p_\\theta$ to approximate these conditional probabilities in order to run the\nreverse diffusion process\n.\n$$\np_\\theta(\\mathbf{x}_{0:T}) = p(\\mathbf{x}_T) \\prod^T_{t=1} p_\\theta(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t) \\quad\np_\\theta(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t) = \\mathcal{N}(\\mathbf{x}_{t-1}; \\boldsymbol{\\mu}_\\theta(\\mathbf{x}_t, t), \\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t))\n$$\nAn example of training a diffusion model for modeling a 2D swiss roll data. (Image source:\nSohl-Dickstein et al., 2015\n)\nIt is noteworthy that the reverse conditional probability is tractable when conditioned on $\\mathbf{x}_0$:\n$$\nq(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0) = \\mathcal{N}(\\mathbf{x}_{t-1}; \\color{blue}{\\tilde{\\boldsymbol{\\mu}}}(\\mathbf{x}_t, \\mathbf{x}_0), \\color{red}{\\tilde{\\beta}_t} \\mathbf{I})\n$$\nUsing Bayes’ rule, we have:\n$$\n\\begin{aligned}\nq(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0) \n&= q(\\mathbf{x}_t \\vert \\mathbf{x}_{t-1}, \\mathbf{x}_0) \\frac{ q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_0) }{ q(\\mathbf{x}_t \\vert \\mathbf{x}_0) } \\\\\n&\\propto \\exp \\Big(-\\frac{1}{2} \\big(\\frac{(\\mathbf{x}_t - \\sqrt{\\alpha_t} \\mathbf{x}_{t-1})^2}{\\beta_t} + \\frac{(\\mathbf{x}_{t-1} - \\sqrt{\\bar{\\alpha}_{t-1}} \\mathbf{x}_0)^2}{1-\\bar{\\alpha}_{t-1}} - \\frac{(\\mathbf{x}_t - \\sqrt{\\bar{\\alpha}_t} \\mathbf{x}_0)^2}{1-\\bar{\\alpha}_t} \\big) \\Big) \\\\\n&= \\exp \\Big(-\\frac{1}{2} \\big(\\frac{\\mathbf{x}_t^2 - 2\\sqrt{\\alpha_t} \\mathbf{x}_t \\color{blue}{\\mathbf{x}_{t-1}} \\color{black}{+ \\alpha_t} \\color{red}{\\mathbf{x}_{t-1}^2} }{\\beta_t} + \\frac{ \\color{red}{\\mathbf{x}_{t-1}^2} \\color{black}{- 2 \\sqrt{\\bar{\\alpha}_{t-1}} \\mathbf{x}_0} \\color{blue}{\\mathbf{x}_{t-1}} \\color{black}{+ \\bar{\\alpha}_{t-1} \\mathbf{x}_0^2}  }{1-\\bar{\\alpha}_{t-1}} - \\frac{(\\mathbf{x}_t - \\sqrt{\\bar{\\alpha}_t} \\mathbf{x}_0)^2}{1-\\bar{\\alpha}_t} \\big) \\Big) \\\\\n&= \\exp\\Big( -\\frac{1}{2} \\big( \\color{red}{(\\frac{\\alpha_t}{\\beta_t} + \\frac{1}{1 - \\bar{\\alpha}_{t-1}})} \\mathbf{x}_{t-1}^2 - \\color{blue}{(\\frac{2\\sqrt{\\alpha_t}}{\\beta_t} \\mathbf{x}_t + \\frac{2\\sqrt{\\bar{\\alpha}_{t-1}}}{1 - \\bar{\\alpha}_{t-1}} \\mathbf{x}_0)} \\mathbf{x}_{t-1} \\color{black}{ + C(\\mathbf{x}_t, \\mathbf{x}_0) \\big) \\Big)}\n\\end{aligned}\n$$\nwhere $C(\\mathbf{x}_t, \\mathbf{x}_0)$ is some function not involving $\\mathbf{x}_{t-1}$ and details are omitted. Following the standard Gaussian density function, the mean and variance can be parameterized as follows (recall that $\\alpha_t = 1 - \\beta_t$ and $\\bar{\\alpha}_t = \\prod_{i=1}^t \\alpha_i$):\n$$\n\\begin{aligned}\n\\tilde{\\beta}_t \n&= 1/(\\frac{\\alpha_t}{\\beta_t} + \\frac{1}{1 - \\bar{\\alpha}_{t-1}}) \n= 1/(\\frac{\\alpha_t - \\bar{\\alpha}_t + \\beta_t}{\\beta_t(1 - \\bar{\\alpha}_{t-1})})\n= \\color{green}{\\frac{1 - \\bar{\\alpha}_{t-1}}{1 - \\bar{\\alpha}_t} \\cdot \\beta_t} \\\\\n\\tilde{\\boldsymbol{\\mu}}_t (\\mathbf{x}_t, \\mathbf{x}_0)\n&= (\\frac{\\sqrt{\\alpha_t}}{\\beta_t} \\mathbf{x}_t + \\frac{\\sqrt{\\bar{\\alpha}_{t-1} }}{1 - \\bar{\\alpha}_{t-1}} \\mathbf{x}_0)/(\\frac{\\alpha_t}{\\beta_t} + \\frac{1}{1 - \\bar{\\alpha}_{t-1}}) \\\\\n&= (\\frac{\\sqrt{\\alpha_t}}{\\beta_t} \\mathbf{x}_t + \\frac{\\sqrt{\\bar{\\alpha}_{t-1} }}{1 - \\bar{\\alpha}_{t-1}} \\mathbf{x}_0) \\color{green}{\\frac{1 - \\bar{\\alpha}_{t-1}}{1 - \\bar{\\alpha}_t} \\cdot \\beta_t} \\\\\n&= \\frac{\\sqrt{\\alpha_t}(1 - \\bar{\\alpha}_{t-1})}{1 - \\bar{\\alpha}_t} \\mathbf{x}_t + \\frac{\\sqrt{\\bar{\\alpha}_{t-1}}\\beta_t}{1 - \\bar{\\alpha}_t} \\mathbf{x}_0\\\\\n\\end{aligned}\n$$\nThanks to the\nnice property\n, we can represent $\\mathbf{x}_0 = \\frac{1}{\\sqrt{\\bar{\\alpha}_t}}(\\mathbf{x}_t - \\sqrt{1 - \\bar{\\alpha}_t}\\boldsymbol{\\epsilon}_t)$ and plug it into the above equation and obtain:\n$$\n\\begin{aligned}\n\\tilde{\\boldsymbol{\\mu}}_t\n&= \\frac{\\sqrt{\\alpha_t}(1 - \\bar{\\alpha}_{t-1})}{1 - \\bar{\\alpha}_t} \\mathbf{x}_t + \\frac{\\sqrt{\\bar{\\alpha}_{t-1}}\\beta_t}{1 - \\bar{\\alpha}_t} \\frac{1}{\\sqrt{\\bar{\\alpha}_t}}(\\mathbf{x}_t - \\sqrt{1 - \\bar{\\alpha}_t}\\boldsymbol{\\epsilon}_t) \\\\\n&= \\color{cyan}{\\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_t \\Big)}\n\\end{aligned}\n$$\nAs demonstrated in Fig. 2., such a setup is very similar to\nVAE\nand thus we can use the variational lower bound to optimize the negative log-likelihood.\n$$\n\\begin{aligned}\n- \\log p_\\theta(\\mathbf{x}_0) \n&\\leq - \\log p_\\theta(\\mathbf{x}_0) + D_\\text{KL}(q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0) \\| p_\\theta(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0) ) & \\small{\\text{; KL is non-negative}}\\\\\n&= - \\log p_\\theta(\\mathbf{x}_0) + \\mathbb{E}_{\\mathbf{x}_{1:T}\\sim q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_0)} \\Big[ \\log\\frac{q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{0:T}) / p_\\theta(\\mathbf{x}_0)} \\Big] \\\\\n&= - \\log p_\\theta(\\mathbf{x}_0) + \\mathbb{E}_q \\Big[ \\log\\frac{q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{0:T})} + \\log p_\\theta(\\mathbf{x}_0) \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ \\log \\frac{q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{0:T})} \\Big] \\\\\n\\text{Let }L_\\text{VLB} \n&= \\mathbb{E}_{q(\\mathbf{x}_{0:T})} \\Big[ \\log \\frac{q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{0:T})} \\Big] \\geq - \\mathbb{E}_{q(\\mathbf{x}_0)} \\log p_\\theta(\\mathbf{x}_0)\n\\end{aligned}\n$$\nIt is also straightforward to get the same result using Jensen’s inequality. Say we want to minimize the cross entropy as the learning objective,\n$$\n\\begin{aligned}\nL_\\text{CE}\n&= - \\mathbb{E}_{q(\\mathbf{x}_0)} \\log p_\\theta(\\mathbf{x}_0) \\\\\n&= - \\mathbb{E}_{q(\\mathbf{x}_0)} \\log \\Big( \\int p_\\theta(\\mathbf{x}_{0:T}) d\\mathbf{x}_{1:T} \\Big) \\\\\n&= - \\mathbb{E}_{q(\\mathbf{x}_0)} \\log \\Big( \\int q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_0) \\frac{p_\\theta(\\mathbf{x}_{0:T})}{q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_{0})} d\\mathbf{x}_{1:T} \\Big) \\\\\n&= - \\mathbb{E}_{q(\\mathbf{x}_0)} \\log \\Big( \\mathbb{E}_{q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_0)} \\frac{p_\\theta(\\mathbf{x}_{0:T})}{q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_{0})} \\Big) \\\\\n&\\leq - \\mathbb{E}_{q(\\mathbf{x}_{0:T})} \\log \\frac{p_\\theta(\\mathbf{x}_{0:T})}{q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_{0})} \\\\\n&= \\mathbb{E}_{q(\\mathbf{x}_{0:T})}\\Big[\\log \\frac{q(\\mathbf{x}_{1:T} \\vert \\mathbf{x}_{0})}{p_\\theta(\\mathbf{x}_{0:T})} \\Big] = L_\\text{VLB}\n\\end{aligned}\n$$\nTo convert each term in the equation to be analytically computable, the objective can be further rewritten to be a combination of several KL-divergence and entropy terms (See the detailed step-by-step process in Appendix B in\nSohl-Dickstein et al., 2015\n):\n$$\n\\begin{aligned}\nL_\\text{VLB} \n&= \\mathbb{E}_{q(\\mathbf{x}_{0:T})} \\Big[ \\log\\frac{q(\\mathbf{x}_{1:T}\\vert\\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{0:T})} \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ \\log\\frac{\\prod_{t=1}^T q(\\mathbf{x}_t\\vert\\mathbf{x}_{t-1})}{ p_\\theta(\\mathbf{x}_T) \\prod_{t=1}^T p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t) } \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ -\\log p_\\theta(\\mathbf{x}_T) + \\sum_{t=1}^T \\log \\frac{q(\\mathbf{x}_t\\vert\\mathbf{x}_{t-1})}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)} \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ -\\log p_\\theta(\\mathbf{x}_T) + \\sum_{t=2}^T \\log \\frac{q(\\mathbf{x}_t\\vert\\mathbf{x}_{t-1})}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)} + \\log\\frac{q(\\mathbf{x}_1 \\vert \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)} \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ -\\log p_\\theta(\\mathbf{x}_T) + \\sum_{t=2}^T \\log \\Big( \\frac{q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)}\\cdot \\frac{q(\\mathbf{x}_t \\vert \\mathbf{x}_0)}{q(\\mathbf{x}_{t-1}\\vert\\mathbf{x}_0)} \\Big) + \\log \\frac{q(\\mathbf{x}_1 \\vert \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)} \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ -\\log p_\\theta(\\mathbf{x}_T) + \\sum_{t=2}^T \\log \\frac{q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)} + \\sum_{t=2}^T \\log \\frac{q(\\mathbf{x}_t \\vert \\mathbf{x}_0)}{q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_0)} + \\log\\frac{q(\\mathbf{x}_1 \\vert \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)} \\Big] \\\\\n&= \\mathbb{E}_q \\Big[ -\\log p_\\theta(\\mathbf{x}_T) + \\sum_{t=2}^T \\log \\frac{q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)} + \\log\\frac{q(\\mathbf{x}_T \\vert \\mathbf{x}_0)}{q(\\mathbf{x}_1 \\vert \\mathbf{x}_0)} + \\log \\frac{q(\\mathbf{x}_1 \\vert \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)} \\Big]\\\\\n&= \\mathbb{E}_q \\Big[ \\log\\frac{q(\\mathbf{x}_T \\vert \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_T)} + \\sum_{t=2}^T \\log \\frac{q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)}{p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t)} - \\log p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1) \\Big] \\\\\n&= \\mathbb{E}_q [\\underbrace{D_\\text{KL}(q(\\mathbf{x}_T \\vert \\mathbf{x}_0) \\parallel p_\\theta(\\mathbf{x}_T))}_{L_T} + \\sum_{t=2}^T \\underbrace{D_\\text{KL}(q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0) \\parallel p_\\theta(\\mathbf{x}_{t-1} \\vert\\mathbf{x}_t))}_{L_{t-1}} \\underbrace{- \\log p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)}_{L_0} ]\n\\end{aligned}\n$$\nLet’s label each component in the variational lower bound loss separately:\n$$\n\\begin{aligned}\nL_\\text{VLB} &= L_T + L_{T-1} + \\dots + L_0 \\\\\n\\text{where } L_T &= D_\\text{KL}(q(\\mathbf{x}_T \\vert \\mathbf{x}_0) \\parallel p_\\theta(\\mathbf{x}_T)) \\\\\nL_t &= D_\\text{KL}(q(\\mathbf{x}_t \\vert \\mathbf{x}_{t+1}, \\mathbf{x}_0) \\parallel p_\\theta(\\mathbf{x}_t \\vert\\mathbf{x}_{t+1})) \\text{ for }1 \\leq t \\leq T-1 \\\\\nL_0 &= - \\log p_\\theta(\\mathbf{x}_0 \\vert \\mathbf{x}_1)\n\\end{aligned}\n$$\nEvery KL term in $L_\\text{VLB}$ (except for $L_0$) compares two Gaussian distributions and therefore they can be computed in\nclosed form\n. $L_T$ is constant and can be ignored during training because $q$ has no learnable parameters and $\\mathbf{x}_T$ is a Gaussian noise.\nHo et al. 2020\nmodels $L_0$ using a separate discrete decoder derived from $\\mathcal{N}(\\mathbf{x}_0; \\boldsymbol{\\mu}_\\theta(\\mathbf{x}_1, 1), \\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_1, 1))$.\nParameterization of $L_t$ for Training Loss\n#\nRecall that we need to learn a neural network to approximate the conditioned probability distributions in the reverse diffusion process, $p_\\theta(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t) = \\mathcal{N}(\\mathbf{x}_{t-1}; \\boldsymbol{\\mu}_\\theta(\\mathbf{x}_t, t), \\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t))$. We would like to train $\\boldsymbol{\\mu}_\\theta$ to predict $\\tilde{\\boldsymbol{\\mu}}_t = \\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_t \\Big)$. Because $\\mathbf{x}_t$ is available as input at training time, we can reparameterize the Gaussian noise term instead to make it predict $\\boldsymbol{\\epsilon}_t$ from the input $\\mathbf{x}_t$ at time step $t$:\n$$\n\\begin{aligned}\n\\boldsymbol{\\mu}_\\theta(\\mathbf{x}_t, t) &= \\color{cyan}{\\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) \\Big)} \\\\\n\\text{Thus }\\mathbf{x}_{t-1} &= \\mathcal{N}(\\mathbf{x}_{t-1}; \\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) \\Big), \\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t))\n\\end{aligned}\n$$\nThe loss term $L_t$ is parameterized to minimize the difference from $\\tilde{\\boldsymbol{\\mu}}$ :\n$$\n\\begin{aligned}\nL_t \n&= \\mathbb{E}_{\\mathbf{x}_0, \\boldsymbol{\\epsilon}} \\Big[\\frac{1}{2 \\| \\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t) \\|^2_2} \\| \\color{blue}{\\tilde{\\boldsymbol{\\mu}}_t(\\mathbf{x}_t, \\mathbf{x}_0)} - \\color{green}{\\boldsymbol{\\mu}_\\theta(\\mathbf{x}_t, t)} \\|^2 \\Big] \\\\\n&= \\mathbb{E}_{\\mathbf{x}_0, \\boldsymbol{\\epsilon}} \\Big[\\frac{1}{2  \\|\\boldsymbol{\\Sigma}_\\theta \\|^2_2} \\| \\color{blue}{\\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_t \\Big)} - \\color{green}{\\frac{1}{\\sqrt{\\alpha_t}} \\Big( \\mathbf{x}_t - \\frac{1 - \\alpha_t}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\boldsymbol{\\epsilon}}_\\theta(\\mathbf{x}_t, t) \\Big)} \\|^2 \\Big] \\\\\n&= \\mathbb{E}_{\\mathbf{x}_0, \\boldsymbol{\\epsilon}} \\Big[\\frac{ (1 - \\alpha_t)^2 }{2 \\alpha_t (1 - \\bar{\\alpha}_t) \\| \\boldsymbol{\\Sigma}_\\theta \\|^2_2} \\|\\boldsymbol{\\epsilon}_t - \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)\\|^2 \\Big] \\\\\n&= \\mathbb{E}_{\\mathbf{x}_0, \\boldsymbol{\\epsilon}} \\Big[\\frac{ (1 - \\alpha_t)^2 }{2 \\alpha_t (1 - \\bar{\\alpha}_t) \\| \\boldsymbol{\\Sigma}_\\theta \\|^2_2} \\|\\boldsymbol{\\epsilon}_t - \\boldsymbol{\\epsilon}_\\theta(\\sqrt{\\bar{\\alpha}_t}\\mathbf{x}_0 + \\sqrt{1 - \\bar{\\alpha}_t}\\boldsymbol{\\epsilon}_t, t)\\|^2 \\Big] \n\\end{aligned}\n$$\nSimplification\n#\nEmpirically,\nHo et al. (2020)\nfound that training the diffusion model works better with a simplified objective that ignores the weighting term:\n$$\n\\begin{aligned}\nL_t^\\text{simple}\n&= \\mathbb{E}_{t \\sim [1, T], \\mathbf{x}_0, \\boldsymbol{\\epsilon}_t} \\Big[\\|\\boldsymbol{\\epsilon}_t - \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)\\|^2 \\Big] \\\\\n&= \\mathbb{E}_{t \\sim [1, T], \\mathbf{x}_0, \\boldsymbol{\\epsilon}_t} \\Big[\\|\\boldsymbol{\\epsilon}_t - \\boldsymbol{\\epsilon}_\\theta(\\sqrt{\\bar{\\alpha}_t}\\mathbf{x}_0 + \\sqrt{1 - \\bar{\\alpha}_t}\\boldsymbol{\\epsilon}_t, t)\\|^2 \\Big]\n\\end{aligned}\n$$\nThe final simple objective is:\n$$\nL_\\text{simple} = L_t^\\text{simple} + C\n$$\nwhere $C$ is a constant not depending on $\\theta$.\nThe training and sampling algorithms in DDPM (Image source:\nHo et al. 2020\n)\nConnection with noise-conditioned score networks (NCSN)\n#\nSong & Ermon (2019)\nproposed a score-based generative modeling method where samples are produced via\nLangevin dynamics\nusing gradients of the data distribution estimated with score matching. The score of each sample $\\mathbf{x}$’s density probability is defined as its gradient $\\nabla_{\\mathbf{x}} \\log q(\\mathbf{x})$. A score network $\\mathbf{s}_\\theta: \\mathbb{R}^D \\to \\mathbb{R}^D$ is trained to estimate it, $\\mathbf{s}_\\theta(\\mathbf{x}) \\approx \\nabla_{\\mathbf{x}} \\log q(\\mathbf{x})$.\nTo make it scalable with high-dimensional data in the deep learning setting, they proposed to use either\ndenoising score matching\n(\nVincent, 2011\n) or\nsliced score matching\n(use random projections;\nSong et al., 2019\n). Denosing score matching adds a pre-specified small noise to the data $q(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$ and estimates $q(\\tilde{\\mathbf{x}})$ with score matching.\nRecall that Langevin dynamics can sample data points from a probability density distribution using only the score $\\nabla_{\\mathbf{x}} \\log q(\\mathbf{x})$ in an iterative process.\nHowever, according to the manifold hypothesis, most of the data is expected to concentrate in a low dimensional manifold, even though the observed data might look only arbitrarily high-dimensional. It brings a negative effect on score estimation since the data points cannot cover the whole space. In regions where data density is low, the score estimation is less reliable. After adding a small Gaussian noise to make the perturbed data distribution cover the full space $\\mathbb{R}^D$, the training of the score estimator network becomes more stable.\nSong & Ermon (2019)\nimproved it by perturbing the data with the noise of\ndifferent levels\nand train a noise-conditioned score network to\njointly\nestimate the scores of all the perturbed data at different noise levels.\nThe schedule of increasing noise levels resembles the forward diffusion process. If we use the diffusion process annotation, the score approximates $\\mathbf{s}_\\theta(\\mathbf{x}_t, t) \\approx \\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t)$. Given a Gaussian distribution $\\mathbf{x} \\sim \\mathcal{N}(\\mathbf{\\mu}, \\sigma^2 \\mathbf{I})$, we can write the derivative of the logarithm of its density function as $\\nabla_{\\mathbf{x}}\\log p(\\mathbf{x}) = \\nabla_{\\mathbf{x}} \\Big(-\\frac{1}{2\\sigma^2}(\\mathbf{x} - \\boldsymbol{\\mu})^2 \\Big) = - \\frac{\\mathbf{x} - \\boldsymbol{\\mu}}{\\sigma^2} = - \\frac{\\boldsymbol{\\epsilon}}{\\sigma}$ where $\\boldsymbol{\\epsilon} \\sim \\mathcal{N}(\\boldsymbol{0}, \\mathbf{I})$.\nRecall\nthat $q(\\mathbf{x}_t \\vert \\mathbf{x}_0) \\sim \\mathcal{N}(\\sqrt{\\bar{\\alpha}_t} \\mathbf{x}_0, (1 - \\bar{\\alpha}_t)\\mathbf{I})$ and therefore,\n$$\n\\mathbf{s}_\\theta(\\mathbf{x}_t, t) \n\\approx \\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t)\n= \\mathbb{E}_{q(\\mathbf{x}_0)} [\\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t \\vert \\mathbf{x}_0)]\n= \\mathbb{E}_{q(\\mathbf{x}_0)} \\Big[ - \\frac{\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)}{\\sqrt{1 - \\bar{\\alpha}_t}} \\Big]\n= - \\frac{\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)}{\\sqrt{1 - \\bar{\\alpha}_t}}\n$$\nParameterization of $\\beta_t$\n#\nThe forward variances are set to be a sequence of linearly increasing constants in\nHo et al. (2020)\n, from $\\beta_1=10^{-4}$ to $\\beta_T=0.02$. They are relatively small compared to the normalized image pixel values between $[-1, 1]$. Diffusion models in their experiments showed high-quality samples but still could not achieve competitive model log-likelihood as other generative models.\nNichol & Dhariwal (2021)\nproposed several improvement techniques to help diffusion models to obtain lower NLL. One of the improvements is to use a cosine-based variance schedule. The choice of the scheduling function can be arbitrary, as long as it provides a near-linear drop in the middle of the training process and subtle changes around $t=0$ and $t=T$.\n$$\n\\beta_t = \\text{clip}(1-\\frac{\\bar{\\alpha}_t}{\\bar{\\alpha}_{t-1}}, 0.999) \\quad\\bar{\\alpha}_t = \\frac{f(t)}{f(0)}\\quad\\text{where }f(t)=\\cos\\Big(\\frac{t/T+s}{1+s}\\cdot\\frac{\\pi}{2}\\Big)^2\n$$\nwhere the small offset $s$ is to prevent $\\beta_t$ from being too small when close to $t=0$.\nComparison of linear and cosine-based scheduling of $\\beta\\_t$ during training. (Image source:\nNichol & Dhariwal, 2021\n)\nParameterization of reverse process variance $\\boldsymbol{\\Sigma}_\\theta$\n#\nHo et al. (2020)\nchose to fix $\\beta_t$ as constants instead of making them learnable and set $\\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t) = \\sigma^2_t \\mathbf{I}$ , where $\\sigma_t$ is not learned but set to $\\beta_t$ or $\\tilde{\\beta}_t = \\frac{1 - \\bar{\\alpha}_{t-1}}{1 - \\bar{\\alpha}_t} \\cdot \\beta_t$. Because they found that learning a diagonal variance $\\boldsymbol{\\Sigma}_\\theta$ leads to unstable training and poorer sample quality.\nNichol & Dhariwal (2021)\nproposed to learn $\\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t)$ as an interpolation between $\\beta_t$ and $\\tilde{\\beta}_t$ by model predicting a mixing vector $\\mathbf{v}$ :\n$$\n\\boldsymbol{\\Sigma}_\\theta(\\mathbf{x}_t, t) = \\exp(\\mathbf{v} \\log \\beta_t + (1-\\mathbf{v}) \\log \\tilde{\\beta}_t)\n$$\nHowever, the simple objective $L_\\text{simple}$ does not depend on $\\boldsymbol{\\Sigma}_\\theta$ . To add the dependency, they constructed a hybrid objective $L_\\text{hybrid} = L_\\text{simple} + \\lambda L_\\text{VLB}$ where $\\lambda=0.001$ is small and stop gradient on $\\boldsymbol{\\mu}_\\theta$ in the $L_\\text{VLB}$ term such that $L_\\text{VLB}$ only guides the learning of $\\boldsymbol{\\Sigma}_\\theta$. Empirically they observed that $L_\\text{VLB}$ is pretty challenging to optimize likely due to noisy gradients, so they proposed to use a time-averaging smoothed version of $L_\\text{VLB}$ with importance sampling.\nComparison of negative log-likelihood of improved DDPM with other likelihood-based generative models. NLL is reported in the unit of bits/dim. (Image source:\nNichol & Dhariwal, 2021\n)\nConditioned Generation\n#\nWhile training generative models on images with conditioning information such as ImageNet dataset, it is common to generate samples conditioned on class labels or a piece of descriptive text.\nClassifier Guided Diffusion\n#\nTo explicit incorporate class information into the diffusion process,\nDhariwal & Nichol (2021)\ntrained a classifier $f_\\phi(y \\vert \\mathbf{x}_t, t)$ on noisy image $\\mathbf{x}_t$ and use gradients $\\nabla_\\mathbf{x} \\log f_\\phi(y \\vert \\mathbf{x}_t)$ to guide the diffusion sampling process toward the conditioning information $y$ (e.g. a target class label) by altering the noise prediction.\nRecall\nthat $\\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t) = - \\frac{1}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)$ and we can write the score function for the joint distribution $q(\\mathbf{x}_t, y)$ as following,\n$$\n\\begin{aligned}\n\\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t, y)\n&= \\nabla_{\\mathbf{x}_t} \\log q(\\mathbf{x}_t) + \\nabla_{\\mathbf{x}_t} \\log q(y \\vert \\mathbf{x}_t) \\\\\n&\\approx - \\frac{1}{\\sqrt{1 - \\bar{\\alpha}_t}} \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) + \\nabla_{\\mathbf{x}_t} \\log f_\\phi(y \\vert \\mathbf{x}_t) \\\\\n&= - \\frac{1}{\\sqrt{1 - \\bar{\\alpha}_t}} (\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) - \\sqrt{1 - \\bar{\\alpha}_t} \\nabla_{\\mathbf{x}_t} \\log f_\\phi(y \\vert \\mathbf{x}_t))\n\\end{aligned}\n$$\nThus, a new classifier-guided predictor $\\bar{\\boldsymbol{\\epsilon}}_\\theta$ would take the form as following,\n$$\n\\bar{\\boldsymbol{\\epsilon}}_\\theta(\\mathbf{x}_t, t) = \\boldsymbol{\\epsilon}_\\theta(x_t, t) - \\sqrt{1 - \\bar{\\alpha}_t} \\nabla_{\\mathbf{x}_t} \\log f_\\phi(y \\vert \\mathbf{x}_t)\n$$\nTo control the strength of the classifier guidance, we can add a weight $w$ to the delta part,\n$$\n\\bar{\\boldsymbol{\\epsilon}}_\\theta(\\mathbf{x}_t, t) = \\boldsymbol{\\epsilon}_\\theta(x_t, t) - \\sqrt{1 - \\bar{\\alpha}_t} \\; w \\nabla_{\\mathbf{x}_t} \\log f_\\phi(y \\vert \\mathbf{x}_t)\n$$\nThe resulting\nablated diffusion model\n(\nADM\n) and the one with additional classifier guidance (\nADM-G\n) are able to achieve better results than SOTA generative models (e.g. BigGAN).\nThe algorithms use guidance from a classifier to run conditioned generation with DDPM and DDIM. (Image source:\nDhariwal & Nichol, 2021\n])\nAdditionally with some modifications on the U-Net architecture,\nDhariwal & Nichol (2021)\nshowed performance better than GAN with diffusion models. The architecture modifications include larger model depth/width, more attention heads, multi-resolution attention, BigGAN residual blocks for up/downsampling, residual connection rescale by $1/\\sqrt{2}$ and adaptive group normalization (AdaGN).\nClassifier-Free Guidance\n#\nWithout an independent classifier $f_\\phi$, it is still possible to run conditional diffusion steps by incorporating the scores from a conditional and an unconditional diffusion model (\nHo & Salimans, 2021\n). Let unconditional denoising diffusion model $p_\\theta(\\mathbf{x})$ parameterized through a score estimator $\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)$ and the conditional model $p_\\theta(\\mathbf{x} \\vert y)$ parameterized through $\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y)$. These two models can be learned via a single neural network. Precisely, a conditional diffusion model $p_\\theta(\\mathbf{x} \\vert y)$ is trained on paired data $(\\mathbf{x}, y)$, where the conditioning information $y$ gets discarded periodically at random such that the model knows how to generate images unconditionally as well, i.e. $\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) = \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y=\\varnothing)$.\nThe gradient of an implicit classifier can be represented with conditional and unconditional score estimators. Once plugged into the classifier-guided modified score, the score contains no dependency on a separate classifier.\n$$\n\\begin{aligned}\n\\nabla_{\\mathbf{x}_t} \\log p(y \\vert \\mathbf{x}_t)\n&= \\nabla_{\\mathbf{x}_t} \\log p(\\mathbf{x}_t \\vert y) - \\nabla_{\\mathbf{x}_t} \\log p(\\mathbf{x}_t) \\\\\n&= - \\frac{1}{\\sqrt{1 - \\bar{\\alpha}_t}}\\Big( \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y) - \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) \\Big) \\\\\n\\bar{\\boldsymbol{\\epsilon}}_\\theta(\\mathbf{x}_t, t, y)\n&= \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y) - \\sqrt{1 - \\bar{\\alpha}_t} \\; w \\nabla_{\\mathbf{x}_t} \\log p(y \\vert \\mathbf{x}_t) \\\\\n&= \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y) + w \\big(\\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y) - \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t) \\big) \\\\\n&= (w+1) \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t, y) - w \\boldsymbol{\\epsilon}_\\theta(\\mathbf{x}_t, t)\n\\end{aligned}\n$$\nTheir experiments showed that classifier-free guidance can achieve a good balance between FID (distinguish between synthetic and generated images) and IS (quality and diversity).\nThe guided diffusion model, GLIDE (\nNichol, Dhariwal & Ramesh, et al. 2022\n), explored both guiding strategies, CLIP guidance and classifier-free guidance, and found that the latter is more preferred. They hypothesized that it is because CLIP guidance exploits the model with adversarial examples towards the CLIP model, rather than optimize the better matched images generation.\nSpeed up Diffusion Models\n#\nIt is very slow to generate a sample from DDPM by following the Markov chain of the reverse diffusion process, as $T$ can be up to one or a few thousand steps. One data point from\nSong et al. (2020)\n: “For example, it takes around 20 hours to sample 50k images of size 32 × 32 from a DDPM, but less than a minute to do so from a GAN on an Nvidia 2080 Ti GPU.”\nFewer Sampling Steps & Distillation\n#\nOne simple way is to run a strided sampling schedule (\nNichol & Dhariwal, 2021\n) by taking the sampling update every $\\lceil T/S \\rceil$ steps to reduce the process from $T$ to $S$ steps. The new sampling schedule for generation is $\\{\\tau_1, \\dots, \\tau_S\\}$  where $\\tau_1 < \\tau_2 < \\dots <\\tau_S \\in [1, T]$ and $S < T$.\nFor another approach, let’s rewrite $q_\\sigma(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)$ to be parameterized by a desired standard deviation $\\sigma_t$ according to the\nnice property\n:\n$$\n\\begin{aligned}\n\\mathbf{x}_{t-1} \n&= \\sqrt{\\bar{\\alpha}_{t-1}}\\mathbf{x}_0 +  \\sqrt{1 - \\bar{\\alpha}_{t-1}}\\boldsymbol{\\epsilon}_{t-1} & \\\\\n&= \\sqrt{\\bar{\\alpha}_{t-1}}\\mathbf{x}_0 + \\sqrt{1 - \\bar{\\alpha}_{t-1} - \\sigma_t^2} \\boldsymbol{\\epsilon}_t + \\sigma_t\\boldsymbol{\\epsilon} & \\\\\n&= \\sqrt{\\bar{\\alpha}_{t-1}} \\Big( \\frac{\\mathbf{x}_t - \\sqrt{1 - \\bar{\\alpha}_t} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t)}{\\sqrt{\\bar{\\alpha}_t}} \\Big) + \\sqrt{1 - \\bar{\\alpha}_{t-1} - \\sigma_t^2} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t) + \\sigma_t\\boldsymbol{\\epsilon} \\\\\nq_\\sigma(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0)\n&= \\mathcal{N}(\\mathbf{x}_{t-1}; \\sqrt{\\bar{\\alpha}_{t-1}} \\Big( \\frac{\\mathbf{x}_t - \\sqrt{1 - \\bar{\\alpha}_t} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t)}{\\sqrt{\\bar{\\alpha}_t}} \\Big) + \\sqrt{1 - \\bar{\\alpha}_{t-1} - \\sigma_t^2} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t), \\sigma_t^2 \\mathbf{I})\n\\end{aligned}\n$$\nwhere the model $\\epsilon^{(t)}_\\theta(.)$ predicts the $\\epsilon_t$ from $\\mathbf{x}_t$.\nRecall that in $q(\\mathbf{x}_{t-1} \\vert \\mathbf{x}_t, \\mathbf{x}_0) = \\mathcal{N}(\\mathbf{x}_{t-1}; \\tilde{\\boldsymbol{\\mu}}(\\mathbf{x}_t, \\mathbf{x}_0), \\tilde{\\beta}_t \\mathbf{I})$, therefore we have:\n$$\n\\tilde{\\beta}_t = \\sigma_t^2 = \\frac{1 - \\bar{\\alpha}_{t-1}}{1 - \\bar{\\alpha}_t} \\cdot \\beta_t\n$$\nLet $\\sigma_t^2 = \\eta \\cdot \\tilde{\\beta}_t$ such that we can adjust $\\eta \\in \\mathbb{R}^+$ as a hyperparameter to control the sampling stochasticity. The special case of $\\eta = 0$ makes the sampling process\ndeterministic\n. Such a model is named the\ndenoising diffusion implicit model\n(\nDDIM\n;\nSong et al., 2020\n). DDIM has the same marginal noise distribution but deterministically maps noise back to the original data samples.\nDuring generation, we don’t have to follow the whole chain $t=1,\\dots,T$, but rather a subset of steps. Let’s denote $s < t$ as two steps in this accelerated trajectory. The DDIM update step is:\n$$\nq_{\\sigma, s < t}(\\mathbf{x}_s \\vert \\mathbf{x}_t, \\mathbf{x}_0)\n= \\mathcal{N}(\\mathbf{x}_s; \\sqrt{\\bar{\\alpha}_s} \\Big( \\frac{\\mathbf{x}_t - \\sqrt{1 - \\bar{\\alpha}_t} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t)}{\\sqrt{\\bar{\\alpha}_t}} \\Big) + \\sqrt{1 - \\bar{\\alpha}_s - \\sigma_t^2} \\epsilon^{(t)}_\\theta(\\mathbf{x}_t), \\sigma_t^2 \\mathbf{I})\n$$\nWhile all the models are trained with $T=1000$ diffusion steps in the experiments, they observed that DDIM ($\\eta=0$) can produce the best quality samples when $S$ is small, while DDPM ($\\eta=1$) performs much worse on small $S$. DDPM does perform better when we can afford to run the full reverse Markov diffusion steps ($S=T=1000$). With DDIM, it is possible to train the diffusion model up to any arbitrary number of forward steps but only sample from a subset of steps in the generative process.\nFID scores on CIFAR10 and CelebA datasets by diffusion models of different settings, including $\\color{cyan}{\\text{DDIM}}$ ($\\eta=0$) and $\\color{orange}{\\text{DDPM}}$ ($\\hat{\\sigma}$). (Image source:\nSong et al., 2020\n)\nCompared to DDPM, DDIM is able to:\nGenerate higher-quality samples using a much fewer number of steps.\nHave “consistency” property since the generative process is deterministic, meaning that multiple samples conditioned on the same latent variable should have similar high-level features.\nBecause of the consistency, DDIM can do semantically meaningful interpolation in the latent variable.\nProgressive distillation can reduce the diffusion sampling steps by half in each iteration. (Image source:\nSalimans & Ho, 2022\n)\nProgressive Distillation\n(\nSalimans & Ho, 2022\n) is a method for distilling trained deterministic samplers into new models of halved sampling steps. The student model is initialized from the teacher model and denoises towards a target where one student DDIM step matches 2 teacher steps, instead of using the original sample $\\mathbf{x}_0$ as the denoise target. In every progressive distillation iteration, we can half the sampling steps.\nComparison of Algorithm 1 (diffusion model training) and Algorithm 2 (progressive distillation) side-by-side, where the relative changes in progressive distillation are highlighted in green.\n(Image source:\nSalimans & Ho, 2022\n)\nConsistency Models\n(\nSong et al. 2023\n) learns to map any intermediate noisy data points $\\mathbf{x}_t, t > 0$ on the diffusion sampling trajectory back to its origin $\\mathbf{x}_0$ directly. It is named as\nconsistency\nmodel because of its\nself-consistency\nproperty as any data points on the same trajectory is mapped to the same origin.\nConsistency models learn to map any data point on the trajectory back to its origin. (Image source:\nSong et al., 2023\n)\nGiven a trajectory $\\{\\mathbf{x}_t \\vert t \\in [\\epsilon, T]\\}$ , the\nconsistency function\n$f$ is defined as $f: (\\mathbf{x}_t, t) \\mapsto \\mathbf{x}_\\epsilon$ and the equation $f(\\mathbf{x}_t, t) = f(\\mathbf{x}_{t’}, t’) = \\mathbf{x}_\\epsilon$ holds true for all $t, t’ \\in [\\epsilon, T]$. When $t=\\epsilon$, $f$ is an identify function. The model can be parameterized as follows, where $c_\\text{skip}(t)$ and $c_\\text{out}(t)$ functions are designed in a way that $c_\\text{skip}(\\epsilon) = 1, c_\\text{out}(\\epsilon) = 0$:\n$$\nf_\\theta(\\mathbf{x}, t) = c_\\text{skip}(t)\\mathbf{x} + c_\\text{out}(t) F_\\theta(\\mathbf{x}, t)\n$$\nIt is possible for the consistency model to generate samples in a single step, while still maintaining the flexibility of trading computation for better quality following a multi-step sampling process.\nThe paper introduced two ways to train consistency models:\nConsistency Distillation (CD)\n: Distill a diffusion model into a consistency model by minimizing the difference between model outputs for pairs generated out of the same trajectory. This enables a much cheaper sampling evaluation. The consistency distillation loss is:\n$$\n \\begin{aligned}\n \\mathcal{L}^N_\\text{CD} (\\theta, \\theta^-; \\phi) &= \\mathbb{E}\n [\\lambda(t_n)d(f_\\theta(\\mathbf{x}_{t_{n+1}}, t_{n+1}), f_{\\theta^-}(\\hat{\\mathbf{x}}^\\phi_{t_n}, t_n)] \\\\\n \\hat{\\mathbf{x}}^\\phi_{t_n} &= \\mathbf{x}_{t_{n+1}} - (t_n - t_{n+1}) \\Phi(\\mathbf{x}_{t_{n+1}}, t_{n+1}; \\phi)\n \\end{aligned}\n $$\nwhere\n$\\Phi(.;\\phi)$ is the update function of a one-step\nODE\nsolver;\n$n \\sim \\mathcal{U}[1, N-1]$, has an uniform distribution over $1, \\dots, N-1$;\nThe network parameters $\\theta^-$ is EMA version of $\\theta$ which greatly stabilizes the training (just like in\nDQN\nor\nmomentum\ncontrastive learning);\n$d(.,.)$ is a positive distance metric function that satisfies $\\forall \\mathbf{x}, \\mathbf{y}: d(\\mathbf{x}, \\mathbf{y}) \\geq 0$ and $d(\\mathbf{x}, \\mathbf{y}) = 0$ if and only if $\\mathbf{x} = \\mathbf{y}$ such as $\\ell_2$, $\\ell_1$ or\nLPIPS\n(learned perceptual image patch similarity) distance;\n$\\lambda(.) \\in \\mathbb{R}^+$ is a positive weighting function and the paper sets $\\lambda(t_n)=1$.\nConsistency Training (CT)\n: The other option is to train a consistency model independently. Note that in CD, a pre-trained score model $s_\\phi(\\mathbf{x}, t)$ is used to approximate the ground truth score $\\nabla\\log p_t(\\mathbf{x})$ but in CT we need a way to estimate this score function and it turns out an unbiased estimator of $\\nabla\\log p_t(\\mathbf{x})$ exists as $-\\frac{\\mathbf{x}_t - \\mathbf{x}}{t^2}$. The CT loss is defined as follows:\n$$\n\\mathcal{L}^N_\\text{CT} (\\theta, \\theta^-; \\phi) = \\mathbb{E}\n[\\lambda(t_n)d(f_\\theta(\\mathbf{x} + t_{n+1} \\mathbf{z},\\;t_{n+1}), f_{\\theta^-}(\\mathbf{x} + t_n \\mathbf{z},\\;t_n)]\n\\text{ where }\\mathbf{z} \\in \\mathcal{N}(\\mathbf{0}, \\mathbf{I})\n$$\nAccording to the experiments in the paper, they found,\nHeun ODE solver works better than Euler’s first-order solver, since higher order ODE solvers have smaller estimation errors with the same $N$.\nAmong different options of the distance metric function $d(.)$, the LPIPS metric works better than $\\ell_1$ and $\\ell_2$ distance.\nSmaller $N$ leads to faster convergence but worse samples, whereas larger $N$ leads to slower convergence but better samples upon convergence.\nComparison of consistency models' performance under different configurations. The best configuration for CD is LPIPS distance metric, Heun ODE solver, and $N=18$.  (Image source:\nSong et al., 2023\n)\nLatent Variable Space\n#\nLatent diffusion model\n(\nLDM\n;\nRombach & Blattmann, et al. 2022\n) runs the diffusion process in the latent space instead of pixel space, making training cost lower and inference speed faster. It is motivated by the observation that most bits of an image contribute to perceptual details and the semantic and conceptual composition still remains after aggressive compression. LDM loosely decomposes the perceptual compression and semantic compression with generative modeling learning by first trimming off pixel-level redundancy with autoencoder and then manipulating / generating semantic concepts with diffusion process on learned latent.\nThe plot for tradeoff between compression rate and distortion, illustrating two-stage compressions - perceptual and semantic compression. (Image source:\nRombach & Blattmann, et al. 2022\n)\nThe perceptual compression process relies on an autoencoder model. An encoder $\\mathcal{E}$ is used to compress the input image $\\mathbf{x} \\in \\mathbb{R}^{H \\times W \\times 3}$ to a smaller 2D latent vector $\\mathbf{z} = \\mathcal{E}(\\mathbf{x}) \\in \\mathbb{R}^{h \\times w \\times c}$ , where the downsampling rate $f=H/h=W/w=2^m, m \\in \\mathbb{N}$. Then an decoder $\\mathcal{D}$ reconstructs the images from the latent vector, $\\tilde{\\mathbf{x}} = \\mathcal{D}(\\mathbf{z})$. The paper explored two types of regularization in autoencoder training to avoid arbitrarily high-variance in the latent spaces.\nKL-reg\n: A small KL penalty towards a standard normal distribution over the learned latent, similar to\nVAE\n.\nVQ-reg\n: Uses a vector quantization layer within the decoder, like\nVQVAE\nbut the quantization layer is absorbed by the decoder.\nThe diffusion and denoising processes happen on the latent vector $\\mathbf{z}$. The denoising model is a time-conditioned U-Net, augmented with the cross-attention mechanism to handle flexible conditioning information for image generation (e.g. class labels, semantic maps, blurred variants of an image). The design is equivalent to fuse representation of different modality into the model with a cross-attention mechanism. Each type of conditioning information is paired with a domain-specific encoder $\\tau_\\theta$ to project the conditioning input $y$ to an intermediate representation that can be mapped into cross-attention component, $\\tau_\\theta(y) \\in \\mathbb{R}^{M \\times d_\\tau}$:\n$$\n\\begin{aligned}\n&\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}\\Big(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{d}}\\Big) \\cdot \\mathbf{V} \\\\\n&\\text{where }\\mathbf{Q} = \\mathbf{W}^{(i)}_Q \\cdot \\varphi_i(\\mathbf{z}_i),\\;\n\\mathbf{K} = \\mathbf{W}^{(i)}_K \\cdot \\tau_\\theta(y),\\;\n\\mathbf{V} = \\mathbf{W}^{(i)}_V \\cdot \\tau_\\theta(y) \\\\\n&\\text{and }\n\\mathbf{W}^{(i)}_Q \\in \\mathbb{R}^{d \\times d^i_\\epsilon},\\;\n\\mathbf{W}^{(i)}_K, \\mathbf{W}^{(i)}_V \\in \\mathbb{R}^{d \\times d_\\tau},\\;\n\\varphi_i(\\mathbf{z}_i) \\in \\mathbb{R}^{N \\times d^i_\\epsilon},\\;\n\\tau_\\theta(y) \\in \\mathbb{R}^{M \\times d_\\tau}\n\\end{aligned}\n$$\nThe architecture of the latent diffusion model (LDM). (Image source:\nRombach & Blattmann, et al. 2022\n)\nScale up Generation Resolution and Quality\n#\nTo generate high-quality images at high resolution,\nHo et al. (2021)\nproposed to use a pipeline of multiple diffusion models at increasing resolutions.\nNoise conditioning augmentation\nbetween pipeline models is crucial to the final image quality, which is to apply strong data augmentation to the conditioning input $\\mathbf{z}$ of each super-resolution model $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$. The conditioning noise helps reduce compounding error in the pipeline setup.\nU-net\nis a common choice of model architecture in diffusion modeling for high-resolution image generation.\nA cascaded pipeline of multiple diffusion models at increasing resolutions. (Image source:\nHo et al. 2021\n])\nThey found the most effective noise is to apply Gaussian noise at low resolution and Gaussian blur at high resolution. In addition, they also explored two forms of conditioning augmentation that require small modification to the training process. Note that conditioning noise is only applied to training but not at inference.\nTruncated conditioning augmentation stops the diffusion process early at step $t > 0$ for low resolution.\nNon-truncated conditioning augmentation runs the full low resolution reverse process until step 0 but then corrupt it by $\\mathbf{z}_t \\sim q(\\mathbf{x}_t \\vert \\mathbf{x}_0)$ and then feeds the corrupted $\\mathbf{z}_t$ s into the super-resolution model.\nThe two-stage diffusion model\nunCLIP\n(\nRamesh et al. 2022\n) heavily utilizes the CLIP text encoder to produce text-guided images at high quality. Given a pretrained CLIP model $\\mathbf{c}$ and paired training data for the diffusion model, $(\\mathbf{x}, y)$, where $x$ is an image and $y$ is the corresponding caption, we can compute the CLIP text and image embedding, $\\mathbf{c}^t(y)$ and $\\mathbf{c}^i(\\mathbf{x})$, respectively. The unCLIP learns two models in parallel:\nA prior model $P(\\mathbf{c}^i \\vert y)$: outputs CLIP image embedding $\\mathbf{c}^i$ given the text $y$.\nA decoder $P(\\mathbf{x} \\vert \\mathbf{c}^i, [y])$: generates the image $\\mathbf{x}$ given CLIP image embedding $\\mathbf{c}^i$ and optionally the original text $y$.\nThese two models enable conditional generation, because\n$$\n\\underbrace{P(\\mathbf{x} \\vert y) = P(\\mathbf{x}, \\mathbf{c}^i \\vert y)}_{\\mathbf{c}^i\\text{ is deterministic given }\\mathbf{x}} = P(\\mathbf{x} \\vert \\mathbf{c}^i, y)P(\\mathbf{c}^i \\vert y)\n$$\nThe architecture of unCLIP. (Image source:\nRamesh et al. 2022\n])\nunCLIP follows a two-stage image generation process:\nGiven a text $y$, a CLIP model is first used to generate a text embedding $\\mathbf{c}^t(y)$. Using CLIP latent space enables zero-shot image manipulation via text.\nA diffusion or autoregressive prior $P(\\mathbf{c}^i \\vert y)$ processes this CLIP text embedding to construct an image prior and then a diffusion decoder $P(\\mathbf{x} \\vert \\mathbf{c}^i, [y])$ generates an image, conditioned on the prior. This decoder can also generate image variations conditioned on an image input, preserving its style and semantics.\nInstead of CLIP model,\nImagen\n(\nSaharia et al. 2022\n) uses a pre-trained large LM (i.e. a frozen T5-XXL text encoder) to encode text for image generation. There is a general trend that larger model size can lead to better image quality and text-image alignment. They found that T5-XXL and CLIP text encoder achieve similar performance on MS-COCO, but human evaluation prefers T5-XXL on DrawBench (a collection of prompts covering 11 categories).\nWhen applying classifier-free guidance, increasing $w$ may lead to better image-text alignment but worse image fidelity. They found that it is due to train-test mismatch, that is to say, because training data $\\mathbf{x}$ stays within the range $[-1, 1]$, the test data should be so too. Two thresholding strategies are introduced:\nStatic thresholding: clip $\\mathbf{x}$ prediction to $[-1, 1]$\nDynamic thresholding: at each sampling step, compute $s$ as a certain percentile absolute pixel value; if $s > 1$, clip the prediction to $[-s, s]$ and divide by $s$.\nImagen modifies several designs in U-net to make it\nefficient U-Net\n.\nShift model parameters from high resolution blocks to low resolution by adding more residual locks for the lower resolutions;\nScale the skip connections by $1/\\sqrt{2}$\nReverse the order of downsampling (move it before convolutions) and upsampling operations (move it after convolution) in order to improve the speed of forward pass.\nThey found that noise conditioning augmentation, dynamic thresholding and efficient U-Net are critical for image quality, but scaling text encoder size is more important than U-Net size.\nModel Architecture\n#\nThere are two common backbone architecture choices for diffusion models: U-Net and Transformer.\nU-Net\n(\nRonneberger, et al. 2015\n) consists of a downsampling stack and an upsampling stack.\nDownsampling\n: Each step consists of the repeated application of two 3x3 convolutions (unpadded convolutions), each followed by a ReLU and a 2x2 max pooling with stride 2. At each downsampling step, the number of feature channels is doubled.\nUpsampling\n: Each step consists of an upsampling of the feature map followed by a 2x2 convolution and each halves the number of feature channels.\nShortcuts\n: Shortcut connections result in a concatenation with the corresponding layers of the downsampling stack and provide the essential high-resolution features to the upsampling process.\nThe U-net architecture. Each blue square is a feature map with the number of channels labeled on top and the height x width dimension labeled on the left bottom side. The gray arrows mark the shortcut connections. (Image source:\nRonneberger, 2015\n)\nTo enable image generation conditioned on additional images for composition info like Canny edges, Hough lines, user scribbles, human post skeletons, segmentation maps, depths and normals,\nControlNet\n(\nZhang et al. 2023\nintroduces architectural changes via adding a “sandwiched” zero convolution layers of a trainable copy of the original model weights into each encoder layer of the U-Net. Precisely, given a neural network block $\\mathcal{F}_\\theta(.)$, ControlNet does the following:\nFirst, freeze the original parameters $\\theta$ of the original block\nClone it to be a copy with trainable parameters $\\theta_c$  and an additional conditioning vector $\\mathbf{c}$.\nUse two zero convolution layers, denoted as $\\mathcal{Z}_{\\theta_{z1}}(.;.)$ and $\\mathcal{Z}_{\\theta_{z2}}(.;.)$, which is 1x1 convo layers with both weights and biases initialized to be zeros, to connect these two blocks. Zero convolutions protect this back-bone by eliminating random noise as gradients in the initial training steps.\nThe final output is: $\\mathbf{y}_c = \\mathcal{F}_\\theta(\\mathbf{x}) + \\mathcal{Z}_{\\theta_{z2}}(\\mathcal{F}_{\\theta_c}(\\mathbf{x} + \\mathcal{Z}_{\\theta_{z1}}(\\mathbf{c})))$\nThe ControlNet architecture. (Image source:\nZhang et al. 2023\n)\nDiffusion Transformer\n(\nDiT\n;\nPeebles & Xie, 2023\n) for diffusion modeling operates on latent patches, using the same design space of\nLDM\n(Latent Diffusion Model)]. DiT has the following setup:\nTake the latent representation of an input $\\mathbf{z}$ as input to DiT.\n“Patchify” the noise latent of size $I \\times I \\times C$ into patches of size $p$ and convert it into a sequence of patches of size $(I/p)^2$.\nThen this sequence of tokens go through Transformer blocks. They are exploring three different designs for how to do generation conditioned on contextual information like timestep $t$ or class label $c$. Among three designs,\nadaLN (Adaptive layer norm)-Zero\nworks out the best, better than in-context conditioning and cross-attention block. The scale and shift parameters, $\\gamma$ and $\\beta$, are regressed from the sum of the embedding vectors of $t$ and $c$. The dimension-wise scaling parameters $\\alpha$ is also regressed and applied immediately prior to any residual connections within the DiT block.\nThe transformer decoder outputs noise predictions and an output diagonal covariance prediction.\nThe Diffusion Transformer (DiT) architecture.\n(Image source:\nPeebles & Xie, 2023\n)\nTransformer architecture can be easily scaled up and it is well known for that. This is one of the biggest benefits of DiT as its performance scales up with more compute and larger DiT models are more compute efficient according to the experiments.\nQuick Summary\n#\nPros\n: Tractability and flexibility are two conflicting objectives in generative modeling. Tractable models can be analytically evaluated and cheaply fit data (e.g. via a Gaussian or Laplace), but they cannot easily describe the structure in rich datasets. Flexible models can fit arbitrary structures in data, but evaluating, training, or sampling from these models is usually expensive. Diffusion models are both analytically tractable and flexible\nCons\n: Diffusion models rely on a long Markov chain of diffusion steps to generate samples, so it can be quite expensive in terms of time and compute. New methods have been proposed to make the process much faster, but the sampling is still slower than GAN.\nCitation\n#\nCited as:\nWeng, Lilian. (Jul 2021). What are diffusion models? Lil’Log. https://lilianweng.github.io/posts/2021-07-11-diffusion-models/.\nOr\n@article{weng2021diffusion,\n  title   = \"What are diffusion models?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Jul\",\n  url     = \"https://lilianweng.github.io/posts/2021-07-11-diffusion-models/\"\n}\nReferences\n#\n[1] Jascha Sohl-Dickstein et al.\n“Deep Unsupervised Learning using Nonequilibrium Thermodynamics.”\nICML 2015.\n[2] Max Welling & Yee Whye Teh.\n“Bayesian learning via stochastic gradient langevin dynamics.”\nICML 2011.\n[3] Yang Song & Stefano Ermon.\n“Generative modeling by estimating gradients of the data distribution.”\nNeurIPS 2019.\n[4] Yang Song & Stefano Ermon.\n“Improved techniques for training score-based generative models.”\nNeuriPS 2020.\n[5] Jonathan Ho et al.\n“Denoising diffusion probabilistic models.”\narxiv Preprint arxiv:2006.11239 (2020). [\ncode\n]\n[6] Jiaming Song et al.\n“Denoising diffusion implicit models.”\narxiv Preprint arxiv:2010.02502 (2020). [\ncode\n]\n[7] Alex Nichol & Prafulla Dhariwal.\n“Improved denoising diffusion probabilistic models”\narxiv Preprint arxiv:2102.09672 (2021). [\ncode\n]\n[8] Prafula Dhariwal & Alex Nichol.\n“Diffusion Models Beat GANs on Image Synthesis.”\narxiv Preprint arxiv:2105.05233 (2021). [\ncode\n]\n[9] Jonathan Ho & Tim Salimans.\n“Classifier-Free Diffusion Guidance.”\nNeurIPS 2021 Workshop on Deep Generative Models and Downstream Applications.\n[10] Yang Song, et al.\n“Score-Based Generative Modeling through Stochastic Differential Equations.”\nICLR 2021.\n[11] Alex Nichol, Prafulla Dhariwal & Aditya Ramesh, et al.\n“GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models.”\nICML 2022.\n[12] Jonathan Ho, et al.\n“Cascaded diffusion models for high fidelity image generation.”\nJ. Mach. Learn. Res. 23 (2022): 47-1.\n[13] Aditya Ramesh et al.\n“Hierarchical Text-Conditional Image Generation with CLIP Latents.”\narxiv Preprint arxiv:2204.06125 (2022).\n[14] Chitwan Saharia & William Chan, et al.\n“Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding.”\narxiv Preprint arxiv:2205.11487 (2022).\n[15] Rombach & Blattmann, et al.\n“High-Resolution Image Synthesis with Latent Diffusion Models.”\nCVPR 2022.\ncode\n[16] Song et al.\n“Consistency Models”\narxiv Preprint arxiv:2303.01469 (2023)\n[17] Salimans & Ho.\n“Progressive Distillation for Fast Sampling of Diffusion Models”\nICLR 2022.\n[18] Ronneberger, et al.\n“U-Net: Convolutional Networks for Biomedical Image Segmentation”\nMICCAI 2015.\n[19] Peebles & Xie.\n“Scalable diffusion models with transformers.”\nICCV 2023.\n[20] Zhang et al.\n“Adding Conditional Control to Text-to-Image Diffusion Models.”\narxiv Preprint arxiv:2302.05543 (2023).",
            "metadata": {
              "title": "What are Diffusion Models? | Lil'Log",
              "description": "[Updated on 2021-09-19: Highly recommend this blog post on score-based generative modeling by Yang Song (author of several key papers in the references)].\n[Updated on 2022-08-27: Added classifier-free guidance, GLIDE, unCLIP and Imagen.\n[Updated on 2022-08-31: Added latent diffusion model.\n[Updated on 2024-04-13: Added progressive distillation, consistency models, and the Model Architecture section.",
              "keywords": "generative-model, math-heavy, image-generation",
              "author": "Lilian Weng",
              "og:title": "What are Diffusion Models?",
              "og:description": "[Updated on 2021-09-19: Highly recommend this blog post on score-based generative modeling by Yang Song (author of several key papers in the references)].\n[Updated on 2022-08-27: Added classifier-free guidance, GLIDE, unCLIP and Imagen.\n[Updated on 2022-08-31: Added latent diffusion model.\n[Updated on 2024-04-13: Added progressive distillation, consistency models, and the Model Architecture section.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/",
              "twitter:card": "summary",
              "twitter:title": "What are Diffusion Models?",
              "twitter:description": "[Updated on 2021-09-19: Highly recommend this blog post on score-based generative modeling by Yang Song (author of several key papers in the references)].\n[Updated on 2022-08-27: Added classifier-free guidance, GLIDE, unCLIP and Imagen.\n[Updated on 2022-08-31: Added latent diffusion model.\n[Updated on 2024-04-13: Added progressive distillation, consistency models, and the Model Architecture section.",
              "article:section": "posts",
              "article:published_time": "2021-07-11T00:00:00+00:00",
              "article:modified_time": "2021-07-11T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/93e53a97f2e3/code/body-000.txt",
                "chars": 253,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/generative-overview.png",
                "bytes": 525595,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-41a09a8696808ecce0b1.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/generative-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM.png",
                "bytes": 839600,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-e78e0ba4b34cda911aa0.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-example.png",
                "bytes": 4019404,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-9f58f5472b55d74decc4.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM-algo.png",
                "bytes": 280949,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-8f6527c6c3694c587d18.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDPM-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-beta.png",
                "bytes": 128389,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-ea3831d82b483995f8de.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/diffusion-beta.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/improved-DDPM-nll.png",
                "bytes": 461423,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-2a1b7652ba6cc48a1275.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/improved-DDPM-nll.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/conditioned-DDPM.png",
                "bytes": 1535460,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-457cd3bc047052c18add.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/conditioned-DDPM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDIM-results.png",
                "bytes": 136690,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-7b1d616dab0a8609f18b.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DDIM-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation.png",
                "bytes": 139161,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-feaad52a803d77f9d89b.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation-algo.png",
                "bytes": 337076,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-d3eae5a72206efa4852f.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/progressive-distillation-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models.png",
                "bytes": 531125,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-f63895c8c6c047926f5f.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models-exp.png",
                "bytes": 701014,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-cf193ab727b4044922a6.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/consistency-models-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/image-distortion-rate.png",
                "bytes": 858306,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-7865196e2489fc001d22.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/image-distortion-rate.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/latent-diffusion-arch.png",
                "bytes": 338942,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-364a0fd3015ab3fcaca4.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/latent-diffusion-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/cascaded-diffusion.png",
                "bytes": 428232,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-34e80819222058397d52.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/cascaded-diffusion.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/unCLIP.png",
                "bytes": 750479,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-92f9487fb8e9f97c5122.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/unCLIP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/U-net.png",
                "bytes": 173159,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-7726aba941acd21dd196.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/U-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/ControlNet.png",
                "bytes": 96971,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-7ca77e5b5a81baabf985.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/ControlNet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DiT.png",
                "bytes": 106505,
                "reused": false,
                "local_path": "attachments/93e53a97f2e3/images/body-b56eeacd975c4881227f.png",
                "src": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/DiT.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://yang-song.github.io/blog/2021/score/",
                "label": "score-based generative modeling",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
                "label": "Flow-based",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03585",
                "label": "Sohl-Dickstein et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.05600",
                "label": "Yang & Ermon, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.11239",
                "label": "Ho et al. 2020",
                "type": "a"
              },
              {
                "href": "https://www.stats.ox.ac.uk/~teh/research/compstats/WelTeh2011a.pdf",
                "label": "Welling & Teh 2011",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "closed form",
                "type": "a"
              },
              {
                "href": "http://www.iro.umontreal.ca/~vincentp/Publications/smdae_techreport.pdf",
                "label": "Vincent, 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07088",
                "label": "Song et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2102.09672",
                "label": "Nichol & Dhariwal (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2105.05233",
                "label": "Dhariwal & Nichol (2021)",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=qw8AKxfYbI",
                "label": "Ho & Salimans, 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2112.10741",
                "label": "Nichol, Dhariwal & Ramesh, et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.02502",
                "label": "Song et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2202.00512",
                "label": "Salimans & Ho, 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2303.01469",
                "label": "Song et al. 2023",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Ordinary_differential_equation",
                "label": "ODE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "DQN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "momentum",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.03924",
                "label": "LPIPS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2112.10752",
                "label": "Rombach & Blattmann, et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2106.15282",
                "label": "Ho et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2204.06125",
                "label": "Ramesh et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2205.11487",
                "label": "Saharia et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.04597",
                "label": "Ronneberger, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2302.05543",
                "label": "Zhang et al. 2023",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2212.09748",
                "label": "Peebles & Xie, 2023",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09011",
                "label": "“Improved techniques for training score-based generative models.”",
                "type": "a"
              },
              {
                "href": "https://github.com/hojonathanho/diffusion",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/ermongroup/ddim",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/improved-diffusion",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/guided-diffusion",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2207.12598",
                "label": "“Classifier-Free Diffusion Guidance.”",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=PxTIG12RRHS",
                "label": "“Score-Based Generative Modeling through Stochastic Differential Equations.”",
                "type": "a"
              },
              {
                "href": "https://github.com/CompVis/latent-diffusion",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:12Z",
            "source_url": "https://lilianweng.github.io/posts/2021-07-11-diffusion-models/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03585",
                "bytes": 4355107,
                "reused": false,
                "local_path": "papers/repair/cdd3500c06ab19cbba99.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.05600",
                "bytes": 8113050,
                "reused": false,
                "local_path": "papers/repair/3b4fd27642b43d30aa2f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.11239",
                "bytes": 10267274,
                "reused": false,
                "local_path": "papers/repair/f8a0cafabed0cfe88ca6.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.stats.ox.ac.uk/~teh/research/compstats/WelTeh2011a.pdf",
                "bytes": 329916,
                "reused": false,
                "local_path": "papers/repair/bbc40d9999e1f9f5fc48.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "http://www.iro.umontreal.ca/~vincentp/Publications/smdae_techreport.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:54:23Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07088",
                "bytes": 6419033,
                "reused": false,
                "local_path": "papers/repair/6686aebbd982d6117171.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2102.09672",
                "bytes": 12442086,
                "reused": false,
                "local_path": "papers/repair/e655aaac9c8d5692cbb1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2105.05233",
                "bytes": 39795106,
                "reused": false,
                "local_path": "papers/repair/2cc7d9f8c42587f06289.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2112.10741",
                "bytes": 21259715,
                "reused": false,
                "local_path": "papers/repair/761e685eac3e57a5db36.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.02502",
                "bytes": 10857218,
                "reused": true,
                "local_path": "papers/repair/2e617588af84373a622f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2202.00512",
                "bytes": 3488589,
                "reused": true,
                "local_path": "papers/repair/353b5d2204f89a0a3e98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2303.01469",
                "bytes": 31529980,
                "reused": true,
                "local_path": "papers/repair/c129e904a22d86f9e0a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.03924",
                "bytes": 5543537,
                "reused": false,
                "local_path": "papers/repair/ff24fdb2d1004cfd5df4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2112.10752",
                "bytes": 40842586,
                "reused": true,
                "local_path": "papers/repair/84de7ccc1cc12ec4cb29.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2106.15282",
                "bytes": 29348312,
                "reused": false,
                "local_path": "papers/repair/2e72edcbfd718e17ae5f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2204.06125",
                "bytes": 42905303,
                "reused": true,
                "local_path": "papers/repair/037740aca2c3ab83f801.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2205.11487",
                "bytes": 11365725,
                "reused": true,
                "local_path": "papers/repair/8c48830dcf885dd9be79.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.04597",
                "bytes": 1648684,
                "reused": false,
                "local_path": "papers/repair/a930a1f7a86248051476.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2302.05543",
                "bytes": 16345157,
                "reused": false,
                "local_path": "papers/repair/d5ad0d4238973bc696c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2212.09748",
                "bytes": 43824062,
                "reused": true,
                "local_path": "papers/repair/6ff6a352b0138ad5d782.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09011",
                "bytes": 13161339,
                "reused": false,
                "local_path": "papers/repair/c2644ba086fa34d7dffc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2207.12598",
                "bytes": 3773509,
                "reused": false,
                "local_path": "papers/repair/b118a9b962027e6555c7.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 54348,
            "expected_body_images": 19,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/93e53a97f2e3/pages/source.html",
            "local_html": "attachments/93e53a97f2e3/pages/article.html",
            "body_base_path": "attachments/93e53a97f2e3/pages/",
            "body_markdown_path": "attachments/93e53a97f2e3/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
          "status": "partial",
          "article_id": "bf0a610ccb4a",
          "local_path": "series-follow/1602/repair/61967ef293614fa66635.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
              "bytes": 513885,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f359d38ab20e9cdac179.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
              "bytes": 1270278,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8d6f8ad7272758de8c53.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
              "bytes": 768852,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7c81aafa4666fddd3762.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
              "bytes": 2642257,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c64df87fedc22e7713a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
              "bytes": 249192,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d72676a1e2d7d681665b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
              "bytes": 737673,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/284f09a3dc26a2be2be6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "bytes": 1162740,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/574c20fa1107bf61368d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
              "bytes": 566411,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/817ed503b242a7831692.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
              "bytes": 103291,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/26dfcda8fac62755a0e6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
              "bytes": 225014,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a7ef42a592f8d64c0933.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
              "bytes": 267029,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/38455ea040ea0eae9625.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
              "bytes": 163908,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2f0fc009f289b69c8d79.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
              "bytes": 1281590,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e3a5248959b284127268.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
              "bytes": 1411892,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/316474d8ca427819890a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
              "bytes": 218384,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7dd458cefc09c96c4325.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
              "bytes": 135102,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/70000ddd170ac7e5840b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
              "bytes": 2011971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ae4b346db197ccab2cfe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
              "bytes": 157839,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1da73a82998c80ae17c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
              "bytes": 1115258,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/976ef652676b26b5a203.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
              "bytes": 1886891,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f8bf05d0018c01caf352.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
              "bytes": 2352713,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dee16f2c447f7c91e79e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
              "bytes": 917157,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7de401f88063093a58d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
              "bytes": 391776,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ce13a8280e64dce3dbf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
              "bytes": 1753636,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c37fd073afd7cb9698fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
              "bytes": 1839222,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e113f6beb0962c59d170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
              "bytes": 164404,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c9ea48204e2765c959ab.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
              "bytes": 388169,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/139471e0d9b6eef5fde9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
              "bytes": 350225,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/211c4ab593d56ae944a3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Self-Supervised Representation Learning",
            "keywords": "自监督,表示学习,预训练",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "publish_date": "2019-11",
            "corpus_stage": "预训练/SFT",
            "notes": "自监督表示学习综述",
            "id": "bf0a610ccb4a",
            "collected_at": "2026-10-02T14:13:29",
            "title": "Self-Supervised Representation Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-01-09: add a new section on\nContrastive Predictive Coding\n].\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n[Updated on 2020-07-08: add a\n“Bisimulation”\nsection on DeepMDP and DBC.]\n[Updated on 2020-09-12: add\nMoCo V2\nand\nBYOL\nin the “Momentum Contrast” section.]\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on\n“Contrastive Representation Learning”\n]\nGiven a task and enough labels, supervised learning can solve it really well. Good performance usually requires a decent amount of labels, but collecting manual labels is expensive (i.e. ImageNet) and hard to be scaled up. Considering the amount of unlabelled data (e.g. free text, all the images on the Internet) is substantially more than a limited number of human curated labelled datasets, it is kinda wasteful not to use them. However, unsupervised learning is not easy and usually works much less efficiently than supervised learning.\nWhat if we can get labels for free for unlabelled data and train unsupervised dataset in a supervised manner? We can achieve this by framing a supervised learning task in a special form to predict only a subset of information using the rest. In this way, all the information needed, both inputs and labels, has been provided. This is known as\nself-supervised learning\n.\nThis idea has been widely used in language modeling. The default task for a language model is to predict the next word given the past sequence.\nBERT\nadds two other auxiliary tasks and both rely on self-generated labels.\nA great summary of how self-supervised learning tasks can be constructed (Image source:\nLeCun’s talk\n)\nHere\nis a nicely curated list of papers in self-supervised learning. Please check it out if you are interested in reading more in depth.\nNote that this post does not focus on either NLP /\nlanguage modeling\nor\ngenerative modeling\n.\nWhy Self-Supervised Learning?\n#\nSelf-supervised learning empowers us to exploit a variety of labels that come with the data for free. The motivation is quite straightforward. Producing a dataset with clean labels is expensive but unlabeled data is being generated all the time. To make use of this much larger amount of unlabeled data, one way is to set the learning objectives properly so as to get supervision from the data itself.\nThe\nself-supervised task\n, also known as\npretext task\n, guides us to a supervised loss function. However, we usually don’t care about the final performance of this invented task. Rather we are interested in the learned intermediate representation with the expectation that this representation can carry good semantic or structural meanings and can be beneficial to a variety of practical downstream tasks.\nFor example, we might rotate images at random and train a model to predict how each input image is rotated. The rotation prediction task is made-up, so the actual accuracy is unimportant, like how we treat auxiliary tasks. But we expect the model to learn high-quality latent variables for real-world tasks, such as constructing an object recognition classifier with very few labeled samples.\nBroadly speaking, all the generative models can be considered as self-supervised, but with different goals: Generative models focus on creating diverse and realistic images, while self-supervised representation learning care about producing good features generally helpful for many tasks. Generative modeling is not the focus of this post, but feel free to check my\nprevious posts\n.\nImages-Based\n#\nMany ideas have been proposed for self-supervised representation learning on images. A common workflow is to train a model on one or multiple pretext tasks with unlabelled images and then use one intermediate feature layer of this model to feed a multinomial logistic regression classifier on ImageNet classification. The final classification accuracy quantifies how good the learned representation is.\nRecently, some researchers proposed to train supervised learning on labelled data and self-supervised pretext tasks on unlabelled data simultaneously with shared weights, like in\nZhai et al, 2019\nand\nSun et al, 2019\n.\nDistortion\n#\nWe expect small distortion on an image does not modify its original semantic meaning or geometric forms. Slightly distorted images are considered the same as original and thus the learned features are expected to be invariant to distortion.\nExemplar-CNN\n(\nDosovitskiy et al., 2015\n) create surrogate training datasets with unlabeled image patches:\nSample $N$ patches of size 32 × 32 pixels from different images at varying positions and scales, only from regions containing considerable gradients as those areas cover edges and tend to contain objects or parts of objects. They are\n“exemplary”\npatches.\nEach patch is distorted by applying a variety of random transformations (i.e., translation, rotation, scaling, etc.). All the resulting distorted patches are considered to belong to the\nsame surrogate class\n.\nThe pretext task is to discriminate between a set of surrogate classes. We can arbitrarily create as many surrogate classes as we want.\nThe original patch of a cute deer is in the top left corner. Random transformations are applied, resulting in a variety of distorted patches. All of them should be classified into the same class in the pretext task. (Image source:\nDosovitskiy et al., 2015\n)\nRotation\nof an entire image (\nGidaris et al. 2018\nis another interesting and cheap way to modify an input image while the semantic content stays unchanged. Each input image is first rotated by a multiple of $90^\\circ$ at random, corresponding to $[0^\\circ, 90^\\circ, 180^\\circ, 270^\\circ]$. The model is trained to predict which rotation has been applied, thus a 4-class classification problem.\nIn order to identify the same image with different rotations, the model has to learn to recognize high level object parts, such as heads, noses, and eyes, and the relative positions of these parts, rather than local patterns. This pretext task drives the model to learn semantic concepts of objects in this way.\nIllustration of self-supervised learning by rotating the entire input images. The model learns to predict which rotation is applied. (Image source:\nGidaris et al. 2018\n)\nPatches\n#\nThe second category of self-supervised learning tasks extract multiple patches from one image and ask the model to predict the relationship between these patches.\nDoersch et al. (2015)\nformulates the pretext task as predicting the\nrelative position\nbetween two random patches from one image. A model needs to understand the spatial context of objects in order to tell the relative position between parts.\nThe training patches are sampled in the following way:\nRandomly sample the first patch without any reference to image content.\nConsidering that the first patch is placed in the middle of a 3x3 grid, and the second patch is sampled from its 8 neighboring locations around it.\nTo avoid the model only catching low-level trivial signals, such as connecting a straight line across boundary or matching local patterns, additional noise is introduced by:\nAdd gaps between patches\nSmall jitters\nRandomly downsample some patches to as little as 100 total pixels, and then upsampling it, to build robustness to pixelation.\nShift green and magenta toward gray or randomly drop 2 of 3 color channels (See\n“chromatic aberration”\nbelow)\nThe model is trained to predict which one of 8 neighboring locations the second patch is selected from, a classification problem over 8 classes.\nIllustration of self-supervised learning by predicting the relative position of two random patches. (Image source:\nDoersch et al., 2015\n)\nOther than trivial signals like boundary patterns or textures continuing, another interesting and a bit surprising trivial solution was found, called\n“chromatic aberration”\n. It is triggered by different focal lengths of lights at different wavelengths passing through the lens. In the process, there might exist small offsets between color channels. Hence, the model can learn to tell the relative position by simply comparing how green and magenta are separated differently in two patches. This is a trivial solution and has nothing to do with the image content. Pre-processing images by shifting green and magenta toward gray or randomly dropping 2 of 3 color channels can avoid this trivial solution.\nIllustration of how chromatic aberration happens. (Image source:\nwikipedia\n)\nSince we have already set up a 3x3 grid in each image in the above task, why not use all of 9 patches rather than only 2 to make the task more difficult? Following this idea,\nNoroozi & Favaro (2016)\ndesigned a\njigsaw puzzle\ngame as pretext task: The model is trained to place 9 shuffled patches back to the original locations.\nA convolutional network processes each patch independently with shared weights and outputs a probability vector per patch index out of a predefined set of permutations. To control the difficulty of jigsaw puzzles, the paper proposed to shuffle patches according to a predefined permutation set and configured the model to predict a probability vector over all the indices in the set.\nBecause how the input patches are shuffled does not alter the correct order to predict. A potential improvement to speed up training is to use permutation-invariant graph convolutional network (GCN) so that we don’t have to shuffle the same set of patches multiple times, same idea as in this\npaper\n.\nIllustration of self-supervised learning by solving jigsaw puzzle. (Image source:\nNoroozi & Favaro, 2016\n)\nAnother idea is to consider “feature” or “visual primitives” as a scalar-value attribute that can be summed up over multiple patches and compared across different patches. Then the relationship between patches can be defined by\ncounting features\nand simple arithmetic (\nNoroozi, et al, 2017\n).\nThe paper considers two transformations:\nScaling\n:  If an image is scaled up by 2x, the number of visual primitives should stay the same.\nTiling\n: If an image is tiled into a 2x2 grid, the number of visual primitives is expected to be the sum, 4 times the original feature counts.\nThe model learns a feature encoder $\\phi(.)$ using the above feature counting relationship. Given an input image $\\mathbf{x} \\in \\mathbb{R}^{m \\times n \\times 3}$, considering two types of transformation operators:\nDownsampling operator, $D: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: downsample by a factor of 2\nTiling operator $T_i: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: extract the $i$-th tile from a 2x2 grid of the image.\nWe expect to learn:\n$$\n\\phi(\\mathbf{x}) = \\phi(D \\circ \\mathbf{x}) = \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\n$$\nThus the MSE loss is: $\\mathcal{L}_\\text{feat} = |\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2$. To avoid trivial solution $\\phi(\\mathbf{x}) = \\mathbf{0}, \\forall{\\mathbf{x}}$, another loss term is added to encourage the difference between features of two different images: $\\mathcal{L}_\\text{diff} = \\max(0, c -|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2)$, where $\\mathbf{y}$ is another input image different from $\\mathbf{x}$ and $c$ is a scalar constant. The final loss is:\n$$\n\\mathcal{L} \n= \\mathcal{L}_\\text{feat} + \\mathcal{L}_\\text{diff} \n= \\|\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2 + \\max(0, M -\\|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2)\n$$\nSelf-supervised representation learning by counting features. (Image source:\nNoroozi, et al, 2017\n)\nColorization\n#\nColorization\ncan be used as a powerful self-supervised task: a model is trained to color a grayscale input image; precisely the task is to map this image to a distribution over quantized color value outputs (\nZhang et al. 2016\n).\nThe model outputs colors in the the\nCIE L\na\nb* color space\n. The L\na\nb* color is designed to approximate human vision, while, in contrast, RGB or CMYK models the color output of physical devices.\nL* component matches human perception of lightness; L* = 0 is black and L* = 100 indicates white.\na* component represents green (negative) / magenta (positive) value.\nb* component models blue (negative) /yellow (positive) value.\nDue to the multimodal nature of the colorization problem, cross-entropy loss of predicted probability distribution over binned color values works better than L2 loss of the raw color values. The a\nb\ncolor space is quantized with bucket size 10.\nTo balance between common colors (usually low a\nb\nvalues, of common backgrounds like clouds, walls, and dirt) and rare colors (which are likely associated with key objects in the image), the loss function is rebalanced with a weighting term that boosts the loss of infrequent color buckets. This is just like why we need both\ntf and idf\nfor scoring words in information retrieval model. The weighting term is constructed as: (1-λ) * Gaussian-kernel-smoothed empirical probability distribution + λ * a uniform distribution, where both distributions are over the quantized a\nb\ncolor space.\nGenerative Modeling\n#\nThe pretext task in generative modeling is to reconstruct the original input while learning meaningful latent representation.\nThe\ndenoising autoencoder\n(\nVincent, et al, 2008\n) learns to recover an image from a version that is partially corrupted or has random noise. The design is inspired by the fact that humans can easily recognize objects in pictures even with noise, indicating that key visual features can be extracted and separated from noise. See my\nold post\n.\nThe\ncontext encoder\n(\nPathak, et al., 2016\n) is trained to fill in a missing piece in the image. Let $\\hat{M}$ be a binary mask, 0 for dropped pixels and 1 for remaining input pixels. The model is trained with a combination of the reconstruction (L2) loss and the adversarial loss. The removed regions defined by the mask could be of any shape.\n$$\n\\begin{aligned}\n\\mathcal{L}(\\mathbf{x}) &= \\mathcal{L}_\\text{recon}(\\mathbf{x}) + \\mathcal{L}_\\text{adv}(\\mathbf{x})\\\\\n\\mathcal{L}_\\text{recon}(\\mathbf{x}) &= \\|(1 - \\hat{M}) \\odot (\\mathbf{x} - F(\\hat{M} \\odot \\mathbf{x})) \\|_2^2 \\\\\n\\mathcal{L}_\\text{adv}(\\mathbf{x}) &= \\max_D \\mathbb{E}_{\\mathbf{x}} [\\log D(\\mathbf{x}) + \\log(1 - D(F(\\hat{M} \\odot \\mathbf{x})))]\n\\end{aligned}\n$$\nwhere $F(.)$ is the full pipeline of reconstructing the input image with missing regions via impainting, including both encoder and decoder portions in $D(.)$ is the discriminator model jointly trained, like in\nGAN\n.\nIllustration of context encoder. (Image source:\nPathak, et al., 2016\n)\nWhen applying a mask on an image, the context encoder removes information of all the color channels in partial regions. How about only hiding a subset of channels? The\nsplit-brain autoencoder\n(\nZhang et al., 2017\n) does this by predicting a subset of color channels from the rest of channels. Let the data tensor $\\mathbf{x} \\in \\mathbb{R}^{h \\times w \\times \\vert C \\vert }$ with $C$ color channels be the input for the $l$-th layer of the network. It is split into two disjoint parts, $\\mathbf{x}_1 \\in \\mathbb{R}^{h \\times w \\times \\vert C_1 \\vert}$ and $\\mathbf{x}_2 \\in \\mathbb{R}^{h \\times w \\times \\vert C_2 \\vert}$, where $C_1 , C_2 \\subseteq C$. Then two sub-networks are trained to do two complementary predictions: one network $f_1$ predicts $\\mathbf{x}_2$ from $\\mathbf{x}_1$ and the other network $f_1$ predicts $\\mathbf{x}_1$ from $\\mathbf{x}_2$. The loss is either L1 loss or cross entropy if color values are quantized.\nThe split can happen once on the RGB-D or L\na\nb* colorspace, or happen even in every layer of a CNN network in which the number of channels can be arbitrary.\nIllustration of split-brain autoencoder. (Image source:\nZhang et al., 2017\n)\nThe generative adversarial networks (GANs) are able to learn to map from simple latent variables to arbitrarily complex data distributions. Studies have shown that the latent space of such generative models captures semantic variation in the data; e.g. when training GAN models on human faces, some latent variables are associated with facial expression, glasses, gender, etc  (\nRadford et al., 2016\n).\nBidirectional GANs\n(\nDonahue, et al, 2017\n) introduces an additional encoder $E(.)$ to learn the mappings from the input to the latent variable $\\mathbf{z}$. The discriminator $D(.)$ predicts in the joint space of the input data and latent representation, $(\\mathbf{x}, \\mathbf{z})$, to tell apart the generated pair $(\\mathbf{x}, E(\\mathbf{x}))$ from the real one $(G(\\mathbf{z}), \\mathbf{z})$. The model is trained to optimize the objective: $\\min_{G, E} \\max_D V(D, E, G)$, where the generator $G$ and the encoder $E$ learn to generate data and latent variables that are realistic enough to confuse the discriminator and at the same time the discriminator $D$ tries to differentiate real and generated data.\n$$\nV(D, E, G) = \\mathbb{E}_{\\mathbf{x} \\sim p_\\mathbf{x}} [ \\underbrace{\\mathbb{E}_{\\mathbf{z} \\sim p_E(.\\vert\\mathbf{x})}[\\log D(\\mathbf{x}, \\mathbf{z})]}_{\\log D(\\text{real})} ] + \\mathbb{E}_{\\mathbf{z} \\sim p_\\mathbf{z}} [ \\underbrace{\\mathbb{E}_{\\mathbf{x} \\sim p_G(.\\vert\\mathbf{z})}[\\log 1 - D(\\mathbf{x}, \\mathbf{z})]}_{\\log(1- D(\\text{fake}))}) ]\n$$\nIllustration of how Bidirectional GAN works. (Image source:\nDonahue, et al, 2017\n)\nContrastive Learning\n#\nThe\nContrastive Predictive Coding (CPC)\n(\nvan den Oord, et al. 2018\n) is an approach for unsupervised learning from high-dimensional data by translating a generative modeling problem to a classification problem. The\ncontrastive loss\nor\nInfoNCE loss\nin CPC, inspired by\nNoise Contrastive Estimation (NCE)\n, uses cross-entropy loss to measure how well the model can classify the “future” representation amongst a set of unrelated “negative” samples. Such design is partially motivated by the fact that the unimodal loss like MSE has no enough capacity but learning a full generative model could be too expensive.\nIllustration of applying Contrastive Predictive Coding on the audio input. (Image source:\nvan den Oord, et al. 2018\n)\nCPC uses an encoder to compress the input data $z_t = g_\\text{enc}(x_t)$ and an\nautoregressive\ndecoder to learn the high-level context that is potentially shared across future predictions, $c_t = g_\\text{ar}(z_{\\leq t})$. The end-to-end training relies on the NCE-inspired contrastive loss.\nWhile predicting future information, CPC is optimized to maximize the the mutual information between input $x$ and context vector $c$:\n$$\nI(x; c) = \\sum_{x, c} p(x, c) \\log\\frac{p(x, c)}{p(x)p(c)} = \\sum_{x, c} p(x, c)\\log\\frac{p(x|c)}{p(x)}\n$$\nRather than modeling the future observations $p_k(x_{t+k} \\vert c_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $x_{t+k}$ and $c_t$:\n$$\nf_k(x_{t+k}, c_t) = \\exp(z_{t+k}^\\top W_k c_t) \\propto \\frac{p(x_{t+k}|c_t)}{p(x_{t+k})}\n$$\nwhere $f_k$ can be unnormalized and a linear transformation $W_k^\\top c_t$ is used for the prediction with a different $W_k$ matrix for every step $k$.\nGiven a set of $N$ random samples $X = \\{x_1, \\dots, x_N\\}$ containing only one positive sample $x_t \\sim p(x_{t+k} \\vert c_t)$ and $N-1$ negative samples $x_{i \\neq t} \\sim p(x_{t+k})$, the cross-entropy loss for classifying the positive sample (where $\\frac{f_k}{\\sum f_k}$ is the prediction) correctly is:\n$$\n\\mathcal{L}_N = - \\mathbb{E}_X \\Big[\\log \\frac{f_k(x_{t+k}, c_t)}{\\sum_{i=1}^N f_k (x_i, c_t)}\\Big]\n$$\nIllustration of applying Contrastive Predictive Coding on images. (Image source:\nvan den Oord, et al. 2018\n)\nWhen using CPC on images (\nHenaff, et al. 2019\n), the predictor network should only access a masked feature set to avoid a trivial prediction. Precisely:\nEach input image is divided into a set of overlapped patches and each patch is encoded by a resnet encoder, resulting in compressed feature vector $z_{i,j}$.\nA masked conv net makes prediction with a mask such that the receptive field of a given output neuron can only see things above it in the image. Otherwise, the prediction problem would be trivial. The prediction can be made in both directions (top-down and bottom-up).\nThe prediction is made for $z_{i+k, j}$ from context $c_{i,j}$: $\\hat{z}_{i+k, j} = W_k c_{i,j}$.\nA contrastive loss quantifies this prediction with a goal to correctly identify the target among a set of negative representation $\\{z_l\\}$ sampled from other patches in the same image and other images in the same batch:\n$$\n\\mathcal{L}_\\text{CPC} \n= -\\sum_{i,j,k} \\log p(z_{i+k, j} \\vert \\hat{z}_{i+k, j}, \\{z_l\\}) \n= -\\sum_{i,j,k} \\log \\frac{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j})}{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j}) + \\sum_l \\exp(\\hat{z}_{i+k, j}^\\top z_l)}\n$$\nFor more content on contrastive learning, check out the post on\n“Contrastive Representation Learning”\n.\nVideo-Based\n#\nA video contains a sequence of semantically related frames. Nearby frames are close in time and more correlated than frames further away. The order of frames describes certain rules of reasonings and physical logics; such as that object motion should be smooth and gravity is pointing down.\nA common workflow is to train a model on one or multiple pretext tasks with unlabelled videos and then feed one intermediate feature layer of this model to fine-tune a simple model on downstream tasks of action classification, segmentation or object tracking.\nTracking\n#\nThe movement of an object is traced by a sequence of video frames. The difference between how the same object is captured on the screen in close frames is usually not big, commonly triggered by small motion of the object or the camera. Therefore any visual representation learned for the same object across close frames should be close in the latent feature space. Motivated by this idea,\nWang & Gupta, 2015\nproposed a way of unsupervised learning of visual representation by\ntracking moving objects\nin videos.\nPrecisely patches with motion are tracked over a small time window (e.g. 30 frames). The first patch $\\mathbf{x}$ and the last patch $\\mathbf{x}^+$ are selected and used as training data points. If we train the model directly to minimize the difference between feature vectors of two patches, the model may only learn to map everything to the same value. To avoid such a trivial solution, same as\nabove\n, a random third patch $\\mathbf{x}^-$ is added. The model learns the representation by enforcing the distance between two tracked patches to be closer than the distance between the first patch and a random one in the feature space, $D(\\mathbf{x}, \\mathbf{x}^-)) > D(\\mathbf{x}, \\mathbf{x}^+)$, where $D(.)$ is the cosine distance,\n$$\nD(\\mathbf{x}_1, \\mathbf{x}_2) = 1 - \\frac{f(\\mathbf{x}_1) f(\\mathbf{x}_2)}{\\|f(\\mathbf{x}_1)\\| \\|f(\\mathbf{x}_2\\|)}\n$$\nThe loss function is:\n$$\n\\mathcal{L}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) \n= \\max\\big(0, D(\\mathbf{x}, \\mathbf{x}^+) - D(\\mathbf{x}, \\mathbf{x}^-) + M\\big) + \\text{weight decay regularization term}\n$$\nwhere $M$ is a scalar constant controlling for the minimum gap between two distances; $M=0.5$ in the paper. The loss enforces $D(\\mathbf{x}, \\mathbf{x}^-) >= D(\\mathbf{x}, \\mathbf{x}^+) + M$ at the optimal case.\nThis form of loss function is also known as\ntriplet loss\nin the face recognition task, in which the dataset contains images of multiple people from multiple camera angles. Let $\\mathbf{x}^a$ be an anchor image of a specific person, $\\mathbf{x}^p$ be a positive image of this same person from a different angle and $\\mathbf{x}^n$ be a negative image of a different person. In the embedding space, $\\mathbf{x}^a$ should be closer to $\\mathbf{x}^p$ than $\\mathbf{x}^n$:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}^a, \\mathbf{x}^p, \\mathbf{x}^n) = \\max(0, \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^p) \\|_2^2 -  \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^n) \\|_2^2 + M)\n$$\nA slightly different form of the triplet loss, named\nn-pair loss\nis also commonly used for learning observation embedding in robotics tasks. See a\nlater section\nfor more related content.\nOverview of learning representation by tracking objects in videos. (a) Identify moving patches in short traces; (b) Feed two related patched and one random patch into a conv network with shared weights. (c) The loss function enforces the distance between related patches to be closer than the distance between random patches. (Image source:\nWang & Gupta, 2015\n)\nRelevant patches are tracked and extracted through a two-step unsupervised\noptical flow\napproach:\nObtain\nSURF\ninterest points and use\nIDT\nto obtain motion of each SURF point.\nGiven the trajectories of SURF interest points, classify these points as moving if the flow magnitude is more than 0.5 pixels.\nDuring training, given a pair of correlated patches $\\mathbf{x}$ and $\\mathbf{x}^+$, $K$ random patches $\\{\\mathbf{x}^-\\}$ are sampled in this same batch to form $K$ training triplets. After a couple of epochs,\nhard negative mining\nis applied to make the training harder and more efficient, that is, to search for random patches that maximize the loss and use them to do gradient updates.\nFrame Sequence\n#\nVideo frames are naturally positioned in chronological order. Researchers have proposed several self-supervised tasks, motivated by the expectation that good representation should learn the\ncorrect sequence\nof frames.\nOne idea is to\nvalidate frame order\n(\nMisra, et al 2016\n). The pretext task is to determine whether a sequence of frames from a video is placed in the correct temporal order (“temporal valid”). The model needs to track and reason about small motion of an object across frames to complete such a task.\nThe training frames are sampled from high-motion windows. Every time 5 frames are sampled $(f_a, f_b, f_c, f_d, f_e)$ and the timestamps are in order $a < b < c < d < e$. Out of 5 frames, one positive tuple $(f_b, f_c, f_d)$ and two negative tuples, $(f_b, f_a, f_d)$ and $(f_b, f_e, f_d)$ are created. The parameter $\\tau_\\max = \\vert b-d \\vert$ controls the difficulty of positive training instances (i.e. higher → harder) and the parameter $\\tau_\\min = \\min(\\vert a-b \\vert, \\vert d-e \\vert)$ controls the difficulty of negatives (i.e. lower → harder).\nThe pretext task of video frame order validation is shown to improve the performance on the downstream task of action recognition when used as a pretraining step.\nOverview of learning representation by validating the order of video frames. (a) the data sample process; (b) the model is a triplet siamese network, where all input frames have shared weights. (Image source:\nMisra, et al 2016\n)\nThe task in\nO3N\n(Odd-One-Out Network;\nFernando et al. 2017\n) is based on video frame sequence validation too. One step further from above, the task is to\npick the incorrect sequence\nfrom multiple video clips.\nGiven $N+1$ input video clips, one of them has frames shuffled, thus in the wrong order, and the rest $N$ of them remain in the correct temporal order. O3N learns to predict the location of the odd video clip. In their experiments, there are 6 input clips and each contain 6 frames.\nThe\narrow of time\nin a video contains very informative messages, on both low-level physics (e.g. gravity pulls objects down to the ground; smoke rises up; water flows downward.) and high-level event reasoning (e.g. fish swim forward; you can break an egg but cannot revert it.). Thus another idea is inspired by this to learn latent representation by predicting the arrow of time (AoT) — whether video playing forwards or backwards (\nWei et al., 2018\n).\nA classifier should capture both low-level physics and high-level semantics in order to predict the arrow of time. The proposed\nT-CAM\n(Temporal Class-Activation-Map) network accepts $T$ groups, each containing a number of frames of optical flow. The conv layer outputs from each group are concatenated and fed into binary logistic regression for predicting the arrow of time.\nOverview of learning representation by predicting the arrow of time. (a) Conv features of multiple groups of frame sequences are concatenated. (b) The top level contains 3 conv layers and average pooling. (Image source:\nWei et al, 2018\n)\nInterestingly, there exist a couple of artificial cues in the dataset. If not handled properly, they could lead to a trivial classifier without relying on the actual video content:\nDue to the video compression, the black framing might not be completely black but instead may contain certain information on the chronological order. Hence black framing should be removed in the experiments.\nLarge camera motion, like vertical translation or zoom-in/out, also provides strong signals for the arrow of time but independent of content. The processing stage should stabilize the camera motion.\nThe AoT pretext task is shown to improve the performance on action classification downstream task when used as a pretraining step. Note that fine-tuning is still needed.\nVideo Colorization\n#\nVondrick et al. (2018)\nproposed\nvideo colorization\nas a self-supervised learning problem, resulting in a rich representation that can be used for video segmentation and unlabelled visual region tracking,\nwithout extra fine-tuning\n.\nUnlike the image-based\ncolorization\n, here the task is to copy colors from a normal reference frame in color to another target frame in grayscale by leveraging the natural temporal coherency of colors across video frames (thus these two frames shouldn’t be too far apart in time). In order to copy colors consistently, the model is designed to learn to keep track of correlated pixels in different frames.\nVideo colorization by copying colors from a reference frame to target frames in grayscale.  (Image source:\nVondrick et al. 2018\n)\nThe idea is quite simple and smart. Let $c_i$ be the true color of the $i-th$ pixel in the reference frame and $c_j$ be the color of $j$-th pixel in the target frame. The predicted color of $j$-th color in the target $\\hat{c}_j$ is a weighted sum of colors of all the pixels in reference, where the weighting term measures the similarity:\n$$\n\\hat{c}_j = \\sum_i A_{ij} c_i \\text{ where } A_{ij} = \\frac{\\exp(f_i f_j)}{\\sum_{i'} \\exp(f_{i'} f_j)}\n$$\nwhere $f$ are learned embeddings for corresponding pixels; $i’$ indexes all the pixels in the reference frame. The weighting term implements an attention-based pointing mechanism, similar to\nmatching network\nand\npointer network\n. As the full similarity matrix could be really large, both frames are downsampled. The categorical cross-entropy loss between $c_j$ and $\\hat{c}_j$ is used with quantized colors, just like in\nZhang et al. 2016\n.\nBased on how the reference frame are marked, the model can be used to complete several color-based downstream tasks such as tracking segmentation or human pose in time. No fine-tuning is needed. See\nUse video colorization to track object segmentation and human pose in time. (Image source:\nVondrick et al. (2018)\n)\nA couple common observations:\nCombining multiple pretext tasks improves performance;\nDeeper networks improve the quality of representation;\nSupervised learning baselines still beat all of them by far.\nControl-Based\n#\nWhen running a RL policy in the real world, such as controlling a physical robot on visual inputs, it is non-trivial to properly track states, obtain reward signals or determine whether a goal is achieved for real. The visual data has a lot of noise that is irrelevant to the true state and thus the equivalence of states cannot be inferred from pixel-level comparison. Self-supervised representation learning has shown great potential in learning useful state embedding that can be used directly as input to a control policy.\nAll the cases discussed in this section are in robotic learning, mainly for state representation from multiple camera views and goal representation.\nMulti-View Metric Learning\n#\nThe concept of metric learning has been mentioned multiple times in the\nprevious\nsections\n. A common setting is: Given a triple of samples, (\nanchor\n$s_a$,\npositive\nsample $s_p$,\nnegative\nsample $s_n$), the learned representation embedding $\\phi(s)$ fulfills that $s_a$ stays close to $s_p$ but far away from $s_n$ in the latent space.\nGrasp2Vec\n(\nJang & Devin et al., 2018\n) aims to learn an object-centric vision representation in the robot grasping task from free, unlabelled grasping activities. By object-centric, it means that, irrespective of how the environment or the robot looks like, if two images contain similar items, they should be mapped to similar representation; otherwise the embeddings should be far apart.\nA conceptual illustration of how grasp2vec learns an object-centric state embedding. (Image source:\nJang & Devin et al., 2018\n)\nThe grasping system can tell whether it moves an object but cannot tell which object it is. Cameras are set up to take images of the entire scene and the grasped object. During early training, the grasp robot is executed to grasp any object $o$ at random, producing a triple of images, $(s_\\text{pre}, s_\\text{post}, o)$:\n$o$ is an image of the grasped object held up to the camera;\n$s_\\text{pre}$ is an image of the scene\nbefore\ngrasping, with the object $o$ in the tray;\n$s_\\text{post}$ is an image of the same scene\nafter\ngrasping, without the object $o$ in the tray.\nTo learn object-centric representation, we expect the difference between embeddings of $s_\\text{pre}$ and $s_\\text{post}$ to capture the removed object $o$. The idea is quite interesting and similar to relationships that have been observed in\nword embedding\n,\ne.g.\ndistance(“king”, “queen”) ≈ distance(“man”, “woman”).\nLet $\\phi_s$ and $\\phi_o$ be the embedding functions for the scene and the object respectively. The model learns the representation by minimizing the distance between $\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})$ and $\\phi_o(o)$ using\nn-pair loss\n:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{grasp2vec} &= \\text{NPair}(\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post}), \\phi_o(o)) + \\text{NPair}(\\phi_o(o), \\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})) \\\\\n\\text{where }\\text{NPair}(a, p) &= \\sum_{i<{B}} -\\log\\frac{\\exp(a_i^\\top p_j)}{\\sum_{j<{B}, i\\neq j}\\exp(a_i^\\top p_j)} + \\lambda (\\|a_i\\|_2^2 + \\|p_i\\|_2^2)\n\\end{aligned}\n$$\nwhere $B$ refers to a batch of (anchor, positive) sample pairs.\nWhen framing representation learning as metric learning,\nn-pair loss\nis a common choice. Rather than processing explicit a triple of (anchor, positive, negative) samples, the n-pairs loss treats all other positive instances in one mini-batch across pairs as negatives.\nThe embedding function $\\phi_o$ works great for presenting a goal $g$ with an image. The reward function that quantifies how close the actually grasped object $o$ is close to the goal is defined as $r = \\phi_o(g) \\cdot \\phi_o(o)$. Note that computing rewards only relies on the learned latent space and doesn’t involve ground truth positions, so it can be used for training on real robots.\nLocalization results of grasp2vec embedding. The heatmap of localizing a goal object in a pre-grasping scene is defined as $\\phi\\_o(o)^\\top \\phi\\_{s, \\text{spatial}} (s\\_\\text{pre})$, where $\\phi\\_{s, \\text{spatial}}$ is the output of the last resnet block after ReLU. The fourth column is a failure case and the last three columns take real images as goals. (Image source:\nJang & Devin et al., 2018\n)\nOther than the embedding-similarity-based reward function, there are a few other tricks for training the RL policy in the grasp2vec framework:\nPosthoc labeling\n: Augment the dataset by labeling a randomly grasped object as a correct goal, like HER (Hindsight Experience Replay;\nAndrychowicz, et al., 2017\n).\nAuxiliary goal augmentation\n: Augment the replay buffer even further by relabeling transitions with unachieved goals; precisely, in each iteration, two goals are sampled $(g, g’)$ and both are used to add new transitions into replay buffer.\nTCN\n(\nTime-Contrastive Networks\n;\nSermanet, et al. 2018\n) learn from multi-camera view videos with the intuition that different viewpoints at the same timestep of the same scene should share the same embedding (like in\nFaceNet\n) while embedding should vary in time, even of the same camera viewpoint. Therefore embedding captures the semantic meaning of the underlying state rather than visual similarity. The TCN embedding is trained with\ntriplet loss\n.\nThe training data is collected by taking videos of the same scene simultaneously but from different angles. All the videos are unlabelled.\nAn illustration of time-contrastive approach for learning state embedding. The blue frames selected from two camera views at the same timestep are anchor and positive samples, while the red frame at a different timestep is the negative sample.\nTCN embedding extracts visual features that are invariant to camera configurations. It can be used to construct a reward function for imitation learning based on the euclidean distance between the demo video and the observations in the latent space.\nA further improvement over TCN is to learn embedding over multiple frames jointly rather than a single frame, resulting in\nmfTCN\n(\nMulti-frame\nTime-Contrastive Networks\n;\nDwibedi et al., 2019\n). Given a set of videos from several synchronized camera viewpoints, $v_1, v_2, \\dots, v_k$, the frame at time $t$ and the previous $n-1$ frames selected with stride $s$ in each video are aggregated and mapped into one embedding vector, resulting in a lookback window of size $(n−1) \\times s + 1$. Each frame first goes through a CNN to extract low-level features and then we use 3D temporal convolutions to aggregate frames in time. The model is trained with\nn-pairs loss\n.\nThe sampling process for training mfTCN. (Image source:\nDwibedi et al., 2019\n)\nThe training data is sampled as follows:\nFirst we construct two pairs of video clips. Each pair contains two clips from different camera views but with synchronized timesteps. These two sets of videos should be far apart in time.\nSample a fixed number of frames from each video clip in the same pair simultaneously with the same stride.\nFrames with the same timesteps are trained as positive samples in the n-pair loss, while frames across pairs are negative samples.\nmfTCN embedding can capture the position and velocity of objects in the scene (e.g. in cartpole) and can also be used as inputs for policy.\nAutonomous Goal Generation\n#\nRIG\n(\nReinforcement learning with\nImagined Goals\n;\nNair et al., 2018\n) described a way to train a goal-conditioned policy with unsupervised representation learning. A policy learns from self-supervised practice by first imagining “fake” goals and then trying to achieve them.\nThe workflow of RIG. (Image source:\nNair et al., 2018\n)\nThe task is to control a robot arm to push a small puck on a table to a desired position. The desired position, or the goal, is present in an image. During training, it learns latent embedding of both state $s$ and goal $g$ through $\\beta$-VAE encoder and the control policy operates entirely in the latent space.\nLet’s say a\n$\\beta$-VAE\nhas an encoder $q_\\phi$ mapping input states to latent variable $z$ which is modeled by a Gaussian distribution and a decoder $p_\\psi$ mapping $z$ back to the states. The state encoder in RIG is set to be the mean of $\\beta$-VAE encoder.\n$$\n\\begin{aligned}\nz &\\sim q_\\phi(z \\vert s) = \\mathcal{N}(z; \\mu_\\phi(s), \\sigma^2_\\phi(s)) \\\\\n\\mathcal{L}_{\\beta\\text{-VAE}} &= - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s)} [\\log p_\\psi (s \\vert z)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s) \\| p_\\psi(s)) \\\\\ne(s) &\\triangleq \\mu_\\phi(s)\n\\end{aligned}\n$$\nThe reward is the Euclidean distance between state and goal embedding vectors: $r(s, g) = -|e(s) - e(g)|$. Similar to\ngrasp2vec\n, RIG applies data augmentation as well by latent goal relabeling: precisely half of the goals are generated from the prior at random and the other half are selected using HER. Also same as grasp2vec, rewards do not depend on any ground truth states but only the learned state encoding, so it can be used for training on real robots.\nThe algorithm of RIG. (Image source:\nNair et al., 2018\n)\nThe problem with RIG is a lack of object variations in the imagined goal pictures. If $\\beta$-VAE is only trained with a black puck, it would not be able to create a goal with other objects like blocks of different shapes and colors. A follow-up improvement replaces $\\beta$-VAE with a\nCC-VAE\n(Context-Conditioned VAE;\nNair, et al., 2019\n), inspired by\nCVAE\n(Conditional VAE;\nSohn, Lee & Yan, 2015\n), for goal generation.\nThe workflow of context-conditioned RIG. (Image source:\nNair, et al., 2019\n).\nA CVAE conditions on a context variable $c$. It trains an encoder $q_\\phi(z \\vert s, c)$ and a decoder $p_\\psi (s \\vert z, c)$ and note that both have access to $c$. The CVAE loss penalizes information passing from the input state $s$ through an information bottleneck but allows for\nunrestricted\ninformation flow from $c$ to both encoder and decoder.\n$$\n\\mathcal{L}_\\text{CVAE} = - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s,c)} [\\log p_\\psi (s \\vert z, c)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s, c) \\| p_\\psi(s))\n$$\nTo create plausible goals, CC-VAE conditions on a starting state $s_0$ so that the generated goal presents a consistent type of object as in $s_0$. This goal consistency is necessary; e.g. if the current scene contains a red puck but the goal has a blue block, it would confuse the policy.\nOther than the state encoder $e(s) \\triangleq \\mu_\\phi(s)$, CC-VAE trains a second convolutional encoder $e_0(.)$ to translate the starting state $s_0$ into a compact context representation $c = e_0(s_0)$. Two encoders, $e(.)$ and $e_0(.)$, are intentionally different without shared weights, as they are expected to encode different factors of image variation. In addition to the loss function of CVAE, CC-VAE adds an extra term to learn to reconstruct $c$ back to $s_0$, $\\hat{s}_0 = d_0(c)$.\n$$\n\\mathcal{L}_\\text{CC-VAE} = \\mathcal{L}_\\text{CVAE} + \\log p(s_0\\vert c)\n$$\nExamples of imagined goals generated by CVAE that conditions on the context image (the first row), while VAE fails to capture the object consistency. (Image source:\nNair, et al., 2019\n).\nBisimulation\n#\nTask-agnostic representation (e.g. a model that intends to represent all the dynamics in the system) may distract the RL algorithms as irrelevant information is also presented. For example, if we just train an auto-encoder to reconstruct the input image, there is no guarantee that the entire learned representation will be useful for RL. Therefore, we need to move away from reconstruction-based representation learning if we only want to learn information relevant to control, as irrelevant details are still important for reconstruction.\nRepresentation learning for control based on bisimulation does not depend on reconstruction, but aims to group states based on their behavioral similarity in MDP.\nBisimulation\n(\nGivan et al. 2003\n) refers to an equivalence relation between two states with similar long-term behavior.\nBisimulation metrics\nquantify such relation so that we can aggregate states to compress a high-dimensional state space into a smaller one for more efficient computation. The\nbisimulation distance\nbetween two states corresponds to how behaviorally different these two states are.\nGiven a\nMDP\n$\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, \\mathcal{P}, \\mathcal{R}, \\gamma \\rangle$ and a bisimulation relation $B$, two states that are equal under relation $B$ (i.e. $s_i B s_j$) should have the same immediate reward for all actions and the same transition probabilities over the next bisimilar states:\n$$\n\\begin{aligned}\n\\mathcal{R}(s_i, a) &= \\mathcal{R}(s_j, a) \\; \\forall a \\in \\mathcal{A} \\\\\n\\mathcal{P}(G \\vert s_i, a) &= \\mathcal{P}(G \\vert s_j, a) \\; \\forall a \\in \\mathcal{A} \\; \\forall G \\in \\mathcal{S}_B\n\\end{aligned}\n$$\nwhere $\\mathcal{S}_B$ is a partition of the state space under the relation $B$.\nNote that $=$ is always a bisimulation relation. The most interesting one is the maximal bisimulation relation $\\sim$, which defines a partition $\\mathcal{S}_\\sim$ with\nfewest\ngroups of states.\nDeepMDP learns a latent space model by minimizing two losses on a reward model and a dynamics model. (Image source:\nGelada, et al. 2019\n)\nWith a goal similar to bisimulation metric,\nDeepMDP\n(\nGelada, et al. 2019\n) simplifies high-dimensional observations in RL tasks and learns a latent space model via minimizing two losses:\nprediction of rewards and\nprediction of the distribution over next latent states.\n$$\n\\begin{aligned}\n\\mathcal{L}_{\\bar{\\mathcal{R}}}(s, a) = \\vert \\mathcal{R}(s, a) - \\bar{\\mathcal{R}}(\\phi(s), a) \\vert \\\\\n\\mathcal{L}_{\\bar{\\mathcal{P}}}(s, a) = D(\\phi \\mathcal{P}(s, a), \\bar{\\mathcal{P}}(. \\vert \\phi(s), a))\n\\end{aligned}\n$$\nwhere $\\phi(s)$ is the embedding of state $s$; symbols with bar are functions (reward function $R$ and transition function $P$) in the same MDP but running in the latent low-dimensional observation space. Here the embedding representation $\\phi$ can be connected to bisimulation metrics, as the bisimulation distance is proved to be upper-bounded by the L2 distance in the latent space.\nThe function $D$ quantifies the distance between two probability distributions and should be chosen carefully. DeepMDP focuses on\nWasserstein-1\nmetric (also known as\n“earth-mover distance”\n). The Wasserstein-1 distance between distributions $P$ and $Q$ on a metric space $(M, d)$ (i.e., $d: M \\times M \\to \\mathbb{R}$) is:\n$$\nW_d (P, Q) = \\inf_{\\lambda \\in \\Pi(P, Q)} \\int_{M \\times M} d(x, y) \\lambda(x, y) \\; \\mathrm{d}x \\mathrm{d}y\n$$\nwhere $\\Pi(P, Q)$ is the set of all\ncouplings\nof $P$ and $Q$. $d(x, y)$ defines the cost of moving a particle from point $x$ to point $y$.\nThe Wasserstein metric has a dual form according to the Monge-Kantorovich duality:\n$$\nW_d (P, Q) = \\sup_{f \\in \\mathcal{F}_d} \\vert \\mathbb{E}_{x \\sim P} f(x) - \\mathbb{E}_{y \\sim Q} f(y) \\vert\n$$\nwhere $\\mathcal{F}_d$ is the set of 1-Lipschitz functions under the metric $d$ - $\\mathcal{F}_d = \\{ f: \\vert f(x) - f(y) \\vert \\leq d(x, y) \\}$.\nDeepMDP generalizes the model to the Norm Maximum Mean Discrepancy (Norm-\nMMD\n) metrics to improve the tightness of the bounds of its deep value function and, at the same time, to save computation (Wasserstein is expensive computationally). In their experiments, they found the model architecture of the transition prediction model can have a big impact on the performance. Adding these DeepMDP losses as auxiliary losses when training model-free RL agents leads to good improvement on most of the Atari games.\nDeep Bisimulatioin for Control\n(short for\nDBC\n;\nZhang et al. 2020\n) learns the latent representation of observations that are good for control in RL tasks, without domain knowledge or pixel-level reconstruction.\nThe Deep Bisimulation for Control algorithm learns a bisimulation metric representation via learning a reward model and a dynamics model. The model architecture is a siamese network. (Image source:\nZhang et al. 2020\n)\nSimilar to DeepMDP, DBC models the dynamics by learning a reward model and a transition model. Both models operate in the latent space, $\\phi(s)$. The optimization of embedding $\\phi$ depends on one important conclusion from\nFerns, et al. 2004\n(Theorem 4.5) and\nFerns, et al 2011\n(Theorem 2.6):\nGiven $c \\in (0, 1)$ a discounting factor, $\\pi$ a policy that is being improved continuously, and $M$ the space of bounded\npseudometric\non the state space $\\mathcal{S}$, we can define $\\mathcal{F}: M \\mapsto M$:\n$$\n\\mathcal{F}(d; \\pi)(s_i, s_j) = (1-c) \\vert \\mathcal{R}_{s_i}^\\pi - \\mathcal{R}_{s_j}^\\pi \\vert + c W_d (\\mathcal{P}_{s_i}^\\pi, \\mathcal{P}_{s_j}^\\pi)\n$$\nThen, $\\mathcal{F}$ has a unique fixed point $\\tilde{d}$ which is a $\\pi^*$-bisimulation metric and $\\tilde{d}(s_i, s_j) = 0 \\iff s_i \\sim s_j$.\n[The proof is not trivial. I may or may not add it in the future  _(:3」∠)_ …]\nGiven batches of observations pairs, the training loss for $\\phi$, $J(\\phi)$, minimizes the mean square error between the on-policy bisimulation metric and Euclidean distance in the latent space:\n$$\nJ(\\phi) = \\Big( \\|\\phi(s_i) - \\phi(s_j)\\|_1 - \\vert \\hat{\\mathcal{R}}(\\bar{\\phi}(s_i)) - \\hat{\\mathcal{R}}(\\bar{\\phi}(s_j)) \\vert - \\gamma W_2(\\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_i), \\bar{\\pi}(\\bar{\\phi}(s_i))), \\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_j), \\bar{\\pi}(\\bar{\\phi}(s_j)))) \\Big)^2\n$$\nwhere $\\bar{\\phi}(s)$ denotes $\\phi(s)$ with stop gradient and $\\bar{\\pi}$ is the mean policy output. The learned reward model $\\hat{\\mathcal{R}}$ is deterministic and the learned forward dynamics model $\\hat{\\mathcal{P}}$ outputs a Gaussian distribution.\nDBC is based on SAC but operates on the latent space:\nThe algorithm of Deep Bisimulation for Control. (Image source:\nZhang et al. 2020\n)\nCited as:\n@article{weng2019selfsup,\n  title   = \"Self-Supervised Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-11-10-self-supervised/\"\n}\nReferences\n#\n[1] Alexey Dosovitskiy, et al.\n“Discriminative unsupervised feature learning with exemplar convolutional neural networks.”\nIEEE transactions on pattern analysis and machine intelligence 38.9 (2015): 1734-1747.\n[2] Spyros Gidaris, Praveer Singh & Nikos Komodakis.\n“Unsupervised Representation Learning by Predicting Image Rotations”\nICLR 2018.\n[3] Carl Doersch, Abhinav Gupta, and Alexei A. Efros.\n“Unsupervised visual representation learning by context prediction.”\nICCV. 2015.\n[4] Mehdi Noroozi & Paolo Favaro.\n“Unsupervised learning of visual representations by solving jigsaw puzzles.”\nECCV, 2016.\n[5] Mehdi Noroozi, Hamed Pirsiavash, and Paolo Favaro.\n“Representation learning by learning to count.”\nICCV. 2017.\n[6] Richard Zhang, Phillip Isola & Alexei A. Efros.\n“Colorful image colorization.”\nECCV, 2016.\n[7] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[8] Jeff Donahue, Philipp Krähenbühl, and Trevor Darrell.\n“Adversarial feature learning.”\nICLR 2017.\n[9] Deepak Pathak, et al.\n“Context encoders: Feature learning by inpainting.”\nCVPR. 2016.\n[10] Richard Zhang, Phillip Isola, and Alexei A. Efros.\n“Split-brain autoencoders: Unsupervised learning by cross-channel prediction.”\nCVPR. 2017.\n[11] Xiaolong Wang & Abhinav Gupta.\n“Unsupervised Learning of Visual Representations using Videos.”\nICCV. 2015.\n[12] Carl Vondrick, et al.\n“Tracking Emerges by Colorizing Videos”\nECCV. 2018.\n[13] Ishan Misra, C. Lawrence Zitnick, and Martial Hebert.\n“Shuffle and learn: unsupervised learning using temporal order verification.”\nECCV. 2016.\n[14] Basura Fernando, et al.\n“Self-Supervised Video Representation Learning With Odd-One-Out Networks”\nCVPR. 2017.\n[15] Donglai Wei, et al.\n“Learning and Using the Arrow of Time”\nCVPR. 2018.\n[16] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering”\nCVPR. 2015.\n[17] Pierre Sermanet, et al.\n“Time-Contrastive Networks: Self-Supervised Learning from Video”\nCVPR. 2018.\n[18] Debidatta Dwibedi, et al.\n“Learning actionable representations from visual observations.”\nIROS. 2018.\n[19] Eric Jang & Coline Devin, et al.\n“Grasp2Vec: Learning Object Representations from Self-Supervised Grasping”\nCoRL. 2018.\n[20] Ashvin Nair, et al.\n“Visual reinforcement learning with imagined goals”\nNeuriPS. 2018.\n[21] Ashvin Nair, et al.\n“Contextual imagined goals for self-supervised robotic learning”\nCoRL. 2019.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748, 2018.\n[23] Olivier J. Henaff, et al.\n“Data-Efficient Image Recognition with Contrastive Predictive Coding”\narXiv preprint arXiv:1905.09272, 2019.\n[24] Kaiming He, et al.\n“Momentum Contrast for Unsupervised Visual Representation Learning.”\nCVPR 2020.\n[25] Zhirong Wu, et al.\n“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”\nCVPR 2018.\n[26] Ting Chen, et al.\n“A Simple Framework for Contrastive Learning of Visual Representations.”\narXiv preprint arXiv:2002.05709, 2020.\n[27] Aravind Srinivas, Michael Laskin & Pieter Abbeel\n“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”\narXiv preprint arXiv:2004.04136, 2020.\n[28] Carles Gelada, et al.\n“DeepMDP: Learning Continuous Latent Space Models for Representation Learning”\nICML 2019.\n[29] Amy Zhang, et al.\n“Learning Invariant Representations for Reinforcement Learning without Reconstruction”\narXiv preprint arXiv:2006.10742, 2020.\n[30] Xinlei Chen, et al.\n“Improved Baselines with Momentum Contrastive Learning”\narXiv preprint arXiv:2003.04297, 2020.\n[31] Jean-Bastien Grill, et al.\n“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”\narXiv preprint arXiv:2006.07733, 2020.\n[32] Abe Fetterman & Josh Albrecht.\n“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”\nUntitled blog. Aug 24, 2020.",
            "metadata": {
              "title": "Self-Supervised Representation Learning | Lil'Log",
              "description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "keywords": "representation-learning, long-read, generative-model, object-recognition, reinforcement-learning, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Self-Supervised Representation Learning",
              "og:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
              "og:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:card": "summary_large_image",
              "twitter:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:title": "Self-Supervised Representation Learning",
              "twitter:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "article:section": "posts",
              "article:published_time": "2019-11-10T00:00:00+00:00",
              "article:modified_time": "2019-11-10T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bf0a610ccb4a/code/body-000.txt",
                "chars": 244,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "bytes": 513885,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f359d38ab20e9cdac179.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "bytes": 1270278,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-8d6f8ad7272758de8c53.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "bytes": 768852,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7c81aafa4666fddd3762.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "bytes": 2642257,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c64df87fedc22e7713a8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "bytes": 249192,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-d72676a1e2d7d681665b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "bytes": 737673,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-284f09a3dc26a2be2be6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "bytes": 1162740,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-574c20fa1107bf61368d.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "bytes": 566411,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-817ed503b242a7831692.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "bytes": 103291,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-26dfcda8fac62755a0e6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "bytes": 225014,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-a7ef42a592f8d64c0933.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "bytes": 267029,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-38455ea040ea0eae9625.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "bytes": 163908,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-2f0fc009f289b69c8d79.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "bytes": 1281590,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e3a5248959b284127268.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "bytes": 1411892,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-316474d8ca427819890a.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "bytes": 218384,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7dd458cefc09c96c4325.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "bytes": 135102,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-70000ddd170ac7e5840b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "bytes": 2011971,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ae4b346db197ccab2cfe.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "bytes": 157839,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-1da73a82998c80ae17c9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "bytes": 1115258,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-976ef652676b26b5a203.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "bytes": 1886891,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f8bf05d0018c01caf352.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "bytes": 2352713,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-dee16f2c447f7c91e79e.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "bytes": 917157,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7de401f88063093a58d8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "bytes": 391776,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ce13a8280e64dce3dbf1.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "bytes": 1753636,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c37fd073afd7cb9698fa.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "bytes": 1839222,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e113f6beb0962c59d170.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "bytes": 164404,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c9ea48204e2765c959ab.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "bytes": 388169,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-139471e0d9b6eef5fde9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "bytes": 350225,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-211c4ab593d56ae944a3.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "src": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "status": "no_1080_or_720",
                "kind": "single_video",
                "error": "ERROR: [youtube] 7I0Qt7GALVk: Requested format is not available. Use --list-formats for a list of available formats\n",
                "title": "",
                "retried_at": "2026-10-20T17:59:07Z"
              }
            ],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "MoCo V2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "label": "LeCun’s talk",
                "type": "a"
              },
              {
                "href": "https://github.com/jason718/awesome-self-supervised-learning",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/tags/generative-model/",
                "label": "generative modeling",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.03670",
                "label": "Zhai et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11825",
                "label": "Sun et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1406.6909",
                "label": "Dosovitskiy et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.07728",
                "label": "Gidaris et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05192",
                "label": "Doersch et al. (2015)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Chromatic_aberration",
                "label": "“chromatic aberration”",
                "type": "a"
              },
              {
                "href": "https://upload.wikimedia.org/wikipedia/commons/a/aa/Chromatic_aberration_lens_diagram.svg",
                "label": "wikipedia",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09246",
                "label": "Noroozi & Favaro (2016)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00025",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.06734",
                "label": "Noroozi, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08511",
                "label": "Zhang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CIELAB_color_space",
                "label": "CIE L a b* color space",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "tf and idf",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "Vincent, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "old post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.07379",
                "label": "Pathak, et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.09842",
                "label": "Zhang et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "Radford et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.09782",
                "label": "Donahue, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Noise Contrastive Estimation (NCE)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.09272",
                "label": "Henaff, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.00687",
                "label": "Wang & Gupta, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "triplet loss",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6200-improved-deep-metric-learning-with-multi-class-n-pair-loss-objective",
                "label": "n-pair loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Optical_flow",
                "label": "optical flow",
                "type": "a"
              },
              {
                "href": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "label": "SURF",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/hal-00873267v2/document",
                "label": "IDT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08561",
                "label": "Misra, et al 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.06646",
                "label": "Fernando et al. 2017",
                "type": "a"
              },
              {
                "href": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "label": "Wei et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09594",
                "label": "Vondrick et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "matching network",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "pointer network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06964",
                "label": "Jang & Devin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://developers.google.com/machine-learning/crash-course/embeddings/translating-to-a-lower-dimensional-space",
                "label": "e.g.",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "label": "Andrychowicz, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.06888",
                "label": "Sermanet, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00928",
                "label": "Dwibedi et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.04742",
                "label": "Nair et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.11670",
                "label": "Nair, et al., 2019",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5775-learning-structured-output-representation-using-deep-conditional-generative-models",
                "label": "Sohn, Lee & Yan, 2015",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.61.2493&rep=rep1&type=pdf",
                "label": "Givan et al. 2003",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "MDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.02736",
                "label": "Gelada, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coupling_(probability)",
                "label": "couplings",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_embedding_of_distributions",
                "label": "MMD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10742",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1207.4114",
                "label": "Ferns, et al. 2004",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.295.2114&rep=rep1&type=pdf",
                "label": "Ferns, et al 2011",
                "type": "a"
              },
              {
                "href": "https://mathworld.wolfram.com/Pseudometric.html",
                "label": "pseudometric",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1806.09594.pdf",
                "label": "“Tracking Emerges by Colorizing Videos”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "“Momentum Contrast for Unsupervised Visual Representation Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "“A Simple Framework for Contrastive Learning of Visual Representations.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "“Improved Baselines with Momentum Contrastive Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:35Z",
            "source_url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.03670",
                "bytes": 933247,
                "reused": false,
                "local_path": "papers/repair/687ecfe304e8db4ee6a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11825",
                "bytes": 1510344,
                "reused": false,
                "local_path": "papers/repair/abe216f7fcd57c5bf090.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.6909",
                "bytes": 1208023,
                "reused": false,
                "local_path": "papers/repair/02461cd2b74a44803bcb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.07728",
                "bytes": 2524968,
                "reused": false,
                "local_path": "papers/repair/09768e0dd5ddaf3f5115.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05192",
                "bytes": 3688221,
                "reused": false,
                "local_path": "papers/repair/8660d67d6d9beb2f409e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09246",
                "bytes": 7884325,
                "reused": false,
                "local_path": "papers/repair/3fad0ba70064de418e86.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00025",
                "bytes": 915177,
                "reused": false,
                "local_path": "papers/repair/e965789a54661a85f29b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.06734",
                "bytes": 4282240,
                "reused": false,
                "local_path": "papers/repair/9041a39543be512b895f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08511",
                "bytes": 8866382,
                "reused": false,
                "local_path": "papers/repair/adde21ae45e292b51011.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": false,
                "local_path": "papers/repair/afb5d72ab0895a64362a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.07379",
                "bytes": 9914955,
                "reused": false,
                "local_path": "papers/repair/24d4451e560641d4763c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.09842",
                "bytes": 2531668,
                "reused": false,
                "local_path": "papers/repair/20050e06cbfd43bbb68b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": true,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.09782",
                "bytes": 5938452,
                "reused": false,
                "local_path": "papers/repair/407a2bae3cb6f778a5c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": true,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.09272",
                "bytes": 2411659,
                "reused": false,
                "local_path": "papers/repair/b9006248b176b4b194f1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.00687",
                "bytes": 3737012,
                "reused": false,
                "local_path": "papers/repair/3078161f1da978e0de72.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": true,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "bytes": 723370,
                "reused": false,
                "local_path": "papers/repair/780b0a793aeb990a3f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08561",
                "bytes": 2615687,
                "reused": false,
                "local_path": "papers/repair/1d251b8fc37ee017f4bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.06646",
                "bytes": 7497944,
                "reused": false,
                "local_path": "papers/repair/739b5e4d4e24134d409b.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "bytes": 1011708,
                "reused": false,
                "local_path": "papers/repair/afdd1eb32a82a2145ccc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/643dffc114da13aa653b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06964",
                "bytes": 6707774,
                "reused": false,
                "local_path": "papers/repair/fa128df9eb0f1f235ebb.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "bytes": 2040774,
                "reused": false,
                "local_path": "papers/repair/d153f5fcbc7ada7f48f2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.06888",
                "bytes": 9504974,
                "reused": false,
                "local_path": "papers/repair/2b339f780c6bfb664948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00928",
                "bytes": 1382430,
                "reused": false,
                "local_path": "papers/repair/a8b22a546f22c92d1a5c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.04742",
                "bytes": 9328088,
                "reused": false,
                "local_path": "papers/repair/509c62da689529aeb058.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.11670",
                "bytes": 2075834,
                "reused": false,
                "local_path": "papers/repair/909f08f6590adde49f8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.02736",
                "bytes": 8541253,
                "reused": false,
                "local_path": "papers/repair/04f92d456ed7ee16b0e3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10742",
                "bytes": 5605228,
                "reused": false,
                "local_path": "papers/repair/1f176920cb7853662844.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1207.4114",
                "bytes": 386038,
                "reused": false,
                "local_path": "papers/repair/b3516a025350622055b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594.pdf",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/591acb652d41fe6382d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": true,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": true,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": true,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": true,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": true,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": true,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53089,
            "expected_body_images": 28,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "no_1080_or_720",
            "raw_html": "attachments/bf0a610ccb4a/pages/source.html",
            "local_html": "attachments/bf0a610ccb4a/pages/article.html",
            "body_base_path": "attachments/bf0a610ccb4a/pages/",
            "body_markdown_path": "attachments/bf0a610ccb4a/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
          "status": "partial",
          "article_id": "7b9f4f54765d",
          "local_path": "series-follow/1602/repair/b48fce1efd05187269e6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
              "bytes": 5376803,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1602/repair/assets/6b91dcea21697574b105.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
              "bytes": 291157,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1f9233b348db9b37e2ee.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
              "bytes": 467414,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/acc2d9731b17ed2baf72.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
              "bytes": 149758,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c138b9ae776276fc8846.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
              "bytes": 1129963,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/02a63a130390d75c9b29.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
              "bytes": 245312,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7c7b014d7ed4fa8401a1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
              "bytes": 208294,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1e519d78d676ad46c539.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
              "bytes": 76657,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/70e7c7e4493d4048b5d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
              "bytes": 331868,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/30ce759c796a4b00b5e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
              "bytes": 499500,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6f821f70a67bba2e4ef7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
              "bytes": 340971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2ea98dac18eabd367373.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
              "bytes": 204770,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/84f271779024a8ad2f72.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
              "bytes": 507936,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c6959ef2ce02358a0d4d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
              "bytes": 451854,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b23af17d8eb4125329b2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
              "bytes": 144456,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cd84e9d2b02b76f1bf08.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
              "bytes": 256303,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5e9526e04be190a25b0e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
              "bytes": 284015,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bb1d03b945066ecdbb48.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
              "bytes": 199433,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/939aa5d0a48211c07558.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Exploration Strategies in Deep Reinforcement Learning",
            "keywords": "探索策略,DRL,bandit",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
            "publish_date": "2020-06",
            "corpus_stage": "强化学习/对齐",
            "notes": "深度强化学习探索策略综述",
            "id": "7b9f4f54765d",
            "collected_at": "2026-10-02T14:13:22",
            "title": "Exploration Strategies in Deep Reinforcement Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-06-17: Add\n“exploration via disagreement”\nin the “Forward Dynamics”\nsection\n.\nExploitation versus exploration\nis a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern\nRL\nalgorithms\nthat optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.\nI would like to discuss several common exploration strategies in Deep RL here. As this is a very big topic, my post by no means can cover all the important subtopics. I plan to update it periodically and keep further enriching the content gradually in time.\nClassic Exploration Strategies\n#\nAs a quick recap, let’s first go through several classic exploration algorithms that work out pretty well in the multi-armed bandit problem or simple tabular RL.\nEpsilon-greedy\n: The agent does random exploration occasionally with probability $\\epsilon$ and takes the optimal action most of the time with probability $1-\\epsilon$.\nUpper confidence bounds\n: The agent selects the greediest action to maximize the upper confidence bound $\\hat{Q}_t(a) + \\hat{U}_t(a)$, where $\\hat{Q}_t(a)$ is the average rewards associated with action $a$ up to time $t$ and $\\hat{U}_t(a)$ is a function reversely proportional to how many times action $a$ has been taken. See\nhere\nfor more details.\nBoltzmann exploration\n: The agent draws actions from a\nboltzmann distribution\n(softmax) over the learned Q values, regulated by a temperature parameter $\\tau$.\nThompson sampling\n: The agent keeps track of a belief over the probability of optimal actions and samples from this distribution. See\nhere\nfor more details.\nThe following strategies could be used for better exploration in deep RL training when neural networks are used for function approximation:\nEntropy loss term\n: Add an entropy term $H(\\pi(a \\vert s))$ into the loss function, encouraging the policy to take diverse actions.\nNoise-based Exploration\n: Add noise into the observation, action or even parameter space (\nFortunato, et al. 2017\n,\nPlappert, et al. 2017\n).\nKey Exploration Problems\n#\nGood exploration becomes especially hard when the environment rarely provides rewards as feedback or the environment has distracting noise. Many exploration strategies are proposed to solve one or both of the following problems.\nThe Hard-Exploration Problem\n#\nThe “hard-exploration” problem refers to exploration in an environment with very sparse or even deceptive reward. It is difficult because random exploration in such scenarios can rarely discover successful states or obtain meaningful feedback.\nMontezuma’s Revenge\nis a concrete example for the hard-exploration problem. It remains as a few challenging games in Atari for DRL to solve. Many papers use Montezuma’s Revenge to benchmark their results.\nThe Noisy-TV Problem\n#\nThe “Noisy-TV” problem started as a thought experiment in\nBurda, et al (2018)\n. Imagine that an RL agent is rewarded with seeking novel experience, a TV with uncontrollable & unpredictable random noise outputs would be able to attract the agent’s attention forever. The agent obtains new rewards from noisy TV consistently, but it fails to make any meaningful progress and becomes a “couch potato”.\nAn agent is rewarded with novel experience in the experiment. If a maze has a noisy TC set up, the agent would be attracted and stop moving in the maze. (Image source: OpenAI Blog:\n\"Reinforcement Learning with Prediction-Based Rewards\"\n)\nIntrinsic Rewards as Exploration Bonuses\n#\nOne common approach to better exploration, especially for solving the\nhard-exploration\nproblem, is to augment the environment reward with an additional bonus signal to encourage extra exploration. The policy is thus trained with a reward composed of two terms, $r_t = r^e_t + \\beta r^i_t$, where $\\beta$ is a hyperparameter adjusting the balance between exploitation and exploration.\n$r^e_t$ is an\nextrinsic\nreward from the environment at time $t$, defined according to the task in hand.\n$r^i_t$ is an\nintrinsic\nexploration bonus at time $t$.\nThis intrinsic reward is somewhat inspired by\nintrinsic motivation\nin psychology (\nOudeyer & Kaplan, 2008\n). Exploration driven by curiosity might be an important way for children to grow and learn. In other words, exploratory activities should be rewarding intrinsically in the human mind to encourage such behavior. The intrinsic rewards could be correlated with curiosity, surprise, familiarity of the state, and many other factors.\nSame ideas can be applied to RL algorithms. In the following sections, methods of bonus-based exploration rewards are roughly grouped into two categories:\nDiscovery of novel states\nImprovement of the agent’s knowledge about the environment.\nCount-based Exploration\n#\nIf we consider intrinsic rewards as rewarding conditions that surprise us, we need a way to measure whether a state is novel or appears often. One intuitive way is to count how many times a state has been encountered and to assign a bonus accordingly. The bonus guides the agent’s behavior to prefer rarely visited states to common states. This is known as the\ncount-based exploration\nmethod.\nLet $N_n(s)$ be the\nempirical count\nfunction that tracks the real number of visits of a state $s$ in the sequence of $s_{1:n}$. Unfortunately, using $N_n(s)$ for exploration directly is not practical, because most of the states would have $N_n(s)=0$, especially considering that the state space is often continuous or high-dimensional. We need an non-zero count for most states, even when they haven’t been seen before.\nCounting by Density Model\n#\nBellemare, et al. (2016)\nused a\ndensity model\nto approximate the frequency of state visits and a novel algorithm for deriving a\npseudo-count\nfrom this density model. Let’s first define a conditional probability over the state space, $\\rho_n(s) = \\rho(s \\vert s_{1:n})$ as the probability of the $(n+1)$-th state being $s$ given the first $n$ states are $s_{1:n}$. To measure this empirically, we can simply use $N_n(s)/n$.\nLet’s also define a\nrecoding probability\nof a state $s$ as the probability assigned by the density model to $s$\nafter observing a new occurrence of\n$s$, $\\rho’_n(s) = \\rho(s \\vert s_{1:n}s)$.\nThe paper introduced two concepts to better regulate the density model, a\npseudo-count\nfunction $\\hat{N}_n(s)$ and a\npseudo-count total\n$\\hat{n}$. As they are designed to imitate an empirical count function, we would have:\n$$\n\\rho_n(s) = \\frac{\\hat{N}_n(s)}{\\hat{n}} \\leq \\rho'_n(s) = \\frac{\\hat{N}_n(s) + 1}{\\hat{n} + 1}\n$$\nThe relationship between $\\rho_n(x)$ and $\\rho’_n(x)$ requires the density model to be\nlearning-positive\n:  for all $s_{1:n} \\in \\mathcal{S}^n$ and all $s \\in \\mathcal{S}$, $\\rho_n(s) \\leq \\rho’_n(s)$. In other words, After observing one instance of $s$, the density model’s prediction of that same $s$ should increase. Apart from being learning-positive, the density model should be trained completely\nonline\nwith non-randomized mini-batches of experienced states, so naturally we have $\\rho’_n = \\rho_{n+1}$.\nThe pseudo-count can be computed from $\\rho_n(s)$ and $\\rho’_n(s)$ after solving the above linear system:\n$$\n\\hat{N}_n(s) = \\hat{n} \\rho_n(s) = \\frac{\\rho_n(s)(1 - \\rho'_n(s))}{\\rho'_n(s) - \\rho_n(s)} \n$$\nOr estimated by the\nprediction gain (PG)\n:\n$$\n\\hat{N}_n(s) \\approx (e^{\\text{PG}_n(s)} - 1)^{-1} = (e^{\\log \\rho'_n(s) - \\log \\rho(s)} - 1)^{-1}\n$$\nA common choice of a count-based intrinsic bonus is $r^i_t = N(s_t, a_t)^{-1/2}$ (as in MBIE-EB;\nStrehl & Littman, 2008\n). The pseudo-count-based exploration bonus is shaped in a similar form, $r^i_t = \\big(\\hat{N}_n(s_t, a_t) + 0.01 \\big)^{-1/2}$.\nExperiments in\nBellemare et al., (2016)\nadopted a simple\nCTS\n(Context Tree Switching) density model to estimate pseudo-counts. The CTS model takes as input a 2D image and assigns to it a probability according to the product of location-dependent L-shaped filters, where the prediction of each filter is given by a CTS algorithm trained on past images. The CTS model is simple but limited in expressiveness, scalability, and data efficiency. In a following-up paper,\nGeorg Ostrovski, et al. (2017)\nimproved the approach by training a PixelCNN (\nvan den Oord et al., 2016\n) as the density model.\nThe density model can also be a Gaussian Mixture Model as in\nZhao & Tresp (2018)\n. They used a variational GMM to estimate the density of trajectories (e.g. concatenation of a sequence of states) and its predicted probabilities to guide prioritization in experience replay in off-policy setting.\nCounting after Hashing\n#\nAnother idea to make it possible to count high-dimensional states is to map states into\nhash codes\nso that the occurrences of states become trackable (\nTang et al. 2017\n). The state space is discretized with a hash function $\\phi: \\mathcal{S} \\mapsto \\mathbb{Z}^k$. An exploration bonus $r^{i}: \\mathcal{S} \\mapsto \\mathbb{R}$ is added to the reward function, defined as $r^{i}(s) = {N(\\phi(s))}^{-1/2}$, where $N(\\phi(s))$ is an empirical count of occurrences of $\\phi(s)$.\nTang et al. (2017)\nproposed to use\nLocality-Sensitive Hashing\n(\nLSH\n) to convert continuous, high-dimensional data to discrete hash codes. LSH is a popular class of hash functions for querying nearest neighbors based on certain similarity metrics. A hashing scheme $x \\mapsto h(x)$ is locality-sensitive if it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. (See how LSH is used in\nTransformer improvement\nif interested.)\nSimHash\nis a type of computationally efficient LSH and it measures similarity by angular distance:\n$$\n\\phi(s) = \\text{sgn}(A g(s)) \\in \\{-1, 1\\}^k\n$$\nwhere $A \\in \\mathbb{R}^{k \\times D}$ is a matrix with each entry drawn i.i.d. from a standard Gaussian and $g: \\mathcal{S} \\mapsto \\mathbb{R}^D$ is an optional preprocessing function. The dimension of binary codes is $k$, controlling the granularity of the state space discretization. A higher $k$ leads to higher granularity and fewer collisions.\nAlgorithm of count-based exploration through hashing high-dimensional states by SimHash. (Image source:\nTang et al. 2017\n)\nFor high-dimensional images, SimHash may not work well on the raw pixel level.\nTang et al. (2017)\ndesigned an autoencoder (AE) which takes as input states $s$ to learn hash codes. It has one special dense layer composed of $k$ sigmoid functions as the latent state in the middle and then the sigmoid activation values $b(s)$ of this layer are binarized by rounding to their closest binary numbers $\\lfloor b(s)\\rceil \\in \\{0, 1\\}^D$ as the binary hash codes for state $s$. The AE loss over $n$ states includes two terms:\n$$\n\\mathcal{L}(\\{s_n\\}_{n=1}^N) = \\underbrace{-\\frac{1}{N} \\sum_{n=1}^N \\log p(s_n)}_\\text{reconstruction loss} + \\underbrace{\\frac{1}{N} \\frac{\\lambda}{K} \\sum_{n=1}^N\\sum_{i=1}^k \\min \\big \\{ (1-b_i(s_n))^2, b_i(s_n)^2 \\big\\}}_\\text{sigmoid activation being closer to binary}\n$$\nOne problem with this approach is that dissimilar inputs $s_i, s_j$ may be mapped to identical hash codes but the AE still reconstructs them perfectly. One can imagine replacing the bottleneck layer $b(s)$ with the hash codes $\\lfloor b(s)\\rceil$, but then gradients cannot be back-propagated through the rounding function. Injecting uniform noise could mitigate this effect, as the AE has to learn to push the latent variable far apart to counteract the noise.\nPrediction-based Exploration\n#\nThe second category of intrinsic exploration bonuses are rewarded for improvement of the agent’s knowledge about the environment. The agent’s familiarity with the environment dynamics can be estimated through a prediction model. This idea of using a prediction model to measure\ncuriosity\nwas actually proposed quite a long time ago (\nSchmidhuber, 1991\n).\nForward Dynamics\n#\nLearning a\nforward dynamics prediction model\nis a great way to approximate how much knowledge our model has obtained about the environment and the task MDPs. It captures an agent’s capability of predicting the consequence of its own behavior, $f: (s_t, a_t) \\mapsto s_{t+1}$. Such a model cannot be perfect (e.g. due to partial observation), the error $e(s_t, a_t) = | f(s_t, a_t) - s_{t+1} |^2_2$ can be used for providing intrinsic exploration rewards. The higher the prediction error, the less familiar we are with that state.  The faster the error rate drops, the more learning progress signals we acquire.\nIntelligent Adaptive Curiosity\n(\nIAC\n;\nOudeyer, et al. 2007\n) sketched an idea of using a forward dynamics prediction model to estimate learning progress and assigned intrinsic exploration reward accordingly.\nIAC relies on a memory which stores all the experiences encountered by the robot, $M=\\{(s_t, a_t, s_{t+1})\\}$ and a forward dynamics model $f$. IAC incrementally splits the state space (i.e. sensorimotor space in the context of robotics, as discussed in the paper) into separate regions based on the transition samples, using a process similar to how a decision tree is split: The split happens when the number of samples is larger than a threshold, and the variance of states in each leaf should be minimal. Each tree node is characterized by its exclusive set of samples and has its own forward dynamics predictor $f$, named “expert”.\nThe prediction error $e_t$ of an expert is pushed into a list associated with each region. The\nlearning progress\nis then measured as the difference between the mean error rate of a moving window with offset $\\tau$ and the current moving window. The intrinsic reward is defined for tracking the learning progress: $r^i_t = \\frac{1}{k}\\sum_{i=0}^{k-1}(e_{t-i-\\tau} - e_{t-i})$, where $k$ is the moving window size. So the larger prediction error rate decrease we can achieve, the higher intrinsic reward we would assign to the agent. In other words, the agent is encouraged to take actions to quickly learn about the environment.\nArchitecture of the IAC (Intelligent Adaptive Curiosity) module: the intrinsic reward is assigned w.r.t the learning progress in reducing prediction error of the dynamics model. (Image source:\nOudeyer, et al. 2007\n)\nStadie et al. (2015)\ntrained a forward dynamics model in the encoding space defined by $\\phi$, $f_\\phi: (\\phi(s_t), a_t) \\mapsto \\phi(s_{t+1})$. The model’s prediction error at time $T$ is normalized by the maximum error up to time $t$, $\\bar{e}_t = \\frac{e_t}{\\max_{i \\leq t} e_i}$, so it is always between 0 and 1. The intrinsic reward is defined accordingly: $r^i_t = (\\frac{\\bar{e}_t(s_t, a_t)}{t \\cdot C})$, where $C > 0$ is a decay constant.\nEncoding the state space via $\\phi(.)$ is necessary, as experiments in the paper have shown that a dynamics model trained directly on raw pixels has\nvery poor\nbehavior — assigning same exploration bonuses to all the states. In\nStadie et al. (2015)\n, the encoding function $\\phi$ is learned via an autocoder (AE) and $\\phi(.)$ is one of the output layers in AE. The AE can be statically trained using a set of images collected by a random agent, or dynamically trained together with the policy where the early frames are gathered using\n$\\epsilon$-greedy\nexploration.\nInstead of autoencoder,\nIntrinsic Curiosity Module\n(\nICM\n;\nPathak, et al., 2017\n) learns the state space encoding $\\phi(.)$ with a self-supervised\ninverse dynamics\nmodel. Predicting the next state given the agent’s own action is not easy, especially considering that some factors in the environment cannot be controlled by the agent or do not affect the agent. ICM believes that a good state feature space should exclude such factors because\nthey cannot influence the agent’s behavior and thus the agent has no incentive for learning them\n. By learning an inverse dynamics model $g: (\\phi(s_t), \\phi(s_{t+1})) \\mapsto a_t$, the feature space only captures those changes in the environment related to the actions of our agent, and ignores the rest.\nGiven a forward model $f$, an inverse dynamics model $g$ and an observation $(s_t, a_t, s_{t+1})$:\n$$\ng_{\\psi_I}(\\phi(s_t), \\phi(s_{t+1})) = \\hat{a}_t \\quad\nf_{\\psi_F}(\\phi(s_t), a_t) = \\hat{\\phi}(s_{t+1}) \\quad\nr_t^i = \\| \\hat{\\phi}(s_{t+1}) - \\phi(s_{t+1}) \\|_2^2\n$$\nSuch $\\phi(.)$ is expected to be robust to uncontrollable aspects of the environment.\nICM (Intrinsic Curiosity Module) assigns the forward dynamics prediction error to the agent as the intrinsic reward. This dynamics model operates in a state encoding space learned through an inverse dynamics model to exclude environmental factors that do not affect the agent's behavior. (Image source:\nPathak, et al. 2017\n)\nBurda, Edwards & Pathak, et al. (2018)\ndid a set of large-scale comparison experiments on purely curiosity-driven learning, meaning that only intrinsic rewards are provided to the agent. In this study, the reward is $r_t = r^i_t = | f(s_t, a_t) - \\phi(s_{t+1})|_2^2$. A good choice of $\\phi$ is crucial to learning forward dynamics, which is expected to be\ncompact\n,\nsufficient\nand\nstable\n, making the prediction task more tractable and filtering out irrelevant observation.\nIn comparison of 4 encoding functions:\nRaw image pixels: No encoding, $\\phi(x) = x$.\nRandom features (RF): Each state is compressed through a fixed random neural network.\nVAE\n: The probabilistic encoder is used for encoding, $\\phi(x) = q(z \\vert x)$.\nInverse dynamic features (IDF): The same feature space as used in\nICM\n.\nAll the experiments have the reward signals normalized by a running estimation of standard deviation of the cumulative returns. And all the experiments are running in an infinite horizon setting to avoid “done” flag leaking information.\nThe mean reward in different games when training with only curiosity signals, generated by different state encoding functions. (Image source:\nBurda, Edwards & Pathak, et al. 2018\n)\nInterestingly\nrandom features\nturn out to be quite competitive, but in feature transfer experiments (i.e. train an agent in Super Mario Bros level 1-1 and then test it in another level), learned IDF features can generalize better.\nThey also compared RF and IDF in an environment with a\nnoisy TV\non. Unsurprisingly the noisy TV drastically slows down the learning and extrinsic rewards are much lower in time.\nExperiments using RF and IDF feature encoding in an environment with noisy TV on or off. The plot tracks extrinsic reward per episode as the training progresses. (Image source:\nBurda, Edwards & Pathak, et al. 2018\n)\nThe forward dynamics optimization can be modeled via variational inference as well.\nVIME\n(short for\n“Variational information maximizing exploration”\n;\nHouthooft, et al. 2017\n) is an exploration strategy based on maximization of\ninformation gain\nabout the agent’s belief of environment dynamics. How much additional information has been obtained about the forward dynamics can be measured as the reduction in entropy.\nLet $\\mathcal{P}$ be the environment transition function, $p(s_{t+1}\\vert s_t, a_t; \\theta)$ be the forward prediction model, parameterized by $\\theta \\in \\Theta$, and $\\xi_t = \\{s_1, a_1, \\dots, s_t\\}$ be the trajectory history. We would like to reduce the entropy after taking a new action and observing the next state, which is to maximize the following:\n$$\n\\begin{aligned}\n&\\sum_t H(\\Theta \\vert \\xi_t, a_t) - H(\\Theta \\vert S_{t+1}, \\xi_t, a_t) \\\\\n=& I(\\Theta; S_{t+1} \\vert \\xi_t, a_t) \\quad \\scriptstyle{\\text{; because } I(X; Y) = I(X) - I(X \\vert Y)} \\\\\n=& \\mathbb{E}_{s_{t+1} \\sim \\mathcal{P}(.\\vert\\xi_t,a_t)} [D_\\text{KL}(p(\\theta \\vert \\xi_t, a_t, s_{t+1}) \\| p(\\theta \\vert \\xi_t, a_t))] \\quad \\scriptstyle{\\text{; because } I(X; Y) = \\mathbb{E}_Y [D_\\text{KL} (p_{X \\vert Y} \\| p_X)]} \\\\\n=& \\mathbb{E}_{s_{t+1} \\sim \\mathcal{P}(.\\vert\\xi_t,a_t)} [D_\\text{KL}(p(\\theta \\vert \\xi_t, a_t, s_{t+1}) \\| p(\\theta \\vert \\xi_t))] \\quad \\scriptstyle{\\text{; because } \\theta \\text{ does not depend on } a_t}\n\\end{aligned}\n$$\nWhile taking expectation over the new possible states, the agent is expected to take a new action to increase the KL divergence (\n“information gain”\n) between its new belief over the prediction model to the old one. This term can be added into the reward function as an intrinsic reward: $r^i_t = D_\\text{KL} [p(\\theta \\vert \\xi_t, a_t, s_{t+1}) | p(\\theta \\vert \\xi_t))]$.\nHowever, computing the posterior $p(\\theta \\vert \\xi_t, a_t, s_{t+1})$ is generally intractable.\n$$\n\\begin{aligned}\np(\\theta \\vert \\xi_t, a_t, s_{t+1}) \n&= \\frac{p(\\theta \\vert \\xi_t, a_t) p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{p(s_{t+1}\\vert\\xi_t, a_t)} \\\\\n&= \\frac{p(\\theta \\vert \\xi_t) p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{p(s_{t+1}\\vert\\xi_t, a_t)} & \\scriptstyle{\\text{; because action doesn't affect the belief.}} \\\\\n&= \\frac{\\color{red}{p(\\theta \\vert \\xi_t)} p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{\\int_\\Theta p(s_{t+1}\\vert\\xi_t, a_t; \\theta) \\color{red}{p(\\theta \\vert \\xi_t)} d\\theta} & \\scriptstyle{\\text{; red part is hard to compute directly.}}\n\\end{aligned}\n$$\nSince it is difficult to compute $p(\\theta\\vert\\xi_t)$ directly, a natural choice is to approximate it with an alternative distribution $q_\\phi(\\theta)$. With variational lower bound, we know the maximization of $q_\\phi(\\theta)$ is equivalent to maximizing $p(\\xi_t\\vert\\theta)$ and minimizing $D_\\text{KL}[q_\\phi(\\theta) | p(\\theta)]$.\nUsing the approximation distribution $q$, the intrinsic reward becomes:\n$$\nr^i_t = D_\\text{KL} [q_{\\phi_{t+1}}(\\theta) \\| q_{\\phi_t}(\\theta))]\n$$\nwhere $\\phi_{t+1}$ represents $q$’s parameters associated with the new relief after seeing $a_t$ and $s_{t+1}$. When used as an exploration bonus, it is normalized by division by the moving median of this KL divergence value.\nHere the dynamics model is parameterized as a\nBayesian neural network\n(BNN), as it maintains a distribution over its weights. The BNN weight distribution $q_\\phi(\\theta)$ is modeled as a fully\nfactorized\nGaussian with $\\phi = \\{\\mu, \\sigma\\}$ and we can easily sample $\\theta \\sim q_\\phi(.)$. After applying a second-order Taylor expansion, the KL term $D_\\text{KL}[q_{\\phi + \\lambda \\Delta\\phi}(\\theta) | q_{\\phi}(\\theta)]$ can be estimated using\nFisher Information Matrix\n$\\mathbf{F}_\\phi$, which is easy to compute, because $q_\\phi$ is factorized Gaussian and thus the covariance matrix is only a diagonal matrix. See more details in\nthe paper\n, especially section 2.3-2.5.\nAll the methods above depend on a single prediction model. If we have multiple such models, we could use the disagreement among models to set the exploration bonus (\nPathak, et al. 2019\n). High disagreement indicates low confidence in prediction and thus requires more exploration.\nPathak, et al. (2019)\nproposed to train a set of forward dynamics models and to use the variance over the ensemble of model outputs as $r_t^i$. Precisely, they encode the state space with\nrandom feature\nand learn 5 models in the  ensemble.\nIllustration of training architecture for self-supervised exploration via disagreement. (Image source:\nPathak, et al. 2019\n)\nBecause $r^i_t$ is differentiable, the intrinsic reward in the model could be directly optimized through gradient descent so as to inform the policy agent to change actions. This differentiable exploration approach is very efficient but limited by having a short exploration horizon.\nRandom Networks\n#\nBut, what if the prediction task is not about the environment dynamics at all? It turns out when the prediction is for a random task, it still can help exploration.\nDORA\n(short for\n“Directed Outreaching Reinforcement Action-Selection”\n;\nFox & Choshen, et al. 2018\n) is a novel framework that injects exploration signals based on a newly introduced,\ntask-independent\nMDP. The idea of DORA depends on two parallel MDPs:\nOne is the original task MDP;\nThe other is an identical MDP but with\nno reward attached\n: Rather, every state-action pair is designed to have value 0. The Q-value learned for the second MDP is called\nE-value\n. If the model cannot perfectly predict E-value to be zero, it is still missing information.\nInitially E-value is assigned with value 1. Such positive initialization can encourage directed exploration for better E-value prediction. State-action pairs with high E-value estimation don’t have enough information gathered yet, at least not enough to exclude their high E-values. To some extent, the logarithm of E-values can be considered as a generalization of\nvisit counters\n.\nWhen using a neural network to do function approximation for E-value, another value head is added to predict E-value and it is simply expected to predict zero. Given a predicted E-value $E(s_t, a_t)$, the exploration bonus is $r^i_t = \\frac{1}{\\sqrt{-\\log E(s_t, a_t)}}$.\nSimilar to DORA,\nRandom Network Distillation\n(\nRND\n;\nBurda, et al. 2018\n) introduces a prediction task\nindependent of the main task\n. The RND exploration bonus is defined as the error of a neural network $\\hat{f}(s_t)$ predicting features of the observations given by a\nfixed randomly initialized\nneural network $f(s_t)$. The motivation is that given a new state, if similar states have been visited many times in the past, the prediction should be easier and thus has lower error. The exploration bonus is $r^i(s_t) = |\\hat{f}(s_t; \\theta) - f(s_t) |_2^2$.\nHow RND (Random Network Distillation) works for providing an intrinsic reward. The features $O_{i+1} \\mapsto f_{i+1}$ are generated by a fixed random neural network. (Image source: OpenAI Blog:\n\"Reinforcement Learning with Prediction-Based Rewards\"\n)\nTwo factors are important in RND experiments:\nNon-episodic setting results in better exploration, especially when not using any extrinsic rewards. It means that the return is not truncated at “Game over” and intrinsic return can spread across multiple episodes.\nNormalization is important since the scale of the reward is tricky to adjust given a random neural network as a prediction target. The intrinsic reward is normalized by division by a running estimate of the standard deviations of the intrinsic return.\nThe RND setup works well for resolving the hard-exploration problem. For example, maximizing the RND exploration bonus consistently finds more than half of the rooms in Montezuma’s Revenge.\nPhysical Properties\n#\nDifferent from games in simulators, some RL applications like Robotics need to understand objects and intuitive reasoning in the physical world. Some prediction tasks require the agent to perform a sequence of interactions with the environment and to observe the corresponding consequences, such as estimating some hidden properties in physics (e.g. mass, friction, etc).\nMotivated by such ideas,\nDenil, et al. (2017)\nfound that DRL agents can learn to perform necessary exploration to discover such hidden properties. Precisely they considered two experiments:\n“Which is heavier?”\n— The agent has to interact with the blocks and infer which one is heavier.\n“Towers”\n— The agent needs to infer how many rigid bodies a tower is composed of by knocking it down.\nThe agent in the experiments first goes through an exploration phase to interact with the environment and to collect information. Once the exploration phase ends, the agent is asked to output a\nlabeling\naction to answer the question. Then a positive reward is assigned to the agent if the answer is correct; otherwise a negative one is assigned. Because the answer requires a decent amount of interactions with items in the scene, the agent has to learn to efficiently play around so as to figure out the physics and the correct answer. The exploration naturally happens.\nIn their experiments, the agent is able to learn in both tasks with performance varied by the difficulty of the task. Although the paper didn’t use the physics prediction task to provide intrinsic reward bonus along with extrinsic reward associated with another learning task, rather it focused on the exploration tasks themselves. I do enjoy the idea of encouraging sophisticated exploration behavior by predicting hidden physics properties in the environment.\nMemory-based Exploration\n#\nReward-based exploration suffers from several drawbacks:\nFunction approximation is slow to catch up.\nExploration bonus is non-stationary.\nKnowledge fading, meaning that states cease to be novel and cannot provide intrinsic reward signals in time.\nMethods in this section rely on external memory to resolve disadvantages of reward bonus-based exploration.\nEpisodic Memory\n#\nAs mentioned above,\nRND\nis better running in an non-episodic setting, meaning the prediction knowledge is accumulated across multiple episodes. The exploration strategy,\nNever Give Up\n(\nNGU\n;\nBadia, et al. 2020a\n), combines an episodic novelty module that can rapidly adapt within one episode with RND as a lifelong novelty module.\nPrecisely, the intrinsic reward in NGU consists of two exploration bonuses from two modules,\nwithin one episode\nand\nacross multiple episodes\n, respectively.\nThe short-term per-episode reward is provided by an\nepisodic novelty module\n. It contains an episodic memory $M$, a dynamically-sized slot-based memory, and an IDF (inverse dynamics features) embedding function $\\phi$, same as the feature encoding in\nICM\nAt every step the current state embedding $\\phi(s_t)$ is added into $M$.\nThe intrinsic bonus is determined by comparing how similar the current observation is to the content of $M$. A larger difference results in a larger bonus.\n$$\n r^\\text{episodic}_t \\approx \\frac{1}{\\sqrt{\\sum_{\\phi_i \\in N_k} K(\\phi(x_t), \\phi_i)} + c}\n $$\nwhere $K(x, y)$ is a kernel function for measuring the distance between two samples. $N_k$ is a set of $k$ nearest neighbors in $M$ according to $K(., .)$.  $c$ is a small constant to keep the denominator non-zero. In the paper, $K(x, y)$ is configured to be the inverse kernel:\n$$\n K(x, y) = \\frac{\\epsilon}{\\frac{d^2(x, y)}{d^2_m} + \\epsilon}\n $$\nwhere $d(.,.)$ is Euclidean distance between two samples and $d_m$ is a running average of the squared Euclidean distance of the k-th nearest neighbors for better robustness. $\\epsilon$ is a small constant.\nThe architecture of NGU's embedding function (left) and reward generator (right). (Image source:\nBadia, et al. 2020a\n)\nThe long-term across-episode novelty relies on RND prediction error in\nlife-long novelty module\n. The exploration bonus is $\\alpha_t = 1 + \\frac{e^\\text{RND}(s_t) - \\mu_e}{\\sigma_e}$ where $\\mu_e$ and $\\sigma_e$ are running mean and std dev for RND error $e^\\text{RND}(s_t)$.\nHowever in the conclusion section of the\nRND paper\n, I noticed the following statement:\n“We find that the RND exploration bonus is sufficient to deal with local exploration, i.e. exploring the consequences of short-term decisions, like whether to interact with a particular object, or avoid it. However global exploration that involves coordinated decisions over long time horizons is beyond the reach of our method. \"\nAnd this confuses me a bit how RND can be used as a good life-long novelty bonus provider. If you know why, feel free to leave a comment below.\nThe final combined intrinsic reward is $r^i_t = r^\\text{episodic}_t \\cdot \\text{clip}(\\alpha_t, 1, L)$, where $L$ is a constant maximum reward scalar.\nThe design of NGU enables it to have two nice properties:\nRapidly discourages\nrevisiting the same state\nwithin\nthe same episode;\nSlowly discourages\nrevisiting states that have been visited many times\nacross\nepisodes.\nLater, built on top of NGU, DeepMind proposed “Agent57” (\nBadia, et al. 2020b\n), the first deep RL agent that outperforms the standard human benchmark on\nall\n57 Atari games. Two major improvements in Agent57 over NGU are:\nA\npopulation\nof policies are trained in Agent57, each equipped with a different exploration parameter pair $\\{(\\beta_j, \\gamma_j)\\}_{j=1}^N$. Recall that given $\\beta_j$, the reward is constructed as $r_{j,t} = r_t^e + \\beta_j r^i_t$ and $\\gamma_j$ is the reward discounting factor. It is natural to expect policies with higher $\\beta_j$ and lower $\\gamma_j$ to make more progress early in training, while the opposite would be expected as training progresses. A meta-controller (\nsliding-window UCB bandit algorithm\n) is trained to select which policies should be prioritized.\nThe second improvement is a new parameterization of Q-value function that decomposes the contributions of the intrinsic and extrinsic rewards in a similar form as the bundled reward: $Q(s, a; \\theta_j) = Q(s, a; \\theta_j^e) + \\beta_j Q(s, a; \\theta_j^i)$. During training, $Q(s, a; \\theta_j^e)$ and $Q(s, a; \\theta_j^i)$ are optimized separately with rewards $r_j^e$ and $r_j^i$, respectively.\nA pretty cool illustration of techniques developed in time since DQN in 2015, eventually leading to Agent57. (Image source: DeepMind Blog:\n\"Agent57: Outperforming the human Atari benchmark\"\n)\nInstead of using the Euclidean distance to measure closeness of states in episodic memory,\nSavinov, et al. (2019)\ntook the transition between states into consideration and proposed a method to measure the number of steps needed to visit one state from other states in memory, named\nEpisodic Curiosity (EC)\nmodule. The novelty bonus depends on reachability between states.\nAt the beginning of each episode, the agent starts with an empty episodic memory $M$.\nAt every step, the agent compares the current state with saved states in memory to determine novelty bonus: If the current state is novel (i.e., takes more steps to reach from observations in memory than a threshold), the agent gets a bonus.\nThe current state is added into the episodic memory if the novelty bonus is high enough. (Imagine that if all the states were added into memory, any new state could be added within 1 step.)\nRepeat 1-3 until the end of this episode.\nThe nodes in the graph are states, the edges are possible transitions. The blue nodes are states in memory. The green nodes are reachable from the memory within $k = 2$ steps (not novel). The orange nodes are further away, so they are considered as novel states. (Image source:\nSavinov, et al. 2019\n)\nIn order to estimate reachability between states, we need to access the transition graph, which is unfortunately not entirely known. Thus,\nSavinov, et al. (2019)\ntrained a\nsiamese\nneural network to predict how many steps separate two states. It contains one embedding network $\\phi: \\mathcal{S} \\mapsto \\mathbb{R}^n$ to first encode the states to feature vectors and then one comparator network $C: \\mathbb{R}^n \\times \\mathbb{R}^n \\mapsto [0, 1]$ to output a binary label on whether two states are close enough (i.e., reachable within $k$ steps) in the transition graph, $C(\\phi(s_i), \\phi(s_j)) \\mapsto [0, 1]$.\nAn episodic memory buffer $M$ stores embeddings of some past observations within the same episode. A new observation will be compared with existing state embeddings via $C$ and the results are aggregated (e.g. max, 90th percentile) to provide a reachability score $C^M(\\phi(s_t))$. The exploration bonus is $r^i_t = \\big(C’ - C^M(f(s_t))\\big)$, where $C’$ is a predefined threshold for determining the sign of the reward (e.g. $C’=0.5$ works well for fixed-duration episodes). High bonus is awarded to new states when they are not easily reachable from states in the memory buffer.\nThey claimed that the EC module can overcome the\nnoisy-TV\nproblem.\nThe architecture of episodic curiosity (EC) module for intrinsic reward generation.  (Image source:\nSavinov, et al. 2019\n)\nDirect Exploration\n#\nGo-Explore\n(\nEcoffet, et al., 2019\n) is an algorithm aiming to solve the “hard-exploration” problem. It is composed of the following two phases.\nPhase 1 (“Explore until solved”)\nfeels quite like\nDijkstra’s algorithm\nfor finding shortest paths in a graph. Indeed, no neural network is involved in phase 1. By maintaining a memory of interesting states as well as trajectories leading to them, the agent can go back (given a simulator is\ndeterministic\n) to promising states and continue doing\nrandom\nexploration from there. The state is mapped into a short discretized code (named “cell”) in order to be memorized. The memory is updated if a new state appears or a better/shorter trajectory is found. When selecting which past states to return to, the agent might select one in the memory uniformly or according to heuristics like recency, visit count, count of neighbors in the memory, etc. This process is repeated until the task is solved and at least one solution trajectory is found.\nThe above found high-performance trajectories would not work well on evaluation envs with any stochasticity. Thus,\nPhase 2 (“Robustification”)\nis needed to robustify the solution via imitation learning. They adopted\nBackward Algorithm\n, in which the agent is started near the last state in the trajectory and then runs RL optimization from there.\nOne important note in phase 1 is: In order to go back to a state deterministically without exploration, Go-Explore depends on a resettable and deterministic simulator, which is a big disadvantage.\nTo make the algorithm more generally useful to environments with stochasticity, an enhanced version of Go-Explore (\nEcoffet, et al., 2020\n), named\npolicy-based Go-Explore\nwas proposed later.\nInstead of resetting the simulator state effortlessly, the policy-based Go-Explore learns a\ngoal-conditioned policy\nand uses that to access a known state in memory repeatedly. The goal-conditioned policy is trained to follow the best trajectory that previously led to the selected states in memory. They include a\nSelf-Imitation Learning\n(\nSIL\n;\nOh, et al. 2018\n) loss to help extract as much information as possible from successful trajectories.\nAlso, they found sampling from policy works better than random actions when the agent returns to promising states to continue exploration.\nAnother improvement in policy-based Go-Explore is to make the downscaling function of images to cells adjustable. It is optimized so that there would be neither too many nor too few cells in the memory.\nAn overview of the Go-Explore algorithm. (Image source:\nEcoffet, et al., 2020\n)\nAfter vanilla Go-Explore,\nYijie Guo, et al. (2019)\nproposed\nDTSIL\n(Diverse Trajectory-conditioned Self-Imitation Learning), which shared a similar idea as policy-based Go-Explore above. DTSIL maintains a memory of diverse demonstrations collected during training and uses them to train a trajectory-conditioned policy via\nSIL\n. They prioritize trajectories that end with a rare state during sampling.\nAlgorithm of DTSIL (Diverse Trajectory-conditioned Self-Imitation Learning). (Image source:\nYijie Guo, et al. 2019\n)\nThe similar approach is also seen in\nGuo, et al. (2019)\n. The main idea is to store goals with\nhigh uncertainty\nin memory so that later the agent can revisit these goal states with a goal-conditioned policy repeatedly. In each episode, the agent flips a coin (probability 0.5) to decide whether it will act greedily w.r.t. the policy or do directed exploration by sampling goals from the memory.\nDifferent components in directed exploration with function approximation. (Image source:\nGuo, et al. 2019\n)\nThe uncertainty measure of a state can be something simple like count-based bonuses or something complex like density or bayesian models. The paper trained a forward dynamics model and took its prediction error as the uncertainty metric.\nQ-Value Exploration\n#\nInspired by\nThompson sampling\n,\nBootstrapped DQN\n(\nOsband, et al. 2016\n) introduces a notion of uncertainty in Q-value approximation in classic\nDQN\nby using the\nbootstrapping\nmethod. Bootstrapping is to approximate a distribution by sampling with replacement from the same population multiple times and then aggregate the results.\nMultiple Q-value heads are trained in parallel but each only consumes a bootstrapped sub-sampled set of data and each has its own corresponding target network. All the Q-value heads share the same backbone network.\nThe algorithm of Bootstrapped DQN. (Image source:\nOsband, et al. 2016\n)\nAt the beginning of one episode, one Q-value head is sampled uniformly and acts for collecting experience data in this episode. Then a binary mask is sampled from the masking distribution $m \\sim \\mathcal{M}$ and decides which heads can use this data for training. The choice of masking distribution $\\mathcal{M}$ determines how bootstrapped samples are generated; For example,\nIf $\\mathcal{M}$ is an independent Bernoulli distribution with $p=0.5$, this corresponds to the double-or-nothing bootstrap.\nIf $\\mathcal{M}$ always returns an all-one mask, the algorithm reduces to an ensemble method.\nHowever, this kind of exploration is still restricted, because uncertainty introduced by bootstrapping fully relies on the training data. It is better to inject some prior information independent of the data. This “noisy” prior is expected to drive the agent to keep exploring when the reward is sparse. The algorithm of adding random prior into bootstrapped DQN for better exploration (\nOsband, et al. 2018\n) depends on Bayesian linear regression. The core idea of Bayesian regression is: We can\n“generate posterior samples by training on noisy versions of the data, together with some random regularization”\n.\nLet $\\theta$ be the Q function parameter and $\\theta^-$ for the target Q, the loss function using a randomized prior function $p$ is:\n$$\n\\mathcal{L}(\\theta, \\theta^{-}, p, \\mathcal{D}; \\gamma) = \\sum_{t\\in\\mathcal{D}}\\Big( r_t + \\gamma \\max_{a'\\in\\mathcal{A}} (\\underbrace{Q_{\\theta^-} + p)}_\\text{target Q}(s'_t, a') - \\underbrace{(Q_\\theta + p)}_\\text{Q to optimize}(s_t, a_t) \\Big)^2\n$$\nVaritional Options\n#\nOptions are policies with termination conditions. There are a large set of options available in the search space and they are independent of an agent’s intentions. By explicitly including intrinsic options into modeling, the agent can obtain intrinsic rewards for exploration.\nVIC\n(short for\n“Variational Intrinsic Control”\n;\nGregor, et al. 2017\n) is such a framework for providing the agent with intrinsic exploration bonuses based on modeling options and learning policies conditioned on options. Let $\\Omega$ represent an option which starts from $s_0$ and ends at $s_f$. An environment probability distribution $p^J(s_f \\vert s_0, \\Omega)$ defines where an option $\\Omega$ terminates given a starting state $s_0$. A controllability distribution $p^C(\\Omega \\vert s_0)$ defines the probability distribution of options we can sample from. And by definition we have $p(s_f, \\Omega \\vert s_0) = p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0)$.\nWhile choosing options, we would like to achieve two goals:\nAchieve a diverse set of the final states from $s_0$ ⇨ Maximization of $H(s_f \\vert s_0)$.\nKnow precisely which state a given option $\\Omega$ can end with ⇨ Minimization of $H(s_f \\vert s_0, \\Omega)$.\nCombining them, we get mutual information $I(\\Omega; s_f \\vert s_0)$ to maximize:\n$$\n\\begin{aligned}\nI(\\Omega; s_f \\vert s_0)\n&= H(s_f \\vert s_0) - H(s_f \\vert s_0, \\Omega) \\\\\n&= - \\sum_{s_f} p(s_f \\vert s_0) \\log p(s_f \\vert s_0) + \\sum_{s_f, \\Omega} p(s_f, \\Omega \\vert s_0) \\log \\frac{p(s_f, \\Omega \\vert s_0)}{p^C(\\Omega \\vert s_0)} \\\\\n&= - \\sum_{s_f} p(s_f \\vert s_0) \\log p(s_f \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log p^J(s_f \\vert s_0, \\Omega) \\\\\n\\end{aligned}\n$$\nBecause mutual information is symmetric, we can switch $s_f$ and $\\Omega$ in several places without breaking the equivalence. Also because $p(\\Omega \\vert s_0, s_f)$ is difficult to observe, let us replace it with an approximation distribution $q$. According to the variational lower bound, we would have $I(\\Omega; s_f \\vert s_0) \\geq I^{VB}(\\Omega; s_f \\vert s_0)$.\n$$\n\\begin{aligned}\nI(\\Omega; s_f \\vert s_0)\n&= I(s_f; \\Omega \\vert s_0) \\\\\n&= - \\sum_{\\Omega} p(\\Omega \\vert s_0) \\log p(\\Omega \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log \\color{red}{p(\\Omega \\vert s_0, s_f)}\\\\\nI^{VB}(\\Omega; s_f \\vert s_0)\n&= - \\sum_{\\Omega} p(\\Omega \\vert s_0) \\log p(\\Omega \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log \\color{red}{q(\\Omega \\vert s_0, s_f)} \\\\\nI(\\Omega; s_f \\vert s_0) &\\geq I^{VB}(\\Omega; s_f \\vert s_0)\n\\end{aligned}\n$$\nThe algorithm for VIC (Variational Intrinsic Control). (Image source:\nGregor, et al. 2017\n)\nHere $\\pi(a \\vert \\Omega, s)$ can be optimized with any RL algorithm. The option inference function $q(\\Omega \\vert s_0, s_f)$ is doing supervised learning. The prior $p^C$ is updated so that it tends to choose $\\Omega$ with higher rewards. Note that $p^C$ can also be fixed (e.g. a Gaussian). Various $\\Omega$ will result in different behavior through learning. Additionally,\nGregor, et al. (2017)\nobserved that it is difficult to make VIC with explicit options work in practice with function approximation and therefore they also proposed another version of VIC with implicit options.\nDifferent from VIC which models $\\Omega$ conditioned only on the start and end states,\nVALOR\n(short for\n“Variational Auto-encoding Learning of Options by Reinforcement”\n;\nAchiam, et al. 2018\n) relies on the whole trajectory to extract the option context $c$, which is sampled from a fixed Gaussian distribution. In VALOR:\nA policy acts as an encoder, translating contexts from a noise distribution into trajectories\nA decoder attempts to recover the contexts from the trajectories, and rewards the policies for making contexts easier to distinguish. The decoder never sees the actions during training, so the agent has to interact with the environment in a way that facilitates communication with the decoder for better prediction. Also, the decoder recurrently takes in a sequence of steps in one trajectory to better model the correlation between timesteps.\nThe decoder of VALOR is a biLSTM which takes $N = 11$ equally spaced observations from one trajectory as inputs. (Image source:\nAchiam, et al. 2018\n)\nDIAYN (“Diversity is all you need”;\nEysenbach, et al. 2018\n) has the idea lying in the same direction, although with a different name — DIAYN models the policies conditioned on a latent\nskill\nvariable. See my\nprevious post\nfor more details.\nCitation\n#\nCited as:\nWeng, Lilian. (Jun 2020). Exploration strategies in deep reinforcement learning. Lil’Log. https://lilianweng.github.io/posts/2020-06-07-exploration-drl/.\nOr\n@article{weng2020exploration,\n  title   = \"Exploration Strategies in Deep Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Jun\",\n  url     = \"https://lilianweng.github.io/posts/2020-06-07-exploration-drl/\"\n}\nReference\n#\n[1] Pierre-Yves Oudeyer & Frederic Kaplan.\n“How can we define intrinsic motivation?”\nConf. on Epigenetic Robotics, 2008.\n[2] Marc G. Bellemare, et al.\n“Unifying Count-Based Exploration and Intrinsic Motivation”\n. NIPS 2016.\n[3] Georg Ostrovski, et al.\n“Count-Based Exploration with Neural Density Models”\n. PMLR 2017.\n[4] Rui Zhao & Volker Tresp.\n“Curiosity-Driven Experience Prioritization via\nDensity Estimation”\n. NIPS 2018.\n[5] Haoran Tang, et al.\n\"#Exploration: A Study of Count-Based Exploration for Deep Reinforcement Learning”\n. NIPS 2017.\n[6] Jürgen Schmidhuber.\n“A possibility for implementing curiosity and boredom in model-building neural controllers”\n1991.\n[7] Pierre-Yves Oudeyer, et al.\n“Intrinsic Motivation Systems for Autonomous Mental Development”\nIEEE Transactions on Evolutionary Computation, 2007.\n[8] Bradly C. Stadie, et al.\n“Incentivizing Exploration In Reinforcement Learning With Deep Predictive Models”\n. ICLR 2016.\n[9] Deepak Pathak, et al.\n“Curiosity-driven Exploration by Self-supervised Prediction”\n. CVPR 2017.\n[10] Yuri Burda, Harri Edwards & Deepak Pathak, et al.\n“Large-Scale Study of Curiosity-Driven Learning”\n. arXiv 1808.04355 (2018).\n[11] Joshua Achiam & Shankar Sastry.\n“Surprise-Based Intrinsic Motivation for Deep Reinforcement Learning”\nNIPS 2016 Deep RL Workshop.\n[12] Rein Houthooft, et al.\n“VIME: Variational information maximizing exploration”\n. NIPS 2016.\n[13] Leshem Choshen, Lior Fox & Yonatan Loewenstein.\n“DORA the explorer: Directed outreaching reinforcement action-selection”\n. ICLR 2018\n[14] Yuri Burda, et al.\n“Exploration by Random Network Distillation”\nICLR 2019.\n[15] OpenAI Blog:\n“Reinforcement Learning with\nPrediction-Based Rewards”\nOct, 2018.\n[16] Misha Denil, et al.\n“Learning to Perform Physics Experiments via Deep Reinforcement Learning”\n. ICLR 2017.\n[17] Ian Osband, et al.\n“Deep Exploration via Bootstrapped DQN”\n. NIPS 2016.\n[18] Ian Osband, John Aslanides & Albin Cassirer.\n“Randomized Prior Functions for Deep Reinforcement Learning”\n. NIPS 2018.\n[19] Karol Gregor, Danilo Jimenez Rezende & Daan Wierstra.\n“Variational Intrinsic Control”\n. ICLR 2017.\n[20] Joshua Achiam, et al.\n“Variational Option Discovery Algorithms”\n. arXiv 1807.10299 (2018).\n[21] Benjamin Eysenbach, et al.\n“Diversity is all you need: Learning skills without a reward function.”\n. ICLR 2019.\n[22] Adrià Puigdomènech Badia, et al.\n“Never Give Up (NGU): Learning Directed Exploration Strategies”\nICLR 2020.\n[23] Adrià Puigdomènech Badia, et al.\n“Agent57: Outperforming the Atari Human Benchmark”\n. arXiv 2003.13350 (2020).\n[24] DeepMind Blog:\n“Agent57: Outperforming the human Atari benchmark”\nMar 2020.\n[25] Nikolay Savinov, et al.\n“Episodic Curiosity through Reachability”\nICLR 2019.\n[26] Adrien Ecoffet, et al.\n“Go-Explore: a New Approach for Hard-Exploration Problems”\n. arXiv 1901.10995 (2019).\n[27] Adrien Ecoffet, et al.\n“First return then explore”\n. arXiv 2004.12919 (2020).\n[28] Junhyuk Oh, et al.\n“Self-Imitation Learning”\n. ICML 2018.\n[29] Yijie Guo, et al.\n“Self-Imitation Learning via Trajectory-Conditioned Policy for Hard-Exploration Tasks”\n. arXiv 1907.10247 (2019).\n[30] Zhaohan Daniel Guo & Emma Brunskill.\n“Directed Exploration for Reinforcement Learning”\n. arXiv 1906.07805 (2019).\n[31] Deepak Pathak, et al.\n“Self-Supervised Exploration via Disagreement.”\nICML 2019.",
            "metadata": {
              "title": "Exploration Strategies in Deep Reinforcement Learning | Lil'Log",
              "description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "keywords": "reinforcement-learning, exploration, long-read",
              "author": "Lilian Weng",
              "og:title": "Exploration Strategies in Deep Reinforcement Learning",
              "og:description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
              "twitter:card": "summary",
              "twitter:title": "Exploration Strategies in Deep Reinforcement Learning",
              "twitter:description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "article:section": "posts",
              "article:published_time": "2020-06-07T00:00:00+00:00",
              "article:modified_time": "2020-06-07T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/7b9f4f54765d/code/body-000.txt",
                "chars": 281,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
                "bytes": 5376803,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-6b91dcea21697574b105.gif",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
                "bytes": 291157,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-1f9233b348db9b37e2ee.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
                "bytes": 467414,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-acc2d9731b17ed2baf72.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
                "bytes": 149758,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-c138b9ae776276fc8846.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
                "bytes": 1129963,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-02a63a130390d75c9b29.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
                "bytes": 245312,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-7c7b014d7ed4fa8401a1.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
                "bytes": 208294,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-1e519d78d676ad46c539.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
                "bytes": 76657,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-70e7c7e4493d4048b5d8.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
                "bytes": 331868,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-30ce759c796a4b00b5e9.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
                "bytes": 499500,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-6f821f70a67bba2e4ef7.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
                "bytes": 340971,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-2ea98dac18eabd367373.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
                "bytes": 204770,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-84f271779024a8ad2f72.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
                "bytes": 507936,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-c6959ef2ce02358a0d4d.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
                "bytes": 451854,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-b23af17d8eb4125329b2.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
                "bytes": 144456,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-cd84e9d2b02b76f1bf08.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
                "bytes": 256303,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-5e9526e04be190a25b0e.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
                "bytes": 284015,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-bb1d03b945066ecdbb48.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
                "bytes": 199433,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-939aa5d0a48211c07558.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "Exploitation versus exploration",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "RL",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "algorithms",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Boltzmann_distribution",
                "label": "boltzmann distribution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.10295",
                "label": "Fortunato, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.01905",
                "label": "Plappert, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Montezuma%27s_Revenge_(video_game)",
                "label": "Montezuma’s Revenge",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.12894",
                "label": "Burda, et al (2018)",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/reinforcement-learning-with-prediction-based-rewards/",
                "label": "\"Reinforcement Learning with Prediction-Based Rewards\"",
                "type": "a"
              },
              {
                "href": "https://www.researchgate.net/profile/Pierre-Yves_Oudeyer/publication/29614795_How_can_we_define_intrinsic_motivation/links/09e415107f1b4c8041000000/How-can-we-define-intrinsic-motivation.pdf",
                "label": "Oudeyer & Kaplan, 2008",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.01868",
                "label": "Bellemare, et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://www.ics.uci.edu/~dechter/courses/ics-295/fall-2019/papers/2008-littman-aij-main.pdf",
                "label": "Strehl & Littman, 2008",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v32/bellemare14.html",
                "label": "CTS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01310",
                "label": "Georg Ostrovski, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.05328",
                "label": "van den Oord et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.08039",
                "label": "Zhao & Tresp (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04717",
                "label": "Tang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "LSH",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "Transformer improvement",
                "type": "a"
              },
              {
                "href": "https://www.cs.princeton.edu/courses/archive/spr04/cos598B/bib/CharikarEstim.pdf",
                "label": "SimHash",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.957",
                "label": "Schmidhuber, 1991",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.177.7661&rep=rep1&type=pdf",
                "label": "Oudeyer, et al. 2007",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.177.7661&rep=rep1&type=pdf)",
                "label": "Oudeyer, et al. 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1507.00814",
                "label": "Stadie et al. (2015)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.05363",
                "label": "Pathak, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04355",
                "label": "Burda, Edwards & Pathak, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.09674",
                "label": "Houthooft, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/book/10.1007/978-1-4612-0745-0",
                "label": "Bayesian neural network",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "Fisher Information Matrix",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.04161",
                "label": "Pathak, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.04012",
                "label": "Fox & Choshen, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.01843",
                "label": "Denil, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.06038",
                "label": "Badia, et al. 2020a",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.13350",
                "label": "Badia, et al. 2020b",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/0805.3415.pdf",
                "label": "sliding-window UCB bandit algorithm",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/article/Agent57-Outperforming-the-human-Atari-benchmark",
                "label": "\"Agent57: Outperforming the human Atari benchmark\"",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.02274",
                "label": "Savinov, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "siamese",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.10995",
                "label": "Ecoffet, et al., 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm",
                "label": "Dijkstra’s algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.03381",
                "label": "Backward Algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.12919",
                "label": "Ecoffet, et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.05635",
                "label": "Oh, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.10247",
                "label": "Yijie Guo, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.07805",
                "label": "Guo, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.04621",
                "label": "Osband, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bootstrapping_(statistics)",
                "label": "bootstrapping",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03335",
                "label": "Osband, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.07507",
                "label": "Gregor, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.10299",
                "label": "Achiam, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.06070",
                "label": "Eysenbach, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "previous post",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.567.6524&rep=rep1&type=pdf",
                "label": "“How can we define intrinsic motivation?”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01732",
                "label": "“Surprise-Based Intrinsic Motivation for Deep Reinforcement Learning”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:33Z",
            "source_url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.10295",
                "bytes": 5552124,
                "reused": false,
                "local_path": "papers/repair/1f48b9e472f1b3e0563e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.01905",
                "bytes": 3960914,
                "reused": false,
                "local_path": "papers/repair/dc0f09fcd81792aca048.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.12894",
                "bytes": 2911077,
                "reused": false,
                "local_path": "papers/repair/d17231099b59eb566f4d.pdf"
              },
              {
                "status": "http_403",
                "url": "https://www.researchgate.net/profile/Pierre-Yves_Oudeyer/publication/29614795_How_can_we_define_intrinsic_motivation/links/09e415107f1b4c8041000000/How-can-we-define-intrinsic-motivation.pdf",
                "retried_at": "2026-10-20T17:42:14Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.01868",
                "bytes": 2457210,
                "reused": false,
                "local_path": "papers/repair/c503c78de7ba5ad6362e.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.ics.uci.edu/~dechter/courses/ics-295/fall-2019/papers/2008-littman-aij-main.pdf",
                "bytes": 409936,
                "reused": false,
                "local_path": "papers/repair/b5c556b215acf6e105c1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01310",
                "bytes": 2916725,
                "reused": false,
                "local_path": "papers/repair/bdac3ac1627bde4d46e7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.05328",
                "bytes": 3801322,
                "reused": false,
                "local_path": "papers/repair/19c3e48f1383cc8845a2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.08039",
                "bytes": 3640642,
                "reused": false,
                "local_path": "papers/repair/545ae3e37b78208a50c7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04717",
                "bytes": 5922605,
                "reused": false,
                "local_path": "papers/repair/708608a107423a31260a.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.princeton.edu/courses/archive/spr04/cos598B/bib/CharikarEstim.pdf",
                "bytes": 158779,
                "reused": false,
                "local_path": "papers/repair/2e350dc41664964cf4c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1507.00814",
                "bytes": 1214970,
                "reused": false,
                "local_path": "papers/repair/1b3b417213490898c8fd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.05363",
                "bytes": 2107475,
                "reused": false,
                "local_path": "papers/repair/bb6518ca6eee5ed84bcd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04355",
                "bytes": 5650841,
                "reused": false,
                "local_path": "papers/repair/ac681cd0663a3bbe19ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.09674",
                "bytes": 3838238,
                "reused": false,
                "local_path": "papers/repair/aea7c89cb600a3d85aa6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.04161",
                "bytes": 4625254,
                "reused": false,
                "local_path": "papers/repair/d391070453bdf8dda89b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.04012",
                "bytes": 5927965,
                "reused": false,
                "local_path": "papers/repair/5613937bebaf570d77bd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01843",
                "bytes": 997337,
                "reused": false,
                "local_path": "papers/repair/5d93aa50d61bc398ce91.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.06038",
                "bytes": 5017925,
                "reused": false,
                "local_path": "papers/repair/69a7ead1dbea9f7670bb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.13350",
                "bytes": 4229515,
                "reused": false,
                "local_path": "papers/repair/e9c227fe1baabe459214.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/0805.3415.pdf",
                "bytes": 638874,
                "reused": false,
                "local_path": "papers/repair/00a83b219fdbe0a26878.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.02274",
                "bytes": 4740962,
                "reused": false,
                "local_path": "papers/repair/7cd12e35e24d9a65f2ee.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.10995",
                "bytes": 3381875,
                "reused": false,
                "local_path": "papers/repair/06494300d92be8e99fdd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.03381",
                "bytes": 1109667,
                "reused": false,
                "local_path": "papers/repair/fae1fd91a0865877cdbb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.12919",
                "bytes": 7040307,
                "reused": false,
                "local_path": "papers/repair/4bca2e670151ddcbd087.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.05635",
                "bytes": 3945361,
                "reused": false,
                "local_path": "papers/repair/4ab58d1cfd4397625733.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.10247",
                "bytes": 9692932,
                "reused": false,
                "local_path": "papers/repair/636049565411cb228c10.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.07805",
                "bytes": 588269,
                "reused": false,
                "local_path": "papers/repair/d90ddf5ab36a75311f87.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.04621",
                "bytes": 6874097,
                "reused": true,
                "local_path": "papers/repair/d7a1d129f52a82d595ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03335",
                "bytes": 1549581,
                "reused": false,
                "local_path": "papers/repair/00fa135c690c6b02e961.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.07507",
                "bytes": 824486,
                "reused": false,
                "local_path": "papers/repair/13142c294f93722d3f50.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.10299",
                "bytes": 4005026,
                "reused": false,
                "local_path": "papers/repair/4a3dfad91f75e22c371f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.06070",
                "bytes": 10804715,
                "reused": false,
                "local_path": "papers/repair/682027046f87efa4a50a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01732",
                "bytes": 883210,
                "reused": false,
                "local_path": "papers/repair/c78f6ff64e8c52b250be.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 50020,
            "expected_body_images": 18,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_403",
            "raw_html": "attachments/7b9f4f54765d/pages/source.html",
            "local_html": "attachments/7b9f4f54765d/pages/article.html",
            "body_base_path": "attachments/7b9f4f54765d/pages/",
            "body_markdown_path": "attachments/7b9f4f54765d/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
          "status": "partial",
          "article_id": "3e47ba682561",
          "local_path": "series-follow/1602/repair/f7460f9330e723bf3e4f.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
              "bytes": 179202,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e21a214c6127867b9495.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
              "bytes": 183003,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0f5bdb5a435b843e8180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
              "bytes": 18594,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f369233bacf831326935.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning Word Embedding",
            "keywords": "词嵌入,word2vec,GloVe",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "publish_date": "2017-10",
            "corpus_stage": "预训练/SFT",
            "notes": "词嵌入学习综述",
            "id": "3e47ba682561",
            "collected_at": "2026-10-02T14:13:32",
            "title": "Learning Word Embedding | Lil'Log",
            "body_markdown": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).\nHowever, one-hot encoding is impractical computationally when dealing with the entire vocabulary, as the representation demands hundreds of thousands of dimensions. Word embedding represents words and phrases in vectors of (non-binary) numeric values with much lower and thus denser dimensions. An intuitive assumption for good word embedding is that they can approximate the similarity between words (i.e., “cat” and “kitten” are similar words, and thus they are expected to be close in the reduced vector space) or disclose hidden semantic relationships (i.e., the relationship between “cat” and “kitten” is an analogy to the one between “dog” and “puppy”). Contextual information is super useful for learning word meaning and relationship, as similar words may appear in the similar context often.\nThere are two main approaches for learning word embedding, both relying on the contextual knowledge.\nCount-based\n: The first one is unsupervised, based on matrix factorization of a global word co-occurrence matrix. Raw co-occurrence counts do not work well, so we want to do smart things on top.\nContext-based\n: The second approach is supervised. Given a local context, we want to design a model to predict the target words and in the meantime, this model learns the efficient word embedding representation.\nCount-Based Vector Space Model\n#\nCount-based vector space models heavily rely on the word frequency and co-occurrence matrix with the assumption that words in the same contexts share similar or related semantic meanings. The models map count-based statistics like co-occurrences between neighboring words down to a small and dense word vectors. PCA, topic models, and neural probabilistic language models are all good examples of this category.\nDifferent from the count-based approaches, context-based methods build predictive models that directly target at predicting a word given its neighbors. The dense word vectors are part of the model parameters. The best vector representation of each word is learned during the model training process.\nContext-Based: Skip-Gram Model\n#\nSuppose that you have a sliding window of a fixed size moving along a sentence: the word in the middle is the “target” and those on its left and right within the sliding window are the context words. The skip-gram model (\nMikolov et al., 2013\n) is trained to predict the probabilities of a word being a context word for the given target.\nThe following example demonstrates multiple pairs of target and context words as training samples, generated by a 5-word window sliding along the sentence.\n“The man who passes the sentence should swing the sword.” – Ned Stark\nSliding window (size = 5)\nTarget word\nContext\n[The man who]\nthe\nman, who\n[The man who passes]\nman\nthe, who, passes\n[The man who passes the]\nwho\nthe, man, passes, the\n[man who passes the sentence]\npasses\nman, who, the, sentence\n…\n…\n…\n[sentence should swing the sword]\nswing\nsentence, should, the, sword\n[should swing the sword]\nthe\nshould, swing, sword\n[swing the sword]\nsword\nswing, the\n{:.info}\nEach context-target pair is treated as a new observation in the data. For example, the target word “swing” in the above case produces four training samples: (“swing”, “sentence”), (“swing”, “should”), (“swing”, “the”), and (“swing”, “sword”).\nThe skip-gram model. Both the input vector $\\mathbf{x}$ and the output $\\mathbf{y}$ are one-hot encoded word representations. The hidden layer is the word embedding of size $N$.\nGiven the vocabulary size $V$, we are about to learn word embedding vectors of size $N$. The model learns to predict one context word (output) using one target word (input) at a time.\nAccording to Fig. 1,\nBoth input word $w_i$ and the output word $w_j$ are one-hot encoded into binary vectors $\\mathbf{x}$ and $\\mathbf{y}$ of size $V$.\nFirst, the multiplication of the binary vector $\\mathbf{x}$ and the word embedding matrix $W$ of size $V \\times N$ gives us the embedding vector of the input word $w_i$: the i-th row of the matrix $W$.\nThis newly discovered embedding vector of dimension $N$ forms the hidden layer.\nThe multiplication of the hidden layer and the word context matrix $W’$ of size $N \\times V$ produces the output one-hot encoded vector $\\mathbf{y}$.\nThe output context matrix $W’$ encodes the meanings of words as context, different from the embedding matrix $W$. NOTE: Despite the name, $W’$ is independent of $W$, not a transpose or inverse or whatsoever.\nContext-Based: Continuous Bag-of-Words (CBOW)\n#\nThe Continuous Bag-of-Words (CBOW) is another similar model for learning word vectors. It predicts the target word (i.e. “swing”) from source context words (i.e., “sentence should the sword”).\nThe CBOW model. Word vectors of multiple context words are averaged to get a fixed-length vector as in the hidden layer. Other symbols have the same meanings as in Fig 1.\nBecause there are multiple contextual words, we average their corresponding word vectors, constructed by the multiplication of the input vector and the matrix $W$. Because the averaging stage smoothes over a lot of the distributional information, some people believe the CBOW model is better for small dataset.\nLoss Functions\n#\nBoth the skip-gram model and the CBOW model should be trained to minimize a well-designed loss/objective function. There are several loss functions we can incorporate to train these language models. In the following discussion, we will use the skip-gram model as an example to describe how the loss is computed.\nFull Softmax\n#\nThe skip-gram model defines the embedding vector of every word by the matrix $W$ and the context vector by the output matrix $W’$. Given an input word $w_I$, let us label the corresponding row of $W$ as vector $v_{w_I}$ (embedding vector) and its corresponding column of $W’$ as $v’_{w_I}$ (context vector). The final output layer applies softmax to compute the probability of predicting the output word $w_O$ given $w_I$, and therefore:\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nThis is accurate as presented in However, when $V$ is extremely large, calculating the denominator by going through all the words for every single sample is computationally impractical. The demand for more efficient conditional probability estimation leads to the new methods like\nhierarchical softmax\n.\nHierarchical Softmax\n#\nMorin and Bengio (\n2005\n) proposed hierarchical softmax to make the sum calculation faster with the help of a binary tree structure. The hierarchical softmax encodes the language model’s output softmax layer into a tree hierarchy, where each leaf is one word and each internal node stands for relative probabilities of the children nodes.\nAn illustration of the hierarchical softmax binary tree. The leaf nodes in white are words in the vocabulary. The gray inner nodes carry information on the probabilities of reaching its child nodes. One path starting from the root to the leaf $w\\_i$. $n(w\\_i, j)$ denotes the j-th node on this path. (Image source:\nword2vec Parameter Learning Explained\n)\nEach word $w_i$ has a unique path from the root down to its corresponding leaf. The probability of picking this word is equivalent to the probability of taking this path from the root down through the tree branches. Since we know the embedding vector $v_n$ of the internal node $n$, the probability of getting the word can be computed by the product of taking left or right turn at every internal node stop.\nAccording to Fig. 3, the probability of one node is ($\\sigma$ is the sigmoid function):\n$$\n\\begin{align}\np(\\text{turn right} \\to \\dots w_I \\vert n) &= \\sigma({v'_n}^{\\top} v_{w_I})\\\\\np(\\text{turn left } \\to \\dots w_I \\vert n) &= 1 - p(\\text{turn right} \\vert n) = \\sigma(-{v'_n}^{\\top} v_{w_I})\n\\end{align}\n$$\nThe final probability of getting a context word $w_O$ given an input word $w_I$ is:\n$$\np(w_O \\vert w_I) = \\prod_{k=1}^{L(w_O)} \\sigma(\\mathbb{I}_{\\text{turn}}(n(w_O, k), n(w_O, k+1)) \\cdot {v'_{n(w_O, k)}}^{\\top} v_{w_I})\n$$\nwhere $L(w_O)$ is the depth of the path leading to the word $w_O$ and $\\mathbb{I}_{\\text{turn}}$ is a specially indicator function which returns 1 if $n(w_O, k+1)$ is the left child of $n(w_O, k)$ otherwise -1. The internal nodes’ embeddings are learned during the model training. The tree structure helps greatly reduce the complexity of the denominator estimation from O(V) (vocabulary size) to O(log V) (the depth of the tree) at the training time. However, at the prediction time, we still to compute the probability of every word and pick the best, as we don’t know which leaf to reach for in advance.\nA good tree structure is crucial to the model performance. Several handy principles are: group words by frequency like what is implemented by Huffman tree for simple speedup; group similar words into same or close branches (i.e. use predefined word clusters, WordNet).\nCross Entropy\n#\nAnother approach completely steers away from the softmax framework. Instead, the loss function measures the cross entropy between the predicted probabilities $p$ and the true binary labels $\\mathbf{y}$.\nFirst, let’s recall that the cross entropy between two distributions $p$ and $q$ is measured as $ H(p, q) = -\\sum_x p(x) \\log q(x) $. In our case, the true label $y_i$ is 1 only when $w_i$ is the output word; $y_j$ is 0 otherwise. The loss function $\\mathcal{L}_\\theta$ of the model with parameter config $\\theta$ aims to minimize the cross entropy between the prediction and the ground truth, as lower cross entropy indicates high similarity between two distributions.\n$$\n\\mathcal{L}_\\theta = - \\sum_{i=1}^V y_i \\log p(w_i | w_I) = - \\log p(w_O \\vert w_I)\n$$\nRecall that,\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nTherefore,\n$$\n\\mathcal{L}_{\\theta} \n= - \\log \\frac{\\exp({v'_{w_O}}^{\\top}{v_{w_I}})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top}{v_{w_I} })}\n= - {v'_{w_O}}^{\\top}{v_{w_I} } + \\log \\sum_{i=1}^V \\exp({v'_{w_i} }^{\\top}{v_{w_I}})\n$$\nTo start training the model using back-propagation with SGD, we need to compute the gradient of the loss function. For simplicity, let’s label $z_{IO} = {v’_{w_O}}^{\\top}{v_{w_I}}$.\n$$\n\\begin{align}\n\\nabla_\\theta \\mathcal{L}_{\\theta}\n&= \\nabla_\\theta\\big( - z_{IO} + \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\ \n&= - \\nabla_\\theta z_{IO} + \\nabla_\\theta \\big( \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\\n&= - \\nabla_\\theta z_{IO} + \\frac{1}{\\sum_{i=1}^V e^{z_{Ii}}} \\sum_{i=1}^V e^{z_{Ii}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V \\frac{e^{z_{Ii}}}{\\sum_{i=1}^V e^{z_{Ii}}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V p(w_i \\vert w_I) \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta z_{Ii}\n\\end{align}\n$$\nwhere $Q(\\tilde{w})$ is the distribution of noise samples.\nAccording to the formula above, the correct output word has a positive reinforcement according to the first term (the larger $\\nabla_\\theta z_{IO}$ the better loss we have), while other words have a negative impact as captured by the second term.\nHow to estimate $\\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta {v’_{w_i}}^{\\top}{v_{w_I}}$ with a sample set of noise words rather than scanning through the entire vocabulary is the key of using cross-entropy-based sampling approach.\nNoise Contrastive Estimation (NCE)\n#\nThe Noise Contrastive Estimation (NCE) metric intends to differentiate the target word from noise samples using a logistic regression classifier (\nGutmann and Hyvärinen, 2010\n).\nGiven an input word $w_I$, the correct output word is known as $w$. In the meantime, we sample $N$ other words from the noise sample distribution $Q$, denoted as $\\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N \\sim Q$. Let’s label the decision of the binary classifier as $d$ and $d$$ can only take a binary value.\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) + \\sum_{i=1, \\tilde{w}_i \\sim Q}^N \\log p(d=0|\\tilde{w}_i, w_I) ]\n$$\nWhen $N$ is big enough, according to\nthe Law of large numbers\n,\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) +  N\\mathbb{E}_{\\tilde{w}_i \\sim Q} \\log p(d=0|\\tilde{w}_i, w_I)]\n$$\nTo compute the probability $p(d=1 \\vert w, w_I)$, we can start with the joint probability $p(d, w \\vert w_I)$. Among $w, \\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N$, we have 1 out of (N+1) chance to pick the true word $w$, which is sampled from the conditional probability $p(w \\vert w_I)$; meanwhile, we have N out of (N+1) chances to pick a noise word, each sampled from $q(\\tilde{w}) \\sim Q$. Thus,\n$$\np(d, w | w_I) = \n  \\begin{cases}\n  \\frac{1}{N+1} p(w \\vert w_I) & \\text{if } d=1 \\\\\n  \\frac{N}{N+1} q(\\tilde{w}) & \\text{if } d=0\n  \\end{cases}\n$$\nThen we can figure out $p(d=1 \\vert w, w_I)$ and $p(d=0 \\vert w, w_I)$:\n$$\n\\begin{align}\np(d=1 \\vert w, w_I) \n&= \\frac{p(d=1, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\n$$\n\\begin{align}\np(d=0 \\vert w, w_I) \n&= \\frac{p(d=0, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{Nq(\\tilde{w})}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\nFinally the loss function of NCE’s binary classifier becomes:\n$$\n\\begin{align}\n\\mathcal{L}_\\theta \n& = - [ \\log p(d=1 \\vert w, w_I) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log p(d=0|\\tilde{w}_i, w_I)] \\\\\n& = - [ \\log \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{p(w \\vert w_I) + Nq(\\tilde{w}_i)}]\n\\end{align}\n$$\nHowever, $p(w \\vert w_I)$ still involves summing up the entire vocabulary in the denominator. Let’s label the denominator as a partition function of the input word, $Z(w_I)$. A common assumption is $Z(w) \\approx 1$ given that we expect the softmax output layer to be normalized (\nMinh and Teh, 2012\n). Then the loss function is simplified to:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\frac{\\exp({v'_w}^{\\top}{v_{w_I}})}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w}_i)}]\n$$\nThe noise distribution $Q$ is a tunable parameter and we would like to design it in a way so that:\nintuitively it should be very similar to the real data distribution; and\nit should be easy to sample from.\nFor example, the sampling implementation (\nlog_uniform_candidate_sampler\n) of NCE loss in tensorflow assumes that such noise samples follow a log-uniform distribution, also known as\nZipfian’s law\n. The probability of a given word in logarithm is expected to be reversely proportional to its rank, while high-frequency words are assigned with lower ranks. In this case, $q(\\tilde{w}) = \\frac{1}{ \\log V}(\\log (r_{\\tilde{w}} + 1) - \\log r_{\\tilde{w}})$, where $r_{\\tilde{w}} \\in [1, V]$ is the rank of a word by frequency in descending order.\nNegative Sampling (NEG)\n#\nThe Negative Sampling (NEG) proposed by Mikolov et al. (\n2013\n) is a simplified variation of NCE loss. It is especially famous for training Google’s\nword2vec\nproject. Different from NCE Loss which attempts to approximately maximize the log probability of the softmax output, negative sampling did further simplification because it focuses on learning high-quality word embedding rather than modeling the word distribution in natural language.\nNEG approximates the binary classifier’s output with sigmoid functions as follows:\n$$\n\\begin{align}\np(d=1 \\vert w_, w_I) &= \\sigma({v'_{w}}^\\top v_{w_I}) \\\\\np(d=0 \\vert w, w_I) &= 1 - \\sigma({v'_{w}}^\\top v_{w_I}) = \\sigma(-{v'_{w}}^\\top v_{w_I})\n\\end{align}\n$$\nThe final NCE loss function looks like:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\sigma({v'_{w}}^\\top v_{w_I}) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\sigma(-{v'_{\\tilde{w}_i}}^\\top v_{w_I})]\n$$\nOther Tips for Learning Word Embedding\n#\nMikolov et al. (\n2013\n) suggested several helpful practices that could result in good word embedding learning outcomes.\nSoft sliding window\n. When pairing the words within the sliding window, we could assign less weight to more distant words. One heuristic is — given a maximum window size parameter defined, $s_{\\text{max}}$, the actual window size is randomly sampled between 1 and $s_{\\text{max}}$ for every training sample. Thus, each context word has the probability of 1/(its distance to the target word) being observed, while the adjacent words are always observed.\nSubsampling frequent words\n. Extremely frequent words might be too general to differentiate the context (i.e. think about stopwords). While on the other hand, rare words are more likely to carry distinct information. To balance the frequent and rare words, Mikolov et al. proposed to discard words $w$ with probability $1-\\sqrt{t/f(w)}$ during sampling. Here $f(w)$ is the word frequency and $t$ is an adjustable threshold.\nLearning phrases first\n. A phrase often stands as a conceptual unit, rather than a simple composition of individual words. For example, we cannot really tell “New York” is a city name even we know the meanings of “new” and “york”. Learning such phrases first and treating them as word units before training the word embedding model improves the outcome quality. A simple data-driven approach is based on unigram and bigram counts: $s_{\\text{phrase}} = \\frac{C(w_i w_j) - \\delta}{ C(w_i)C(w_j)}$, where $C(.)$ is simple count of an unigram $w_i$ or bigram $w_i w_j$ and $\\delta$ is a discounting threshold to prevent super infrequent words and phrases. Higher scores indicate higher chances of being phrases. To form phrases longer than two words, we can scan the vocabulary multiple times with decreasing score cutoff values.\nGloVe: Global Vectors\n#\nThe Global Vector (GloVe) model proposed by Pennington et al. (\n2014\n) aims to combine the count-based matrix factorization and the context-based skip-gram model together.\nWe all know the counts and co-occurrences can reveal the meanings of words. To distinguish from $p(w_O \\vert w_I)$ in the context of a word embedding word, we would like to define the co-ocurrence probability as:\n$$\np_{\\text{co}}(w_k \\vert w_i) = \\frac{C(w_i, w_k)}{C(w_i)}\n$$\n$C(w_i, w_k)$ counts the co-occurrence between words $w_i$ and $w_k$.\nSay, we have two words, $w_i$=“ice” and $w_j$=“steam”. The third word $\\tilde{w}_k$=“solid” is related to “ice” but not “steam”, and thus we expect $p_{\\text{co}}(\\tilde{w}_k \\vert w_i)$ to be much larger than $p_{\\text{co}}(\\tilde{w}_k \\vert w_j)$ and therefore $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ to be very large. If the third word $\\tilde{w}_k$ = “water” is related to both or $\\tilde{w}_k$ = “fashion” is unrelated to either of them, $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ is expected to be close to one.\nThe intuition here is that the word meanings are captured by the ratios of co-occurrence probabilities rather than the probabilities themselves. The global vector models the relationship between two words regarding to the third context word as:\n$$\nF(w_i, w_j, \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nFurther, since the goal is to learn meaningful word vectors, $F$ is designed to be a function of the linear difference between two words $w_i - w_j$:\n$$\nF((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nWith the consideration of $F$ being symmetric between target words and context words, the final solution is to model $F$ as an\nexponential\nfunction. Please read the original paper (\nPennington et al., 2014\n) for more details of the equations.\n$$\n\\begin{align}\nF({w_i}^\\top \\tilde{w}_k) &= \\exp({w_i}^\\top \\tilde{w}_k) = p_{\\text{co}}(\\tilde{w}_k \\vert w_i) \\\\\nF((w_i - w_j)^\\top \\tilde{w}_k) &= \\exp((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{\\exp(w_i^\\top \\tilde{w}_k)}{\\exp(w_j^\\top \\tilde{w}_k)} = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n\\end{align}\n$$\nFinally,\n$$\n{w_i}^\\top \\tilde{w}_k = \\log p_{\\text{co}}(\\tilde{w}_k \\vert w_i) = \\log \\frac{C(w_i, \\tilde{w}_k)}{C(w_i)} = \\log C(w_i, \\tilde{w}_k) - \\log C(w_i)\n$$\nSince the second term $-\\log C(w_i)$ is independent of $k$, we can add bias term $b_i$ for $w_i$ to capture $-\\log C(w_i)$. To keep the symmetric form, we also add in a bias $\\tilde{b}_k$ for $\\tilde{w}_k$.\n$$\n\\log C(w_i, \\tilde{w}_k) = {w_i}^\\top \\tilde{w}_k + b_i + \\tilde{b}_k\n$$\nThe loss function for the GloVe model is designed to preserve the above formula by minimizing the sum of the squared errors:\n$$\n\\mathcal{L}_\\theta = \\sum_{i=1, j=1}^V f(C(w_i,w_j)) ({w_i}^\\top \\tilde{w}_j + b_i + \\tilde{b}_j - \\log C(w_i, \\tilde{w}_j))^2\n$$\nThe weighting schema $f(c)$ is a function of the co-occurrence of $w_i$ and $w_j$ and it is an adjustable model configuration. It should be close to zero as $c \\to 0$; should be non-decreasing as higher co-occurrence should have more impact; should saturate when $c$ become extremely large. The paper proposed the following weighting function.\n$$\nf(c) = \n  \\begin{cases}\n  (\\frac{c}{c_{\\max}})^\\alpha & \\text{if } c < c_{\\max} \\text{, } c_{\\max} \\text{ is adjustable.} \\\\\n  1 & \\text{if } \\text{otherwise}\n  \\end{cases}\n$$\nExamples: word2vec on “Game of Thrones”\n#\nAfter reviewing all the theoretical knowledge above, let’s try a little experiment in word embedding extracted from “the Games of Thrones corpus”. The process is super straightforward using\ngensim\n.\nStep 1: Extract words\nimport\nsys\nfrom\nnltk.corpus\nimport\nstopwords\nfrom\nnltk.tokenize\nimport\nsent_tokenize\nSTOP_WORDS\n=\nset(stopwords\n.\nwords(\n'english'\n))\ndef\nget_words\n(txt):\nreturn\nfilter(\nlambda\nx: x\nnot\nin\nSTOP_WORDS,\nre\n.\nfindall(\nr\n'\\b(\\w+)\\b'\n, txt)\n)\ndef\nparse_sentence_words\n(input_file_names):\n\"\"\"Returns a list of a list of words. Each sublist is a sentence.\"\"\"\nsentence_words\n=\n[]\nfor\nfile_name\nin\ninput_file_names:\nfor\nline\nin\nopen(file_name):\nline\n=\nline\n.\nstrip()\n.\nlower()\nline\n=\nline\n.\ndecode(\n'unicode_escape'\n)\n.\nencode(\n'ascii'\n,\n'ignore'\n)\nsent_words\n=\nmap(get_words, sent_tokenize(line))\nsent_words\n=\nfilter(\nlambda\nsw: len(sw)\n>\n1\n, sent_words)\nif\nlen(sent_words)\n>\n1\n:\nsentence_words\n+=\nsent_words\nreturn\nsentence_words\n# You would see five .txt files after unzip 'a_song_of_ice_and_fire.zip'\ninput_file_names\n=\n[\n\"001ssb.txt\"\n,\n\"002ssb.txt\"\n,\n\"003ssb.txt\"\n,\n\"004ssb.txt\"\n,\n\"005ssb.txt\"\n]\nGOT_SENTENCE_WORDS\n=\nparse_sentence_words(input_file_names)\nStep 2: Feed a word2vec model\nfrom\ngensim.models\nimport\nWord2Vec\n# size: the dimensionality of the embedding vectors.\n# window: the maximum distance between the current and predicted word within a sentence.\nmodel\n=\nWord2Vec(GOT_SENTENCE_WORDS, size\n=\n128\n, window\n=\n3\n, min_count\n=\n5\n, workers\n=\n4\n)\nmodel\n.\nwv\n.\nsave_word2vec_format(\n\"got_word2vec.txt\"\n, binary\n=\nFalse\n)\nStep 3: Check the results\nIn the GoT word embedding space, the top similar words to “king” and “queen” are:\nmodel.most_similar('king', topn=10)\n(word, similarity with ‘king’)\nmodel.most_similar('queen', topn=10)\n(word, similarity with ‘queen’)\n(‘kings’, 0.897245)\n(‘cersei’, 0.942618)\n(‘baratheon’, 0.809675)\n(‘joffrey’, 0.933756)\n(‘son’, 0.763614)\n(‘margaery’, 0.931099)\n(‘robert’, 0.708522)\n(‘sister’, 0.928902)\n(’lords’, 0.698684)\n(‘prince’, 0.927364)\n(‘joffrey’, 0.696455)\n(‘uncle’, 0.922507)\n(‘prince’, 0.695699)\n(‘varys’, 0.918421)\n(‘brother’, 0.685239)\n(’ned’, 0.917492)\n(‘aerys’, 0.684527)\n(‘melisandre’, 0.915403)\n(‘stannis’, 0.682932)\n(‘robb’, 0.915272)\nCited as:\n@article{weng2017wordembedding,\n  title   = \"Learning word embedding\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-15-word-embedding/\"\n}\nReferences\n#\n[1] Tensorflow Tutorial\nVector Representations of Words\n.\n[2]\n“Word2Vec Tutorial - The Skip-Gram Model”\nby Chris McCormick.\n[3]\n“On word embeddings - Part 2: Approximating the Softmax”\nby Sebastian Ruder.\n[4] Xin Rong.\nword2vec Parameter Learning Explained\n[5] Mikolov, Tomas, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[6] Frederic Morin and Yoshua Bengio.\n“Hierarchical Probabilistic Neural Network Language Model.”\nAistats. Vol. 5. 2005.\n[7] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nProc. Intl. Conf. on Artificial Intelligence and Statistics. 2010.\n[8] Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Distributed representations of words and phrases and their compositionality.”\nAdvances in neural information processing systems. 2013.\n[9] Tomas Mikolov, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[10] Marco Baroni, Georgiana Dinu, and Germán Kruszewski.\n“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”\nACL (1). 2014.\n[11] Jeffrey Pennington, Richard Socher, and Christopher Manning.\n“Glove: Global vectors for word representation.”\nProc. Conf. on empirical methods in natural language processing (EMNLP). 2014.",
            "metadata": {
              "title": "Learning Word Embedding | Lil'Log",
              "description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "keywords": "nlp, language-model",
              "author": "Lilian Weng",
              "og:title": "Learning Word Embedding",
              "og:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
              "twitter:card": "summary",
              "twitter:title": "Learning Word Embedding",
              "twitter:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "article:section": "posts",
              "article:published_time": "2017-10-15T00:00:00+00:00",
              "article:modified_time": "2017-10-15T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/3e47ba682561/code/body-000.txt",
                "chars": 1066,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-001.txt",
                "chars": 323,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-002.txt",
                "chars": 233,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "bytes": 179202,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-e21a214c6127867b9495.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "bytes": 183003,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-0f5bdb5a435b843e8180.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "bytes": 18594,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-f369233bacf831326935.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://arxiv.org/pdf/1301.3781.pdf",
                "label": "Mikolov et al., 2013",
                "type": "a"
              },
              {
                "href": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "label": "2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1411.2738.pdf",
                "label": "word2vec Parameter Learning Explained",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "label": "Gutmann and Hyvärinen, 2010",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "the Law of large numbers",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "label": "Minh and Teh, 2012",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/candidate_sampling_ops.py",
                "label": "log_uniform_candidate_sampler",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Zipf%27s_law",
                "label": "Zipfian’s law",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "label": "2013",
                "type": "a"
              },
              {
                "href": "https://code.google.com/archive/p/word2vec/",
                "label": "word2vec",
                "type": "a"
              },
              {
                "href": "http://www.aclweb.org/anthology/D14-1162",
                "label": "2014",
                "type": "a"
              },
              {
                "href": "https://radimrehurek.com/gensim/models/word2vec.html",
                "label": "gensim",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/word2vec",
                "label": "Vector Representations of Words",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/",
                "label": "“Word2Vec Tutorial - The Skip-Gram Model”",
                "type": "a"
              },
              {
                "href": "http://ruder.io/word-embeddings-softmax/",
                "label": "“On word embeddings - Part 2: Approximating the Softmax”",
                "type": "a"
              },
              {
                "href": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "label": "“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:36Z",
            "source_url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3781.pdf",
                "bytes": 228716,
                "reused": false,
                "local_path": "papers/repair/1e8e84311c23b0346b07.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T18:04:55Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1411.2738.pdf",
                "bytes": 816833,
                "reused": false,
                "local_path": "papers/repair/b37b38f8ebbcb26bcb27.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "bytes": 633631,
                "reused": false,
                "local_path": "papers/repair/4e238b55e8eb6f9638d6.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "bytes": 332740,
                "reused": false,
                "local_path": "papers/repair/d0eae5ee0263039f0b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "bytes": 111997,
                "reused": false,
                "local_path": "papers/repair/32de112509f802883250.pdf"
              },
              {
                "status": "ok",
                "url": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "bytes": 152976,
                "reused": false,
                "local_path": "papers/repair/c28d8258a40dec5bef84.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25736,
            "expected_body_images": 3,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/3e47ba682561/pages/source.html",
            "local_html": "attachments/3e47ba682561/pages/article.html",
            "body_base_path": "attachments/3e47ba682561/pages/",
            "body_markdown_path": "attachments/3e47ba682561/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
          "status": "partial",
          "article_id": "2cf34df8cd69",
          "local_path": "series-follow/1602/repair/755e367caba0c679040a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
              "bytes": 661245,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7efefadad7e7dd1bd368.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
              "bytes": 173461,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ef8c4099815df32d696d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
              "bytes": 192230,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a2c96b21ecb7e2fe5261.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
              "bytes": 180723,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9d359913e38042c21f68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
              "bytes": 131727,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/658614a9a3e7c1d7b935.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
              "bytes": 337530,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/eaf24c5188513fae50ed.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
              "bytes": 124437,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ff31b70ac499e0b32939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
              "bytes": 865287,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2e1a4cd54853b0630bf6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
              "bytes": 553919,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7826a791054014f6fcfb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
              "bytes": 260572,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d37427b8abf7df28ba56.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
              "bytes": 198348,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1debd5c40323ec83577c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
              "bytes": 290218,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/76ae01d2ac36750aac13.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
              "bytes": 145311,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cb02352f1fcc5796b966.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
              "bytes": 201245,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4a06ae2c872925f426c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
              "bytes": 329545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/592734de78cf202658cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
              "bytes": 244182,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f4f90d0aeb9507c08585.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Build an Open-Domain Question Answering System?",
            "keywords": "开放域问答,检索,ODQA",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "publish_date": "2020-10",
            "corpus_stage": "预训练/SFT",
            "notes": "开放域问答系统构建综述",
            "id": "2cf34df8cd69",
            "collected_at": "2026-10-02T14:13:11",
            "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
            "body_markdown": "[Updated on 2020-11-12: add\nan example\non closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.\nDisclaimers given so many papers in the wild:\nAssume we have access to a powerful pretrained\nlanguage model\n.\nWe do not cover how to use structured knowledge base (e.g. Freebase, WikiData) here.\nWe only focus on a single-turn QA instead of a multi-turn conversation style QA.\nWe mostly focus on QA models that contain neural networks, specially Transformer-based language models.\nI admit that I missed a lot of papers with architectures designed specifically for QA tasks between 2017-2019😔\nWhat is Open-Domain Question Answering?\n#\nOpen-domain Question Answering (ODQA)\nis a type of language tasks, asking a model to produce answers to factoid questions in natural language. The true answer is objective, so it is simple to evaluate model performance.\nFor example,\nQuestion: What did Albert Einstein win the Nobel Prize for?\nAnswer: The law of the photoelectric effect.\nThe “open-domain” part refers to the lack of the relevant context for any arbitrarily asked factual question. In the above case, the model only takes as the input the question but no article about “why Einstein didn’t win a Nobel Prize for the theory of relativity” is provided, where the term “the law of the photoelectric effect” is likely mentioned. In the case when both the question and the context are provided, the task is known as\nReading comprehension (RC)\n.\nAn ODQA model may work with or without\naccess to an external source of knowledge\n(e.g. Wikipedia) and these two conditions are referred to as\nopen-book\nor\nclosed-book\nquestion answering, respectively.\nWhen considering different types of open-domain questions, I like the classification by\nLewis, et al., 2020\n, in increasing order of difficulty:\nA model is able to correctly memorize and respond with the answer to a question that has been seen at training time.\nA model is able to answer novel questions at test time and choose an answer from the set of answers it has seen during training.\nA model is able to answer novel questions which have answers not contained in the training dataset.\nOverview of three frameworks discussed in this post.\nNotation\n#\nGiven a question $x$ and a ground truth answer span $y$, the context passage containing the true answer is labelled as $z \\in \\mathcal{Z}$, where $\\mathcal{Z}$ is an external knowledge corpus. Wikipedia is a common choice for such an external knowledge source.\nConcerns of QA data fine-tuning\n#\nBefore we dive into the details of many models below. I would like to point out one concern of fine-tuning a model with common QA datasets, which appears as one fine-tuning step in several ODQA models. It could be concerning, because there is a significant overlap between questions in the train and test sets in several public QA datasets.\nLewis, et al., (2020)\n(\ncode\n) found that 58-71% of test-time answers are also present somewhere in the training sets and 28-34% of test-set questions have a near-duplicate paraphrase in their corresponding training sets. In their experiments, several models performed notably worse when duplicated or paraphrased questions were removed from the training set.\nOpen-book QA: Retriever-Reader\n#\nGiven a factoid question, if a language model has no context or is not big enough to memorize the context which exists in the training dataset, it is unlikely to guess the correct answer. In an open-book exam, students are allowed to refer to external resources like notes and books while answering test questions. Similarly, a ODQA system can be paired with a rich knowledge base to identify relevant documents as evidence of answers.\nWe can decompose the process of finding answers to given questions into two stages,\nFind the related context in an external repository of knowledge;\nProcess the retrieved context to\nextract\nan answer.\nThe retriever-reader QA framework combines information retrieval with machine reading comprehension.\nSuch a retriever + reader framework was first proposed in\nDrQA\n(“Document retriever Question-Answering” by\nChen et al., 2017\n;\ncode\n). The retriever and the reader components can be set up and trained independently, or jointly trained\nend-to-end\n.\nRetriever Model\n#\nTwo popular approaches for implementing the retriever is to use the information retrieval (IR) system that depends on (1) the classic non-learning-based\nTF-IDF\nfeatures (“classic IR”) or (2) dense embedding vectors of text produced by neural networks (“neural IR”).\nClassic IR\n#\nDrQA\n(\nChen et al., 2017\n) adopts an efficient non-learning-based search engine based on the\nvector space model\n. Every query and document is modelled as a bag-of-word vector, where each term is weighted by TF-IDF (term frequency $\\times$ inverse document frequency).\n$$\n\\begin{aligned}\n\\text{tf-idf}(t, d, \\mathcal{D}) &= \\text{tf}(t, d) \\times \\text{idf}(t, \\mathcal{D}) \\\\\n\\text{tf}(t, d) &= \\log(1 + \\text{freq}(t, d)) \\\\\n\\text{idf}(t, \\mathcal{D}) &= \\log \\Big( \\frac{\\vert\\mathcal{D}\\vert}{\\vert d\\in\\mathcal{D}: t\\in d\\vert} \\Big)\n\\end{aligned}\n$$\nwhere $t$ is a unigram or bigram term in a document $d$ from a collection of documents $\\mathcal{D}$ . $\\text{freq}(t, d)$ measures how many times a term $t$ appears in $d$. Note that the term-frequency here includes bigram counts too, which is found to be very helpful because the local word order is taken into consideration via bigrams. As part of the implementation, DrQA maps the bigrams of $2^{24}$ bins using unsigned murmur3 hash.\nPrecisely, DrQA implemented Wikipedia as its knowledge source and this choice has became a default setting for many ODQA studies since then. The non-ML document retriever returns the top $k=5$ most relevant Wikipedia articles given a question.\nBERTserini\n(\nYang et al., 2019\n) pairs the open-source\nAnserini\nIR toolkit as the retriever with a fine-tuned pre-trained BERT model as the reader. The top $k$ documents ($k=10$) are retrieved via the\npost-v3.0\nbranch of Anserini with the query treated as a bag of words. The retrieved text segments are ranked by\nBM25\n, a classic TF-IDF-based retrieval scoring function. In terms of the effect of text granularity on performance, they found that paragraph retrieval > sentence retrieval > article retrieval.\nAn illustration of BERTserini architecture. (Image source:\nYang et al., 2019\n)\nElasticSearch + BM25\nis used by the\nMulti-passage BERT\nQA model (\nWang et al., 2019\n). They found that splitting articles into passages with the length of 100 words by\nsliding window\nbrings 4% improvements, since splitting documents into passages without overlap may cause some near-boundary evidence to lose useful contexts.\nNeural IR\n#\nThere is a long history in learning a low-dimensional representation of text, denser than raw term-based vectors (\nDeerwester et al., 1990\n;\nYih, et al., 2011\n). Dense representations can be learned through matrix decomposition or some neural network architectures (e.g. MLP, LSTM, bidirectional LSTM, etc). When involving neural networks, such approaches are referred to as “Neural IR”, Neural IR is a new category of methods for retrieval problems, but it is not necessary to perform better/superior than classic IR (\nLim, 2018\n).\nAfter the success of many large-scale\ngeneral language models\n, many QA models embrace the following approach:\n$$\nh_x = E_x(x)\\quad\nh_z = E_z(z)\\quad\n\\text{score}(x, z) = h_x^\\top h_z\n$$\nExtract the dense representations of a question $x$ and a context passage $z$ by feeding them into a language model;\nUse the dot-product of these two representations as the retrieval score to rank and select most relevant passages.\nORQA, REALM and DPR all use such a scoring function for context retrieval, which will be described in detail in a\nlater section\non the end-to-end QA model.\nAn extreme approach, investigated by\nDenSPI\n(“Dense-Sparse Phrase Index”;\nSeo et al., 2019\n), is to encode all the text in the knowledge corpus at the\nphrase\nlevel and then only rely on the retriever to identify the most relevant phrase as the predicted answer. In this way, the retriever+reader pipeline is reduced to only retriever. Of course, the index would be much larger and the retrieval problem is more challenging.\nDenSPI introduces a\nquery-agnostic\nindexable representation of document phrases. Precisely it encodes query-agnostic representations of text spans in Wikipedia offline and looks for the answer at inference time by performing nearest neighbor search. It can drastically speed up the inference time, because there is no need to re-encode documents for every new query, which is often required by a reader model.\nGiven a question $x$ and a fixed set of (Wikipedia) documents, $z_1, \\dots, z_K$ and each document $z_k$ contains $N_k$ words, $z_k = \\langle z_k^{(1)}, \\dots, z_k^{(N_k)}\\rangle$. An ODQA model is a scoring function $F$ for each candidate phrase span $z_k^{(i:j)}, 1 \\leq i \\leq j \\leq N_k$, such that the truth answer is the phrase with maximum score: $y = {\\arg\\max}_{k,i,j} F(x, z_k^{(i:j)})$.\nThe phrase representation $z_k^{(i:j)}$ combines both dense and sparse vectors, $z_k^{(i:j)} = [d_k^{(i:j)}, s_k^{(i:j)}] \\in \\mathbb{R}^{d^d + d^s}$ (note that $d^d \\ll d^s$):\nThe dense vector $d_k^{(i:j)}$ is effective for encoding local\nsyntactic\nand\nsemantic\ncues, as what can be learned by a pretrained language model.\nThe sparse vector $s_k^{(i:j)}$ is superior at encoding precise\nlexical\ninformation. The sparse vector is term-frequency-based encoding. DenSPI uses 2-gram term-frequency same as DrQA, resulting a highly sparse representation ($d^s \\approx 16$M)\nThe dense vector $d^{(i:j)}$ is further decomposed into three parts, $d^{(i:j)} = [a_i, b_j, c_{ij}] \\in \\mathbb{R}^{2d^b + 1}$ where $2d^b + 1 = d^d$. All three components are learned based on different columns of the fine-tuned BERT representations.\nA vector $a_i$ encodes the\nstart\nposition for the $i$-th word of the document;\nA vector $b_j$ encodes the\nend\nposition for the $j$-th word of the document;\nA scalar $c_{ij}$ measures the\ncoherency\nbetween the start and the end vectors, helping avoid non-constituent phrases during inference.\nFor all possible $(i,j,k)$ tuples where $j-i < J$, the text span embeddings are precomputed and stored as a\nphrase index\n. The maximum span length $J$ is a predefined scalar constant.\nAn illustration of Dense-Sparse Phrase Index (DenSPI) architecture. (Image source:\nSeo et al., 2019\n)\nAt the inference time, the question is mapped into the same vector space $x=[d’, s’] \\in \\mathbb{R}^{d^d + d^s}$, where the dense vector $d’$ is extracted from the BERT embedding of the special\n[CLS]\nsymbol. The same BERT model is shared for encoding both questions and phrases. The final answer is predicted by $k^*, i^*, j^* = \\arg\\max x^\\top z_k^{(i:j)}$.\nReader Model\n#\nThe reader model learns to solve the reading comprehension task — extract an answer for a given question from a given context document. Here we only discuss approaches for machine comprehension using neural networks.\nBi-directional LSTM\n#\nThe reader model for answer detection of\nDrQA\n(\nChen et al., 2017\n) is a 3-layer bidirectional LSTM with hidden size 128. Every relevant paragraph of retrieved Wikipedia articles is encoded by a sequence of feature vector, $\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m \\}$. Each feature vector $\\hat{\\mathbf{z}}_i \\in \\mathbb{R}^{d_z}$ is expected to capture useful contextual information around one token $z_i$. The feature consists of several categories of features:\nWord embeddings: A 300d\nGlove\nword embedding trained from 800B Web crawl data, $f_\\text{embed} = E_g(z_i)$.\nExact match: Whether a word $z_i$ appears in the question $x$, $f_\\text{match} = \\mathbb{I}(z_i \\in x)$.\nToken features: This includes POS (part-of-speech) tagging, NER (named entity recognition), and TF (term-frequency), $f_\\text{token}(z_i) = (\\text{POS}(z_i), \\text{NER}(z_i), \\text{TF}(z_i))$.\nAligned question embedding: The attention score $y_{ij}$ is designed to capture inter-sentence matching and similarity between the paragraph token $z_i$ and the question word $x_j$. This feature adds soft alignments between similar but non-identical words.\n$$\n\\begin{aligned}\nf_\\text{align}(z_i) &= \\sum_j y_{i,j} E_g(x_j) \\\\ \ny_{i,j} &= \\frac{\\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_j)) )}{\\sum_{j'} \\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_{j'})) ) }\n\\end{aligned}\n$$\nwhere $\\alpha$ is a single dense layer with ReLU and $E_g(.)$ is the glove word embedding.\nThe feature vector of a paragraph of $m$ tokens is fed into LSTM to obtain the final paragraph vectors:\n$$\n\\begin{aligned}\n\\mathbf{z} = \\{\\mathbf{z}_1, \\dots, \\mathbf{z}_m\\} &= \\text{LSTM}(\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m\\}) \\\\\n\\text{where } \\tilde{\\mathbf{z}}_i &= \\{f_\\text{embed}, f_\\text{match}, f_\\text{token}, f_\\text{align}\\}\n\\end{aligned}\n$$\nThe question is encoded as a weighted sum of the embeddings of every word in the question:\n$$\n\\mathbf{x} = \\sum_j b_j E(x_j) \\quad b_j = \\text{softmax}(\\mathbf{w}^\\top E(x_j))\n$$\nwhere $\\mathbf{w}$ is a weight vector to learn.\nOnce the feature vectors are constructed for the question and all the related paragraphs, the reader needs to predict the probabilities of each position in a paragraph to be the start and the end of an answer span, $p_\\text{start}(i_s)$ and $p_\\text{end}(i_s)$, respectively. Across all the paragraphs, the optimal span is returned as the final answer with maximum $p_\\text{start}(i_s)  \\times p_\\text{end}(i_e) $.\n$$\n\\begin{aligned}\np_\\text{start}(i_s) \\propto \\exp(\\mathbf{z}_{i_s} \\mathbf{W}_s \\mathbf{x}) \\\\ \np_\\text{end}(i_e) \\propto \\exp(\\mathbf{z}_{i_e} \\mathbf{W}_e \\mathbf{x}) \\\\\n\\text{ s.t. } i_s \\leq i_e \\leq i_s + 15\n\\end{aligned}\n$$\nwhere $\\mathbf{W}_s$ and $\\mathbf{W}_e$ are learned parameters.\nBERT-universe\n#\nFollowing the success of\nBERT\n(\nDevlin et al., 2018\n), many QA models develop the machine comprehension component based on BERT. Let’s define the BERT model as a function that can take one or multiple strings (concatenated by\n[SEP]\n) as input and outputs a set of BERT encoding vectors for the special\n[CLS]\ntoken and every input token:\n$$\n\\text{BERT}(s_1, s_2, \\dots) = [\\mathbf{h}^\\texttt{[CLS]}, \\mathbf{h}^{(1)}, \\mathbf{h}^{(2)}, \\dots]\n$$\nwhere $\\mathbf{h}^\\texttt{[CLS]}$ is the embedding vector for the special\n[CLS]\ntoken and $\\mathbf{h}^{(i)}$ is the embedding vector for the $i$-th token.\nTo use BERT for reading comprehension, it learns two additional weights, $\\mathbf{W}_s$ and $\\mathbf{W}_e$, and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_s)$ and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_e)$ define two probability distributions of start and end position of the predicted span per token.\nBERTserini\n(\nYang et al., 2019\n) utilizes a pre-trained BERT model to work as the reader. Their experiments showed that\nfine-tuning\npretrained BERT with SQuAD is sufficient to achieve high accuracy in identifying answer spans.\nHow BERT is used to solve question-answering tasks. (Image source:\nDevlin et al., 2018\n)\nThe key difference of the BERTserini reader from the original BERT is: to allow comparison and aggregation of results from different segments, the final softmax layer over different answer spans is removed. The pre-trained BERT model is fine-tuned on the training set of SQuAD, where all inputs to the reader are padded to 384 tokens with the learning rate 3e-5.\nWhen ranking all the extracted answer spans, the retriever score (BM25) and the reader score (probability of token being the start position $\\times$ probability of the same token being the end position ) are combined via linear interpolation.\nThe original BERT normalizes the probability distributions of start and end position per token for every passage independently. Differently, the\nMulti-passage BERT\n(\nWang et al., 2019\n) normalizes answer scores across all the retrieved passages of one question\nglobally\n. Precisely, multi-passage BERT removes the final normalization layer per passage in BERT for QA (same as in BERTserini) and then adds a global\nsoftmax\nover all the word positions of all the passages. Global normalization makes the reader model more stable while pin-pointing answers from a large number of passages.\nIn addition, multi-passage BERT implemented an independent\npassage ranker\nmodel via another BERT model and the rank score for $(x, z)$ is generated by a\nsoftmax\nover the representation vectors of the first\n[CLS]\ntoken. The passage ranker brings in extra 2% improvements. Similar idea of re-ranking passages with BERT was discussed in\nNogueira & Cho, 2019\n, too.\nInterestingly,\nWang et al., 2019\nfound that\nexplicit inter-sentence matching\ndoes not seem to be critical for RC tasks with BERT; check the original paper for how the experiments were designed. One possible reason is that the multi-head self-attention layers in BERT has already embedded the inter-sentence matching.\nEnd-to-end Joint Training\n#\nThe retriever and reader components can be jointly trained. This section covers R^3, ORQA, REALM and DPR. There are a lot of common designs, such as BERT-based dense vectors for retrieval and the loss function on maximizing the marginal likelihood of obtaining true answers.\nThe retriever and reader models in the\nR^3\n(“Reinforced Ranker-Reader”;\nWang, et al., 2017\n) QA system are jointly trained via\nreinforcement learning\n. (Note that to keep the term consistent between papers in this section, the “ranker” model in the original R^3 paper is referred to as the “retriever” model here.) Both components are variants of\nMatch-LSTM\n, which relies on an attention mechanism to compute word similarities between the passage and question sequences.\nHow does the Match-LSTM module work?\nGiven a question $\\mathbf{X}$ of $d_x$ words and a passage $\\mathbf{Z}$ of $d_z$ words, both representations use fixed\nGlove\nword embeddings,\n$$\n\\begin{aligned}\n\\mathbf{H}^x &= \\text{BiLSTM}(\\mathbf{X}) \\in \\mathbb{R}^{l \\times d_x} \\\\\n\\mathbf{H}^z &= \\text{BiLSTM}(\\mathbf{Z}) \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{G} &= \\text{softmax}((\\mathbf{W}^g \\mathbf{H}^x + \\mathbf{b}^g \\otimes \\mathbf{e}_{d_x})^\\top \\mathbf{H}^z) \\in \\mathbb{R}^{d_x \\times d_z} & \\text{; an attention matrix}\\\\\n\\bar{\\mathbf{H}}^x &= \\mathbf{H}^x \\mathbf{G} \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{M} &= \\text{ReLU} \\Big( \\mathbf{W}^m \\begin{bmatrix}\n\\mathbf{H}^z \\\\\n\\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z \\odot \\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z - \\bar{\\mathbf{H}}^x\n\\end{bmatrix} \\Big) \\in \\mathbb{R}^{2l \\times d_z} \\\\\n\\mathbf{H}^m &= \\text{BiLSTM}(M) \\in \\mathbb{R}^{l \\times d_z}\n\\end{aligned}\n$$\nwhere $l$ is the hidden dimension of the bidirectional LSTM module. $\\mathbf{W}^g \\in \\mathbb{R}^{l\\times l}$, $\\mathbf{b}^g \\in \\mathbb{R}^l$, and $\\mathbf{W}^m \\in \\mathbb{R}^{2l \\times 4l}$ are parameters to learn. The operator $\\otimes \\mathbf{e}_{d_x}$ is the outer product to repeat the column vector $\\mathbf{b}^g$ $d_x$ times.\nThe ranker and reader components share the same Match-LSTM module with two separate prediction heads in the last layer, resulting in $\\mathbf{H}^\\text{rank}$ and $\\mathbf{H}^\\text{reader}$.\nThe overview of R^3 (reinforced ranker-reader) architecture. Both components share the same Match-LSTM module. (Image source:\nWang, et al., 2017\n)\nThe retriever runs a max-pooling operation per passage and then aggregates to output a probability of each passage entailing the answer.\n$$\n\\begin{aligned}\n\\mathbf{u}_i &= \\text{max-pooling}(\\mathbf{H}^\\text{rank}_i) \\in \\mathbb{R}^l \\\\\n\\mathbf{C} &= \\text{tanh}(\\mathbf{W}^c[\\mathbf{u}_1;\\dots;\\mathbf{u}_N] + \\mathbf{b}^c \\otimes \\mathbf{e}_N) \\in \\mathbb{R}^{l \\times n} \\\\\n\\gamma &= \\text{softmax}(\\mathbf{w}^c \\mathbf{C}) \\in \\mathbb{R}^n\n\\end{aligned}\n$$\nFinally, the retriever is viewed as a\npolicy\nto output action to sample a passage according to predicted $\\gamma$,\n$$\n\\pi(z \\vert x; \\theta^\\gamma) = \\gamma_z\n$$\nThe reader predicts the start position $\\beta^s$ and the end position $\\beta^e$ of the answer span. Two positions are computed in the same way, with independent parameters to learn. There are $V$ words in all the passages involved.\n$$\n\\begin{aligned}\n\\mathbf{H}^\\text{read} &= [\\mathbf{H}^\\text{read}_\\tau; \\mathbf{H}^\\text{read}_{\\text{neg}_1}; \\dots; \\mathbf{H}^\\text{read}_{\\text{neg}_n}] \\\\\n\\mathbf{F}^s &= \\text{tanh}(\\mathbf{W}^s \\mathbf{H}^\\text{read} + \\mathbf{b}^s \\otimes \\mathbf{e}_V) \\quad\n\\beta^s = \\text{softmax}(\\mathbf{w}^s \\mathbf{F}^s) \\in \\mathbb{R}^V \\\\\n\\mathbf{F}^e &= \\text{tanh}(\\mathbf{W}^e \\mathbf{H}^\\text{read} + \\mathbf{b}^e \\otimes \\mathbf{e}_V) \\quad\n\\beta^e = \\text{softmax}(\\mathbf{w}^e \\mathbf{F}^e) \\in \\mathbb{R}^V \\\\\nL(y \\vert z, x) &= -\\log(\\beta^s_{y_z^s})-\\log(\\beta^e_{y_z^e})\n\\end{aligned}\n$$\nwhere $y$ is the ground-truth answer and the passage $z$ is sampled by the retriever. $\\beta^s_{y_z^s}$ and $\\beta^s_{y_z^e}$ represent the probabilities of the start and end positions of $y$ in passage $z$.\nThe training objective for the end-to-end R^3 QA system is to minimize the negative log-likelihood of obtaining the correct answer $y$ given a question $x$,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= -\\mathbb{E}_{z\\sim\\pi(.\\vert x)} [L(y \\vert z, x)] \\\\\n\\nabla \\mathcal{J}(\\theta) \n&= - \\nabla_\\theta \\sum_z \\pi(z \\vert x) L(y \\vert z, x) \\\\\n&= - \\sum_z \\big( L(y \\vert z, x) \\nabla_\\theta\\pi(z \\vert x) + \\pi(z \\vert x) \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&= - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\color{red}{L(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)} + \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&\\approx - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\underbrace{\\color{red}{R(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)}}_\\text{REINFORCE} + \\nabla_\\theta L(y \\vert z, x) \\big)\n\\end{aligned}\n$$\nEssentially in training, given a passage $z$ sampled by the retriever, the reader is trained by gradient descent while the retriever is trained by\nREINFORCE\nusing $L(y \\vert z, x)$ as the reward function. However, $L(y \\vert z, x)$ is not bounded and may introduce a lot of variance. The paper replaces the reward with a customized scoring function by comparing the ground truth $y$ and the answer extracted by the reader $\\hat{y}$:\n$$\nR(y, \\hat{y} \\vert z) = \\begin{cases}\n2 & \\text{if } y = \\hat{y}\\\\\nf1(y, \\hat{y}) & \\text{if } y \\cap \\hat{y} = \\varnothing \\\\\n-1 & \\text{otherwise}\n\\end{cases}\n$$\nThe workflow of R^3 training process. (Image source:\nacl2020-openqa-tutorial/slides/part4\n)\nORQA\n(“Open-Retrieval Question-Answering”;\nLee et al., 2019\n) jointly learns a retriever + reader QA model to optimize marginal log-likelihood of obtaining correct answers in a supervised manner. No explicit “black-box” IR system is involved. Instead, it is capable of retrieving any text in an open corpus. During training, ORQA does not need ground-truth context passages (i.e. reading comprehension datasets) but only needs (question, answer) string pairs. Both retriever and reader components are based on BERT, but not shared.\nAn illustration of the retriever component in ORQA. (Image source: replotted based on one slide in\nacl2020-openqa-tutorial/slides/part5\n)\nAll the evidence blocks are ranked by a retrieval score, defined as the inner product of BERT embedding vectors of the\n[CLS]\ntoken of the question $x$ and the evidence block $z$. Note that the encoders for questions and context are independent.\n$$\n\\begin{aligned}\nh_x &= \\mathbf{W}_x \\text{BERT}_x(x)^{\\mathtt{[CLS]}} \\\\\nh_z &= \\mathbf{W}_z \\text{BERT}_z(z)^{\\mathtt{[CLS]}} \\\\\nS_\\text{retr}(z, x) &= h_x^\\top h_z\n\\end{aligned}\n$$\nThe retriever module is pretrained with\nInverse Cloze Task (ICT)\n, which is to predict the context given a sentence, opposite to the standard\nCloze Task\n. The ICT objective is to maximize the retrieval score of the correct context $z$ given a random sentence $x$:\n$$\nL_\\text{ICT} = p_\\text{early}(z \\vert x) = \\frac{\\exp(S_\\text{retr}(z, x))}{\\sum_{z'\\in\\text{BATCH}(\\mathcal{Z})} \\exp(S_\\text{retr}(z', x))}\n$$\nwhere $\\text{BATCH}(\\mathcal{Z})$ is the set of evidence blocks in the same batch used as sampled negatives.\nAfter such pretraining, the BERT retriever is expected to have representations good enough for evidence retrieval. Only the question encoder needs to be fine-tuned for answer extraction. In other words, the evidence block encoder (i.e., $\\mathbf{W}_z$ and $\\text{BERT}_z$) is fixed and thus all the evidence block encodings can be pre-computed with support for\nfast Maximum Inner Product Search (MIPS)\n.\nAn illustration of the reader component in ORQA. (Image source:\nacl2020-openqa-tutorial/slides/part5\n)\nThe reader follows the same design as in the original\nBERT RC\nexperiments. It learns in a supervised manner, while the parameters of the evidence block encoder are fixed and all other parameters are fine-tuned. Given a question $x$ and a gold answer string $y$, the reader loss contains two parts:\n$$\n\\mathcal{L}(x, y) = \\mathcal{L}_\\text{early}(x, y) + \\mathcal{L}_\\text{full}(x, y)\n$$\n(1) Find all correct text spans within top $k$ evidence blocks and optimize for the marginal likelihood of a text span $s$ that matches the true answer $y$:\n$$\n\\begin{aligned}\nh_s &= \\text{BERT}_R(x, y)^{(\\text{START}(s))} \\\\\nh_e &= \\text{BERT}_R(x, y)^{(\\text{END}(s))} \\\\\nS_\\text{read}(z, s, x) &= \\text{MLP}([h_s; h_e]) \\\\\np(z, s \\vert x) &= \\frac{\\exp(S_\\text{read}(z, s, x))}{\\sum_{z'\\in\\text{TOP}(k)} \\sum_{s'\\in z'} \\exp(S_\\text{read}(z', s', x))} \\\\\nL_\\text{full}(x, y) &= - \\log \\sum_{\\substack{z \\in \\text{TOP}(k)\\\\ s \\in z}} \\sum_{y=\\text{TEXT}(s)} p(z, s \\vert x)\n\\end{aligned}\n$$\nwhere $y=\\text{TEXT}(s)$ indicates whether the answer $y$ matches the text span $s$. $\\text{TOP}(k)$ is the top $k$ retrieved blocks according to $S_\\text{retr}(z, x)$. The paper sets $k=5$.\n(2) At the early stage of learning, when the retriever is not strong enough, it is possible none of the top $k$ blocks contains the answer. To avoid such sparse learning signals, ORQA considers a larger set of $c$ evidence blocks for more aggressive learning. The paper has $c=5000$.\n$$\nL_\\text{early}(x, y)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} p_\\text{early}(z\\vert x)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} \\frac{\\exp(S_\\text{retr}(z, x)}{\\sum_{z'\\in\\text{TOP}(c)} \\exp(S_\\text{retr}(z', x)}\n$$\nSome issues in SQuAD dataset were discussed in the ORQA paper:\n\" The notable drop between development and test accuracy for SQuAD is a reflection of an artifact in the dataset—its 100k questions are derived from only 536 documents. Therefore, good retrieval targets are highly correlated between training examples, violating the IID assumption, and making it unsuitable for learned retrieval. We strongly suggest that those who are interested in end-to-end open-domain QA models no longer train and evaluate with SQuAD for this reason.\"\nREALM\n(“Retrieval-Augmented Language Model pre-training”;\nGuu et al., 2020\n) also jointly trains retriever + reader by optimizing the marginal likelihood of obtaining the true answer:\n$$\np(y \\vert x) \n= \\sum_{z \\in \\mathcal{Z}} \\underbrace{p(y \\vert x, z)}_\\text{reader} \\underbrace{p(z \\vert x)}_\\text{retriever}\n\\approx \\sum_{z \\in \\text{TOP}_k(\\mathcal{Z})} p(y \\vert x, z) p(z \\vert x)\n$$\nREALM is first unsupervised pre-trained with salient spans masking and then fine-tuned with QA data. (Image source:\nGuu et al., 2020\n).\nREALM computes two probabilities, $p(z \\vert x)$ and $p(y \\vert x, z)$, same as ORQA. However, different from ICT in ORQA, REALM upgrades the unsupervised pre-training step with several new design decisions, leading towards better retrievals. REALM pre-trains the model with Wikipedia or CC-News corpus.\nUse\nsalient span masking\n. Named entities and dates are identified. Then one of these “salient spans” is selected and masked. Salient span masking is a special case of MLM and works out well for QA tasks.\nAdd an\nempty null document\n. Because not every question demands a context document.\nNo trivial retrieval. The context document should not be same as the selected sentence with a masked span.\nApply the same ICT loss as in ORQA to encourage learning when the retrieval quality is still poor at the early stage of training.\n“Among all systems, the most direct comparison with REALM is ORQA (Lee et al., 2019), where the fine-tuning setup, hyperparameters and training data are identical. The improvement of REALM over ORQA is purely due to better pre-training methods.” — from REALM paper.\nBoth unsupervised pre-training and supervised fine-tuning optimize the same log-likelihood $\\log p(y \\vert x)$. Because the parameters of the retriever encoder for evidence documents are also updated in the process, the index for MIPS is changing. REALM asynchronously refreshes the index with the updated encoder parameters every several hundred training steps.\nBalachandran, et al. (2021)\nfound that REALM is significantly undertrained and REALM++ achieves great EM accuracy improvement (3-5%) by scaling up the model training with larger batch size and more retrieved documents for the reader to process.\nDPR\n(“Dense Passage Retriever”;\nKarpukhin et al., 2020\n,\ncode\n) argues that ICT pre-training could be too computationally expensive and the ORQA’s context encoder might be sub-optimal because it is not fine-tuned with question-answer pairs. DPR aims to resolve these two issues by only training a dense dual-encoder architecture for retrieval only from a small number of Q/A pairs, without any pre-training.\nSame as previous work, DPR uses the dot-product (L2 distance or cosine similarity also works) of BERT representations as retrieval score. The loss function for training the dual-encoder is the NLL of the positive passage, which essentially takes the same formulation as\nICT loss\nof ORQA. Note that both of them consider other passages in the same batch as the negative samples, named\nin-batch negative sampling\n. The main difference is that DPR relies on supervised QA data, while ORQA trains with ICT on unsupervised corpus. At the inference time, DPR uses\nFAISS\nto run fast MIPS.\nDPR did a set of comparison experiments involving several different types of negatives:\nRandom: any random passage from the corpus;\nBM25: top passages returned by BM25 which don’t contain the answer but match most question tokens;\nIn-batch negative sampling (“gold”): positive passages paired with other questions which appear in the training set.\nDPR found that using gold passages from the same mini-batch and one negative passage with high BM25 score works the best. To further improve the retrieval results, DPR also explored a setting where a BM25 score and a dense embedding retrieval score are linearly combined to serve as a new ranking function.\nOpen-book QA: Retriever-Generator\n#\nCompared to the retriever-reader approach, the retriever-generator also has 2 stages but the second stage is to generate free text directly to answer the question rather than to extract start/end position in a retrieved passage. Some paper also refer to this as\nGenerative question answering\n.\nThe retriever + generator QA framework combines a document retrieval system with a general language model.\nA pretrained LM has a great capacity of memorizing knowledge in its parameters, as shown above. However, they cannot easily modify or expand their memory, cannot straightforwardly provide insights into their predictions, and may produce non-existent illusion.\nPetroni et al. (2020)\nstudied how the retrieved relevant context can help a generative language model produce better answers. They found:\nAugmenting queries with relevant contexts dramatically improves the pretrained LM on unsupervised machine reading capabilities.\nAn off-the-shelf IR system is sufficient for BERT to match the performance of a supervised ODQA baseline;\nBERT’s\nNSP\npre-training strategy is a highly effective unsupervised mechanism in dealing with noisy and irrelevant contexts.\nThey pair the BERT model with different types of context, including adversarial (unrelated context), retrieved (by BM25), and generative (by an autoregressive language model of 1.4N parameters, trained on CC-NEWS). The model is found to be robust to adversarial context, but only when the question and the context are provided as two segments (e.g. separated by\n[SEP]\n). One hypothesis is related to NSP task: “BERT might learn to not condition across segments for masked token prediction if the NSP score is low, thereby implicitly detecting irrelevant and noisy contexts.”\nRAG\n(“Retrieval-Augmented Generation”;\nLewis et al., 2020\n) combines pre-trained parametric (language model) and non-parametric memory (external knowledge index) together for language generation. RAG can be fine-tuned on any seq2seq task, whereby both the retriever and the sequence generator are jointly learned. They found that unconstrained generation outperforms previous extractive approaches.\nRAG consists of a retriever model $p_\\eta(z \\vert x)$ and a generator model $p_\\theta(y_i \\vert x, z, y_{1:i-1})$:\nThe retriever uses the input sequence $x$ to retrieve text passages $z$, implemented as a\nDPR\nretriever. $\\log p_\\eta(z \\vert x) \\propto E_z(z)^\\top E_x(x)$.\nThe generator uses $z$ as additional context when generating the target sequence $y$, where the context and the question are simply concatenated.\nDepending on whether using the same or different retrieved documents for each token generation, there are two versions of RAG:\n$$\n\\begin{aligned}\np_\\text{RAG-seq}(y \\vert x) &= \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z \\vert x) \\prod_i^N p_\\theta(y_i \\vert x, z, y_{1:i-1}) \\\\\np_\\text{RAG-token}(y \\vert x) &= \\prod_i^N \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z_i\\vert x) p_\\theta(y_i \\vert x, z_i, y_{1:i-1})\n\\end{aligned}\n$$\nThe retriever + generator in RAG is jointly trained to minimize the NLL loss, $\\mathcal{L}_\\text{RAG} = \\sum_j -\\log p(y_j \\vert x_j)$. Updating the passage encoder $E_z(.)$ is expensive as it requires the model to re-index the documents for fast MIPS. RAG does not find fine-tuning $E_z(.)$ necessary (like in\nORQA\n) and only updates the query encoder + generator.\nAn illustration of retrieval-augmented generation (RAG) architecture. (Image source:\nLewis et al., 2020\n)\nAt decoding/test time, RAG-token can be evaluated via a\nbeam search\n. RAG-seq cannot be broken down into a set of per-token likelihood, so it runs beam search for each candidate document $z$ and picks the one with optimal $p_\\theta(y_i \\vert x, z, y_{1:i-1})$.\nThe\nFusion-in-Decoder\napproach, proposed by\nIzacard & Grave (2020)\nis also based on a pre-trained T5. It works similar to RAG but differently for how the context is integrated into the decoder.\nRetrieve top $k$ related passage of 100 words each, using BM25 or DPR.\nEach retrieved passage and its title are concatenated with the question using special tokens like\nquestion:\n,\ntitle:\nand\ncontext:\nto indicate the content differences.\nEach retrieved passage is processed independently and later combined in the decoder. Processing passages independently in the encoder allows us to parallelize the computation. OTOH, processing them jointly encourages better aggregation of multiple pieces of evidence. The aggregation part is missing in extractive approaches.\nNote that they did fine-tune the pretrained LM independently for each dataset.\nClosed-book QA: Generative Language Model\n#\nBig language models have been pre-trained on a large collection of unsupervised textual corpus. Given enough parameters, these models are able to memorize some factual knowledge within parameter weights. Therefore, we can use these models to do question-answering without explicit context, just like in a closed-book exam. The pre-trained language models produce\nfree text\nto respond to questions, no explicit reading comprehension.\nThe amount of computation used for training big language models of different sizes is getting big. (Image source:\nBrown et al., 2020\n).\nRoberts et al. (2020)\nmeasured the practical utility of a language model by fine-tuning a pre-trained model to answer questions without access to any external context or knowledge. They fine-tuned the\nT5\nlanguage model (same architecture as the original Transformer) to answer questions without inputting any additional information or context. Such setup enforces the language model to answer questions based on “knowledge” that it internalized during pre-training.\nT5 is first pre-trained with salient span masking and then fine-tuned for each QA dataset to produce answers in free text. (Image source:\nRoberts et al. 2020\n)\nThe original T5 models were pre-trained on a multi-task mixture including an unsupervised\n“masked language modeling”\n(MLM) tasks on the C4 (“Colossal Clean Crawled Corpus”) dataset as well as fine-tuned altogether with supervised translation, summarization, classification, and reading comprehension tasks.\nRoberts, et al. (2020)\ntook a pre-trained T5 model and continued pre-training with\nsalient span masking\nover Wikipedia corpus, which has been found to substantially boost the performance for ODQA. Then they fine-tuned the model for each QA datasets independently.\nWith a pre-trained T5 language model +  continue pre-training with salient spans masking + fine-tuning for each QA dataset,\nIt can attain competitive results in open-domain question answering without access to external knowledge.\nA larger model can obtain better performance. For example, a T5 with 11B parameters is able to match the performance with\nDPR\nwith 3 BERT-base models, each with 330M parameters.\nInterestingly, fine-tuning is not strictly necessary. GPT3 (\nBrown et al., 2020\n) has been evaluated on the closed book question answering task\nwithout any gradient updates or fine-tuning\n. During evaluation, the few-shot, one-shot and zero-shot settings here only refer to how many demonstrations are provided as context in the text input:\n“few-shot learning”: GPT3 is allowed to take as many demonstrations as what can fit into the model’s context window (typically 10 to 100).\n“one-shot learning”: only one demonstration is provided.\n“zero-shot learning”: no demonstrations are allowed and only an instruction in natural language is given to the model.\nThe performance grows with the model size. On the TriviaQA dataset, GPT3 evaluation with demonstrations can match or exceed the performance of SOTA baseline with fine-tuning.\nGPT3's performance on TriviaQA grows smoothly with the model size. More demonstrations lead to better performance. (Image source:\nBrown et al., 2020\n).\nCheck out this cool example in OpenAI API\nplayground viewer\n. The model is able to answer factal questions in short answer and not to make up things when the model does not know the answer. I added the last two questions and asked the model to respond with\nA:\n. The API is still in beta version, so you might need to\napply\nto get on the wait list.\nQ: Who is Batman?\nA: Batman is a fictional comic book character.\n##\nQ: What is torsalplexity?\nA: ?\n##\nQ: What is Devz9?\nA: ?\n##\nQ: Who is George Lucas?\nA: George Lucas is American film director and producer famous for creating Star Wars.\n##\nQ: What is the capital of California?\nA: Sacramento.\n##\nQ: What orbits the Earth?\nA: The Moon.\n##\nQ: Who is Fred Rickerson?\nA: ?\n##\nQ: What is an atom?\nA: An atom is a tiny particle that makes up everything.\n##\nQ: Who is Alvan Muntz?\nA: ?\n##\nQ: What is Kozar-09?\nA: ?\n##\nQ: How many moons does Mars have?\nA: Two, Phobos and Deimos.\n##\nQ: What is COVID-19?\nA: ?\n##\nQ: What is H1N1?\nA: H1N1 is a strain of influenza.\nRelated Techniques\n#\nFast Maximum Inner Product Search (MIPS)\n#\nMIPS (maximum inner product search) is a crucial component in many open-domain question answering models. In retriever + reader/generator framework, a large number of passages from the knowledge source are encoded and stored in a memory. A retrieval model is able to query the memory to identify the top relevant passages which have the maximum inner product with the question’s embedding.\nWe need fast MIPS because the number of precomputed passage representations can be gigantic. There are several ways to achieve fast MIPS at run time, such as\nasymmetric LSH\n,\ndata-dependent hashing\n,  and\nFAISS\n.\nLanguage Model Pre-training\n#\nTwo pre-training tasks are especially helpful for QA tasks, as we have discussed above.\nInverse Cloze Task\n(proposed by\nORQA\n): The goal of\nCloze Task\nis to predict masked-out text based on its context. The prediction of Inverse Cloze Task (ICT) is in the reverse direction, aiming to predict the context given a sentence. In the context of QA tasks, a random sentence can be treated as a pseudo-question, and its context can be treated as pseudo-evidence.\nSalient Spans Masking\n(proposed by\nREALM\n): Salient span masking is a special case for MLM task in language model training. First, we find\nsalient spans\nby using a tagger to identify named entities and a regular expression to identify dates. Then one of the detected salient spans is selected and masked. The task is to predict this masked salient span.\nSummary\n#\nModel\nRetriever\nReader / Generator\nPre-training / Fine-tuning\nEnd2end\nDrQA\nTF-IDF\nBi-directional LSTM\n–\nNo\nBERTserini\nAserini + BM25\nBERT without softmax layer\nFine-tune with SQuAD\nNo\nMulti-passage BERT\nElasticSearch + BM25\nMulti-passage BERT + Passage ranker\nNo\nR^3\nClassic IR + Match-LSTM\nMatch-LSTM\nYes\nORQA\nDot product of BERT embeddings\nBERT-RC\nInverse cloze task\nYes\nREALM\nDot product of BERT embeddings\nBERT-RC\nSalient span masking\nYes\nDPR\nDot product of BERT embeddings\nBERT-RC\nsupervised training with QA pairs\nYes\nDenSPI\nClassic + Neural IR\n–\nYes\nT5 + SSM\n–\nT5\nSSM on\nCommonCrawl\ndata + Fine-tuning on QA data\nYes\nGPT3\n–\nGPT3\nNSP on\nCommonCrawl\ndata\nYes\nRAG\nDPR retriever\nBART\nYes\nFusion-in-Decoder\nBM25 / DPR retriever\nTranformer\nNo\nA comparison of performance of several QA models on common QA datasets. On TriviaQA, two columns of results are reported, on the open domain test set (left) and on the hidden test set (right). (Image source:\nIzacard & Grave, 2020\n).\nCitation\n#\nCited as:\nWeng, Lilian. (Oct 2020). How to build an open-domain question answering system? Lil’Log. https://lilianweng.github.io/posts/2020-10-29-odqa/.\nOr\n@article{weng2020odqa,\n  title   = \"How to Build an Open-Domain Question Answering System?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Oct\"\n  url     = \"https://lilianweng.github.io/posts/2020-10-29-odqa/\"\n}\nAppendix: QA Datasets\n#\nSQuAD 2.0\n: the Stanford QA dataset.\nRACE\n: a reading comprehension dataset collected from English Examinations that are created for middle school and high school students.\nTREC QA\n: the TREC QA collections.\nMS MARCO\n: a QA dataset featuring 100,000 real Bing questions and a human generated answer.\nCuratedTREC\n: based on the benchmarks from the TREC QA tasks that have been curated by\nBaudis & Sedivy (2015)\n.\nGoogle Natural Questions\n:  contains real user questions issued to Google search, and answers found from Wikipedia by annotators.\nWebQuestions\n: designed for knowledge-base QA with answers restricted to Freebase entities.\nWikiQA\n: Bing query logs were used as the source of questions. Each question is then linked to a Wikipedia page that potentially contains the answer.\nWikiMovies\n: contains movie-related questions from the OMDb and MovieLens databases and where the questions can be answered using Wikipedia pages.\nWikiReading\n: to predict textual values from the structured knowledge base Wikidata by reading the text of the corresponding Wikipedia articles.\nTriviaQA\n: a reading comprehension dataset containing 95K question-answer pairs authored by trivia enthusiasts and independently gathered multiple evidence documents per question.\nJeopardy! Questions\n: contains 200,000+\nJeopardy!\nquestions.\nDeepMind Q&A Dataset\n: question/answer pairs from CNN and Daily Mail articles.\nbAbi\n: a rich collection of datasets for text understanding by Facebook.\nFEVER\n: for fact extraction and verification.\nSearchQA\n: question-answer pairs were crawled from from\nJ! Archive\n, and then augmented with text snippets from Google.\nQuasar-T\n: a collection of open-domain trivia questions and their answers obtained from various internet sources.\nQuiz bowl\n: contains data from a trivia competition called quiz bowl.\nAmbigNQ\n: ambiguous questions selected from NQ-OPEN dataset.\nQA-Overlap\n: a collections of overlapped answers/questions between train and test set for Natural Questions, TriviaQA, and WebQuestions.\nReferences\n#\n[1] Danqi Chen & Scott Yih.\n“ACL2020 Tutorial: Open-Domain Question Answering”\nJuly 2020.\n[2] Danqi Chen, et al.\n“Reading Wikipedia to Answer Open-Domain Questions”\nACL 2017. |\ncode\n[3] Shuohang Wang, et al.\n“R^3: Reinforced Ranker-Reader for Open-Domain Question Answering”\nAAAI 2018.\n[4] Jimmy Lin.\n“The neural hype and comparisons against weak baselines.”\nACM SIGIR Forum. Vol. 52. No. 2. 2019.\n[5] Wei Yang, et al.\n“End-to-End Open-Domain Question Answering with BERTserini”\nNAACL 2019.\n[6] Christopher Clark & Matt Gardner.\n“Simple and Effective Multi-Paragraph Reading Comprehension.”\narXiv:1710.10723 (2017).\n[7] Rodrigo Nogueira & Kyunghyun Cho.\n“Passage Re-ranking with BERT.”\narXiv preprint arXiv:1901.04085 (2019). |\ncode\n[8] Zhiguo Wang, et al.\n“Multi-passage BERT: A globally normalized BERT model for open-domain question answering.”\nEMNLP 2019.\n[9] Minjoon Seo et al.\n“Real-time open-domain question answering with dense-sparse phrase index.”\nACL 2019.\n[10] Kenton Lee, et al.\n“Latent Retrieval for Weakly Supervised Open Domain Question Answering”\nACL 2019.\n[11] Kelvin Guu, et al.\n“REALM: Retrieval-Augmented Language Model Pre-Training”\narXiv:2002.08909 (2020).\n[12] Vladimir Karpukhin et al.\n“Dense passage retrieval for open-domain question answering.”\n. EMNLP 2020. |\ncode\n[13] Patrick Lewis et al.\n“Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”\narXiv:2005.11401 (2020).\n[14] Adam Roberts, et al.\n“How Much Knowledge Can You Pack Into the Parameters of a Language Model?”\nEMNLP 2020.\n[15] Tom Brown, et al.\n“Language models are few-shot learners.”\narXiv:2005.14165 (2020).\n[16] Fabio Petroni, et al.\n“How Context Affects Language Models’ Factual Predictions”\nAKBC 2020.\n[17] Gautier Izacard & Edouard Grave.\n“Leveraging passage retrieval with generative models for open domain question answering.”\narXiv:2007.01282 (2020).\n[18]\n“Dive into deep learning: Beam search”\n[19] Patrick Lewis, et al.\n“Question and Answer Test-Train Overlap in Open-Domain Question Answering Datasets”\narXiv:2008.02637 (2020). |\ndata\n[20] Hervé Jegou, et al.\n“Faiss: A library for efficient similarity search”\nMar 2017.\n[21] Vidhisha Balachandran, et al.\n“Simple and Efficient ways to Improve REALM.”\narXiv:2104.08710 (2021).",
            "metadata": {
              "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
              "description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "keywords": "nlp, language-model, attention, transformer",
              "author": "Lilian Weng",
              "og:title": "How to Build an Open-Domain Question Answering System?",
              "og:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
              "twitter:card": "summary",
              "twitter:title": "How to Build an Open-Domain Question Answering System?",
              "twitter:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "article:section": "posts",
              "article:published_time": "2020-10-29T00:00:00+00:00",
              "article:modified_time": "2020-10-29T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/2cf34df8cd69/code/body-000.txt",
                "chars": 105,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-001.txt",
                "chars": 656,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-002.txt",
                "chars": 263,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "bytes": 661245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7efefadad7e7dd1bd368.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "bytes": 173461,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ef8c4099815df32d696d.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "bytes": 192230,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-a2c96b21ecb7e2fe5261.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "bytes": 180723,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-9d359913e38042c21f68.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "bytes": 131727,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-658614a9a3e7c1d7b935.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "bytes": 337530,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-eaf24c5188513fae50ed.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "bytes": 124437,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ff31b70ac499e0b32939.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "bytes": 865287,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-2e1a4cd54853b0630bf6.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "bytes": 553919,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7826a791054014f6fcfb.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "bytes": 260572,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-d37427b8abf7df28ba56.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "bytes": 198348,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-1debd5c40323ec83577c.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "bytes": 290218,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-76ae01d2ac36750aac13.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "bytes": 145311,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-cb02352f1fcc5796b966.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "bytes": 201245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-4a06ae2c872925f426c9.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "bytes": 329545,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-592734de78cf202658cc.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "bytes": 244182,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-f4f90d0aeb9507c08585.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2008.02637",
                "label": "Lewis, et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/QA-Overlap",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.00051",
                "label": "Chen et al., 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DrQA",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "TF-IDF",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Vector_space_model",
                "label": "vector space model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01718",
                "label": "Yang et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/castorini/anserini",
                "label": "Anserini",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Okapi_BM25",
                "label": "BM25",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.08167",
                "label": "Wang et al., 2019",
                "type": "a"
              },
              {
                "href": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "label": "Deerwester et al., 1990",
                "type": "a"
              },
              {
                "href": "https://www.aclweb.org/anthology/W11-0329/",
                "label": "Yih, et al., 2011",
                "type": "a"
              },
              {
                "href": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "label": "Lim, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.05807",
                "label": "Seo et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Glove",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "Devlin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.10723",
                "label": "globally",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.04085",
                "label": "Nogueira & Cho, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.00023",
                "label": "Wang, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.08849",
                "label": "Match-LSTM",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part4-retriever-reader.pdf",
                "label": "acl2020-openqa-tutorial/slides/part4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00300",
                "label": "Lee et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part5-dense-retriever-e2e-training.pdf",
                "label": "acl2020-openqa-tutorial/slides/part5",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Cloze Task",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08909",
                "label": "Guu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08710",
                "label": "Balachandran, et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DPR",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.04611",
                "label": "Petroni et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.11401",
                "label": "Lewis et al., 2020",
                "type": "a"
              },
              {
                "href": "https://d2l.ai/chapter_recurrent-modern/beam-search.html",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.01282",
                "label": "Izacard & Grave (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08910",
                "label": "Roberts et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "T5",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/playground/p/HMoho4552EHXrPLbmOIxpX4X",
                "label": "playground viewer",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/",
                "label": "apply",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "label": "asymmetric LSH",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1501.01062",
                "label": "data-dependent hashing",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/the-data/get-started/",
                "label": "CommonCrawl",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "BART",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD 2.0",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/qa.html",
                "label": "TREC QA",
                "type": "a"
              },
              {
                "href": "https://microsoft.github.io/msmarco/",
                "label": "MS MARCO",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-curated",
                "label": "CuratedTREC",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/chapter/10.1007%2F978-3-319-24027-5_20",
                "label": "Baudis & Sedivy (2015)",
                "type": "a"
              },
              {
                "href": "https://ai.google.com/research/NaturalQuestions/dataset",
                "label": "Google Natural Questions",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-webquestions",
                "label": "WebQuestions",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/publication/wikiqa-a-challenge-dataset-for-open-domain-question-answering/",
                "label": "WikiQA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "WikiMovies",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research-datasets/wiki-reading",
                "label": "WikiReading",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/triviaqa/",
                "label": "TriviaQA",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/tunguz/200000-jeopardy-questions",
                "label": "Jeopardy! Questions",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jeopardy!",
                "label": "Jeopardy!",
                "type": "a"
              },
              {
                "href": "https://cs.nyu.edu/~kcho/DMQA/",
                "label": "DeepMind Q&A Dataset",
                "type": "a"
              },
              {
                "href": "https://fever.ai/data.html",
                "label": "FEVER",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4ir-searchQA",
                "label": "SearchQA",
                "type": "a"
              },
              {
                "href": "https://j-archive.com/",
                "label": "J! Archive",
                "type": "a"
              },
              {
                "href": "https://github.com/bdhingra/quasar",
                "label": "Quasar-T",
                "type": "a"
              },
              {
                "href": "https://people.cs.umass.edu/~miyyer/qblearn/index.html",
                "label": "Quiz bowl",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/ambigqa/",
                "label": "AmbigNQ",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial",
                "label": "“ACL2020 Tutorial: Open-Domain Question Answering”",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4marco-bert",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://engineering.fb.com/2017/03/29/data-infrastructure/faiss-a-library-for-efficient-similarity-search/",
                "label": "“Faiss: A library for efficient similarity search”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:28Z",
            "source_url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2008.02637",
                "bytes": 146376,
                "reused": false,
                "local_path": "papers/repair/8ad962c997b08e996dd4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00051",
                "bytes": 2048034,
                "reused": false,
                "local_path": "papers/repair/d0f7a3fcc176ba86400e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01718",
                "bytes": 1306033,
                "reused": false,
                "local_path": "papers/repair/5601bffbfa0b981b6331.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.08167",
                "bytes": 259305,
                "reused": false,
                "local_path": "papers/repair/fa52b7dcb76039375378.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "content_type": "text/html; charset=UTF-8",
                "retried_at": "2026-10-20T17:40:15Z"
              },
              {
                "status": "ok",
                "url": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "bytes": 134597,
                "reused": false,
                "local_path": "papers/repair/4ab646693162802f854c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.05807",
                "bytes": 359767,
                "reused": false,
                "local_path": "papers/repair/747eb29b4590aa97c069.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.10723",
                "bytes": 452153,
                "reused": false,
                "local_path": "papers/repair/28189a7ac5e78a81e437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.04085",
                "bytes": 179659,
                "reused": false,
                "local_path": "papers/repair/05b68ab5e80214473436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.00023",
                "bytes": 467789,
                "reused": false,
                "local_path": "papers/repair/2b555bf087dc301d5ab3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.08849",
                "bytes": 560057,
                "reused": false,
                "local_path": "papers/repair/4a818c3029a76aba9073.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part4-retriever-reader.pdf",
                "bytes": 7788557,
                "reused": false,
                "local_path": "papers/repair/8edd53d3acc87ec95877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00300",
                "bytes": 324074,
                "reused": false,
                "local_path": "papers/repair/21d0f741ef22e8382844.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part5-dense-retriever-e2e-training.pdf",
                "bytes": 5923321,
                "reused": false,
                "local_path": "papers/repair/09e19d59295cafdb35c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08909",
                "bytes": 419037,
                "reused": false,
                "local_path": "papers/repair/9325ba1ac58281154385.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08710",
                "bytes": 314281,
                "reused": false,
                "local_path": "papers/repair/4afe57efbece847b61fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.04611",
                "bytes": 599811,
                "reused": false,
                "local_path": "papers/repair/d1464f0dd0e30968c8ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.11401",
                "bytes": 885323,
                "reused": true,
                "local_path": "papers/repair/fc8d32f196e0f0c27ffb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.01282",
                "bytes": 326612,
                "reused": false,
                "local_path": "papers/repair/63195f1903a8ee821e29.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08910",
                "bytes": 310594,
                "reused": false,
                "local_path": "papers/repair/4f3639d8e3ec9d8f612f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "bytes": 429326,
                "reused": false,
                "local_path": "papers/repair/615a9235abb8f6f533bd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1501.01062",
                "bytes": 849475,
                "reused": false,
                "local_path": "papers/repair/63f32442dc6c96976afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46975,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/2cf34df8cd69/pages/source.html",
            "local_html": "attachments/2cf34df8cd69/pages/article.html",
            "body_base_path": "attachments/2cf34df8cd69/pages/",
            "body_markdown_path": "attachments/2cf34df8cd69/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
          "status": "partial",
          "article_id": "9e1d58627b38",
          "local_path": "series-follow/1602/repair/3966b026c35e1e97e15a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
              "bytes": 58269,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/418c8992a5cc9d9deeb1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
              "bytes": 107025,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d53eaab123d7a3b8d561.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
              "bytes": 33772,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1a3ee27cdec9dd4e95e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
              "bytes": 55693,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1602/repair/assets/8b930e0942e1d249d7cd.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
              "bytes": 27143,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/508e643f8751bb71fcf3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
              "bytes": 32728,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/aa4ac628fe85693e0ba3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
              "bytes": 21618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8917c12943284b1507b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
              "bytes": 133435,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c1fcc0568374ce65ea91.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
              "bytes": 35850,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/be7712dd68a63d561005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
              "bytes": 128382,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d374974862f12f0f0ada.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
              "bytes": 91431,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0d8b962a59d7ad31b2ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
              "bytes": 136647,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3ceb5a7713444f264e70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
              "bytes": 61555,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/070437b06f4b4d8a0287.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "A (Long) Peek into Reinforcement Learning",
            "keywords": "强化学习,RL,入门",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "publish_date": "2018-02",
            "corpus_stage": "强化学习/对齐",
            "notes": "强化学习入门经典综述",
            "id": "9e1d58627b38",
            "collected_at": "2026-10-02T14:13:19",
            "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-09-03: Updated the algorithm of\nSARSA\nand\nQ-learning\nso that the difference is more pronounced.\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in\nChinese\n].\nA couple of exciting news in Artificial Intelligence (AI) has just happened in recent years.  AlphaGo defeated the best professional human player in the game of Go. Very soon the extended algorithm AlphaGo Zero beat AlphaGo by 100-0 without supervised learning on human knowledge. Top professional game players lost to the bot developed by OpenAI on DOTA2 1v1 competition. After knowing these, it is pretty hard not to be curious about the magic behind these algorithms — Reinforcement Learning (RL). I’m writing this post to briefly go over the field. We will first introduce several fundamental concepts and then dive into classic approaches to solving RL problems. Hopefully, this post could be a good starting point for newbies, bridging the future study on the cutting-edge research.\nWhat is Reinforcement Learning?\n#\nSay, we have an agent in an unknown environment and this agent can obtain some rewards by interacting with the environment. The agent ought to take actions so as to maximize cumulative rewards. In reality, the scenario could be a bot playing a game to achieve high scores, or a robot trying to complete physical tasks with physical items; and not just limited to these.\nAn agent interacts with the environment, trying to take smart actions to maximize cumulative rewards.\nThe goal of Reinforcement Learning (RL) is to learn a good strategy for the agent from experimental trials and relative simple feedback received. With the optimal strategy, the agent is capable to actively adapt to the environment to maximize future rewards.\nKey Concepts\n#\nNow Let’s formally define a set of key concepts in RL.\nThe agent is acting in an\nenvironment\n. How the environment reacts to certain actions is defined by a\nmodel\nwhich we may or may not know. The agent can stay in one of many\nstates\n($s \\in \\mathcal{S}$) of the environment, and choose to take one of many\nactions\n($a \\in \\mathcal{A}$) to switch from one state to another. Which state the agent will arrive in is decided by transition probabilities between states ($P$). Once an action is taken, the environment delivers a\nreward\n($r \\in \\mathcal{R}$) as feedback.\nThe model defines the reward function and transition probabilities. We may or may not know how the model works and this differentiate two circumstances:\nKnow the model\n: planning with perfect information; do model-based RL. When we fully know the environment, we can find the optimal solution by\nDynamic Programming\n(DP). Do you still remember “longest increasing subsequence” or “traveling salesmen problem” from your Algorithms 101 class? LOL. This is not the focus of this post though.\nDoes not know the model\n: learning with incomplete information; do model-free RL or try to learn the model explicitly as part of the algorithm. Most of the following content serves the scenarios when the model is unknown.\nThe agent’s\npolicy\n$\\pi(s)$ provides the guideline on what is the optimal action to take in a certain state with\nthe goal to maximize the total rewards\n. Each state is associated with a\nvalue\nfunction $V(s)$ predicting the expected amount of future rewards we are able to receive in this state by acting the corresponding policy. In other words, the value function quantifies how good a state is. Both policy and value functions are what we try to learn in reinforcement learning.\nSummary of approaches in RL based on whether we want to model the value, policy, or the environment. (Image source: reproduced from David Silver's RL course\nlecture 1\n.)\nThe interaction between the agent and the environment involves a sequence of actions and observed rewards in time, $t=1, 2, \\dots, T$. During the process, the agent accumulates the knowledge about the environment, learns the optimal policy, and makes decisions on which action to take next so as to efficiently learn the best policy. Let’s label the state, action, and reward at time step t as $S_t$, $A_t$, and $R_t$, respectively. Thus the interaction sequence is fully described by one\nepisode\n(also known as “trial” or “trajectory”) and the sequence ends at the terminal state $S_T$:\n$$\nS_1, A_1, R_2, S_2, A_2, \\dots, S_T\n$$\nTerms you will encounter a lot when diving into different categories of RL algorithms:\nModel-based\n: Rely on the model of the environment; either the model is known or the algorithm learns it explicitly.\nModel-free\n: No dependency on the model during learning.\nOn-policy\n: Use the deterministic outcomes or samples from the target policy to train the algorithm.\nOff-policy\n: Training on a distribution of transitions or episodes produced by a different behavior policy rather than that produced by the target policy.\nModel: Transition and Reward\n#\nThe model is a descriptor of the environment. With the model, we can learn or infer how the environment would interact with and provide feedback to the agent. The model has two major parts, transition probability function $P$ and reward function $R$.\nLet’s say when we are in state s, we decide to take action a to arrive in the next state s’ and obtain reward r. This is known as one\ntransition\nstep, represented by a tuple (s, a, s’, r).\nThe transition function P records the probability of transitioning from state s to s’ after taking action a while obtaining reward r. We use $\\mathbb{P}$ as a symbol of “probability”.\n$$\nP(s', r \\vert s, a)  = \\mathbb{P} [S_{t+1} = s', R_{t+1} = r \\vert S_t = s, A_t = a]\n$$\nThus the state-transition function can be defined as a function of $P(s’, r \\vert s, a)$:\n$$\nP_{ss'}^a = P(s' \\vert s, a)  = \\mathbb{P} [S_{t+1} = s' \\vert S_t = s, A_t = a] = \\sum_{r \\in \\mathcal{R}} P(s', r \\vert s, a)\n$$\nThe reward function R predicts the next reward triggered by one action:\n$$\nR(s, a) = \\mathbb{E} [R_{t+1} \\vert S_t = s, A_t = a] = \\sum_{r\\in\\mathcal{R}} r \\sum_{s' \\in \\mathcal{S}} P(s', r \\vert s, a)\n$$\nPolicy\n#\nPolicy, as the agent’s behavior function $\\pi$, tells us which action to take in state s. It is a mapping from state s to action a and can be either deterministic or stochastic:\nDeterministic: $\\pi(s) = a$.\nStochastic: $\\pi(a \\vert s) = \\mathbb{P}_\\pi [A=a \\vert S=s]$.\nValue Function\n#\nValue function measures the goodness of a state or how rewarding a state or an action is by a prediction of future reward. The future reward, also known as\nreturn\n, is a total sum of discounted rewards going forward. Let’s compute the return $G_t$ starting from time t:\n$$\nG_t = R_{t+1} + \\gamma R_{t+2} + \\dots = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}\n$$\nThe discounting factor $\\gamma \\in [0, 1]$ penalize the rewards in the future, because:\nThe future rewards may have higher uncertainty; i.e. stock market.\nThe future rewards do not provide immediate benefits; i.e. As human beings, we might prefer to have fun today rather than 5 years later ;).\nDiscounting provides mathematical convenience; i.e., we don’t need to track future steps forever to compute return.\nWe don’t need to worry about the infinite loops in the state transition graph.\nThe\nstate-value\nof a state s is the expected return if we are in this state at time t, $S_t = s$:\n$$\nV_{\\pi}(s) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s]\n$$\nSimilarly, we define the\naction-value\n(“Q-value”; Q as “Quality” I believe?) of a state-action pair as:\n$$\nQ_{\\pi}(s, a) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s, A_t = a]\n$$\nAdditionally, since we follow the target policy $\\pi$, we can make use of the probility distribution over possible actions and the Q-values to recover the state-value:\n$$\nV_{\\pi}(s) = \\sum_{a \\in \\mathcal{A}} Q_{\\pi}(s, a) \\pi(a \\vert s)\n$$\nThe difference between action-value and state-value is the action\nadvantage\nfunction (“A-value”):\n$$\nA_{\\pi}(s, a) = Q_{\\pi}(s, a) - V_{\\pi}(s)\n$$\nOptimal Value and Policy\n#\nThe optimal value function produces the maximum return:\n$$\nV_{*}(s) = \\max_{\\pi} V_{\\pi}(s),\nQ_{*}(s, a) = \\max_{\\pi} Q_{\\pi}(s, a)\n$$\nThe optimal policy achieves optimal value functions:\n$$\n\\pi_{*} = \\arg\\max_{\\pi} V_{\\pi}(s),\n\\pi_{*} = \\arg\\max_{\\pi} Q_{\\pi}(s, a)\n$$\nAnd of course, we have $V_{\\pi_{*}}(s)=V_{*}(s)$ and $Q_{\\pi_{*}}(s, a) = Q_{*}(s, a)$.\nMarkov Decision Processes\n#\nIn more formal terms, almost all the RL problems can be framed as\nMarkov Decision Processes\n(MDPs). All states in MDP has “Markov” property, referring to the fact that the future only depends on the current state, not the history:\n$$\n\\mathbb{P}[ S_{t+1} \\vert S_t ] = \\mathbb{P} [S_{t+1} \\vert S_1, \\dots, S_t]\n$$\nOr in other words, the future and the past are\nconditionally independent\ngiven the present, as the current state encapsulates all the statistics we need to decide the future.\nThe agent-environment interaction in a Markov decision process. (Image source: Sec. 3.1 Sutton & Barto (2017).)\nA Markov deicison process consists of five elements $\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, P, R, \\gamma \\rangle$, where the symbols carry the same meanings as key concepts in the\nprevious\nsection, well aligned with RL problem settings:\n$\\mathcal{S}$ - a set of states;\n$\\mathcal{A}$ - a set of actions;\n$P$ - transition probability function;\n$R$ - reward function;\n$\\gamma$ - discounting factor for future rewards.\nIn an unknown environment, we do not have perfect knowledge about $P$ and $R$.\nA fun example of Markov decision process: a typical work day. (Image source:\nrandomant.net/reinforcement-learning-concepts\n)\nBellman Equations\n#\nBellman equations refer to a set of equations that decompose the value function into the immediate reward plus the discounted future values.\n$$\n\\begin{aligned}\nV(s) &= \\mathbb{E}[G_t \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma R_{t+2} + \\gamma^2 R_{t+3} + \\dots \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma (R_{t+2} + \\gamma R_{t+3} + \\dots) \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma G_{t+1} \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\vert S_t = s]\n\\end{aligned}\n$$\nSimilarly for Q-value,\n$$\n\\begin{aligned}\nQ(s, a) \n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\mid S_t = s, A_t = a] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma \\mathbb{E}_{a\\sim\\pi} Q(S_{t+1}, a) \\mid S_t = s, A_t = a]\n\\end{aligned}\n$$\nBellman Expectation Equations\n#\nThe recursive update process can be further decomposed to be equations built on both state-value and action-value functions. As we go further in future action steps, we extend V and Q alternatively by following the policy $\\pi$.\nIllustration of how Bellman expection equations update state-value and action-value functions.\n$$\n\\begin{aligned}\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) Q_{\\pi}(s, a) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\\\\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\big) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\sum_{a' \\in \\mathcal{A}} \\pi(a' \\vert s') Q_{\\pi} (s', a')\n\\end{aligned}\n$$\nBellman Optimality Equations\n#\nIf we are only interested in the optimal values, rather than computing the expectation following a policy, we could jump right into the maximum returns during the alternative updates without using a policy. RECAP: the optimal values $V_*$ and $Q_*$ are the best returns we can obtain, defined\nhere\n.\n$$\n\\begin{aligned}\nV_*(s) &= \\max_{a \\in \\mathcal{A}} Q_*(s,a)\\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\\\\nV_*(s) &= \\max_{a \\in \\mathcal{A}} \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\big) \\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\max_{a' \\in \\mathcal{A}} Q_*(s', a')\n\\end{aligned}\n$$\nUnsurprisingly they look very similar to Bellman expectation equations.\nIf we have complete information of the environment, this turns into a planning problem, solvable by DP. Unfortunately, in most scenarios, we do not know $P_{ss’}^a$ or $R(s, a)$, so we cannot solve MDPs by directly applying Bellmen equations, but it lays the theoretical foundation for many RL algorithms.\nCommon Approaches\n#\nNow it is the time to go through the major approaches and classic algorithms for solving RL problems. In future posts, I plan to dive into each approach further.\nDynamic Programming\n#\nWhen the model is fully known, following Bellman equations, we can use\nDynamic Programming\n(DP) to iteratively evaluate value functions and improve policy.\nPolicy Evaluation\n#\nPolicy Evaluation is to compute the state-value $V_\\pi$ for a given policy $\\pi$:\n$$\nV_{t+1}(s) \n= \\mathbb{E}_\\pi [r + \\gamma V_t(s') | S_t = s]\n= \\sum_a \\pi(a \\vert s) \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_t(s'))\n$$\nPolicy Improvement\n#\nBased on the value functions, Policy Improvement generates a better policy $\\pi’ \\geq \\pi$ by acting greedily.\n$$\nQ_\\pi(s, a) \n= \\mathbb{E} [R_{t+1} + \\gamma V_\\pi(S_{t+1}) \\vert S_t=s, A_t=a]\n= \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_\\pi(s'))\n$$\nPolicy Iteration\n#\nThe\nGeneralized Policy Iteration (GPI)\nalgorithm refers to an iterative procedure to improve the policy when combining policy evaluation and improvement.\n$$\n\\pi_0 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_0} \\xrightarrow[]{\\text{improve}}\n\\pi_1 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_1} \\xrightarrow[]{\\text{improve}}\n\\pi_2 \\xrightarrow[]{\\text{evaluation}} \\dots \\xrightarrow[]{\\text{improve}}\n\\pi_* \\xrightarrow[]{\\text{evaluation}} V_*\n$$\nIn GPI, the value function is approximated repeatedly to be closer to the true value of the current policy and in the meantime, the policy is improved repeatedly to approach optimality. This policy iteration process works and always converges to the optimality, but why this is the case?\nSay, we have a policy $\\pi$ and then generate an improved version $\\pi’$ by greedily taking actions, $\\pi’(s) = \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)$. The value of this improved $\\pi’$ is guaranteed to be better because:\n$$\n\\begin{aligned}\nQ_\\pi(s, \\pi'(s))\n&= Q_\\pi(s, \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)) \\\\\n&= \\max_{a \\in \\mathcal{A}} Q_\\pi(s, a) \\geq Q_\\pi(s, \\pi(s)) = V_\\pi(s)\n\\end{aligned}\n$$\nMonte-Carlo Methods\n#\nFirst, let’s recall that $V(s) = \\mathbb{E}[ G_t \\vert S_t=s]$. Monte-Carlo (MC) methods uses a simple idea: It learns from episodes of raw experience without modeling the environmental dynamics and computes the observed mean return as an approximation of the expected return. To compute the empirical return $G_t$, MC methods need to learn from\ncomplete\nepisodes $S_1, A_1, R_2, \\dots, S_T$ to compute $G_t = \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1}$ and all the episodes must eventually terminate.\nThe empirical mean return for state s is:\n$$\nV(s) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s]}\n$$\nwhere $\\mathbb{1}[S_t = s]$ is a binary indicator function. We may count the visit of state s every time so that there could exist multiple visits of one state in one episode (“every-visit”), or only count it the first time we encounter a state in one episode (“first-visit”). This way of approximation can be easily extended to action-value functions by counting (s, a) pair.\n$$\nQ(s, a) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}\n$$\nTo learn the optimal policy by MC, we iterate it by following a similar idea to\nGPI\n.\nImprove the policy greedily with respect to the current value function: $\\pi(s) = \\arg\\max_{a \\in \\mathcal{A}} Q(s, a)$.\nGenerate a new episode with the new policy $\\pi$ (i.e. using algorithms like\nε-greedy\nhelps us balance between exploitation and exploration.)\nEstimate Q using the new episode: $q_\\pi(s, a) = \\frac{\\sum_{t=1}^T \\big( \\mathbb{1}[S_t = s, A_t = a] \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1} \\big)}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}$\nTemporal-Difference Learning\n#\nSimilar to Monte-Carlo methods, Temporal-Difference (TD) Learning is model-free and learns from episodes of experience. However, TD learning can learn from\nincomplete\nepisodes and hence we don’t need to track the episode up to termination. TD learning is so important that Sutton & Barto (2017) in their RL book describes it as “one idea … central and novel to reinforcement learning”.\nBootstrapping\n#\nTD learning methods update targets with regard to existing estimates rather than exclusively relying on actual rewards and complete returns as in MC methods. This approach is known as\nbootstrapping\n.\nValue Estimation\n#\nThe key idea in TD learning is to update the value function $V(S_t)$ towards an estimated return $R_{t+1} + \\gamma V(S_{t+1})$ (known as “\nTD target\n”). To what extent we want to update the value function is controlled by the learning rate hyperparameter α:\n$$\n\\begin{aligned}\nV(S_t) &\\leftarrow (1- \\alpha) V(S_t) + \\alpha G_t \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (G_t - V(S_t)) \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (R_{t+1} + \\gamma V(S_{t+1}) - V(S_t))\n\\end{aligned}\n$$\nSimilarly, for action-value estimation:\n$$\nQ(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t))\n$$\nNext, let’s dig into the fun part on how to learn optimal policy in TD learning (aka “TD control”). Be prepared, you are gonna see many famous names of classic algorithms in this section.\nSARSA: On-Policy TD control\n#\n“SARSA” refers to the procedure of updaing Q-value by following a sequence of $\\dots, S_t, A_t, R_{t+1}, S_{t+1}, A_{t+1}, \\dots$. The idea follows the same route of\nGPI\n. Within one episode, it works as follows:\nInitialize $t=0$.\nStart with $S_0$ and choose action $A_0 = \\arg\\max_{a \\in \\mathcal{A}} Q(S_0, a)$, where\n$\\epsilon$-greedy\nis commonly applied.\nAt time $t$, after applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nThen pick the next action in the same way as in step 2: $A_{t+1} = \\arg\\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a)$.\nUpdate the Q-value function: $ Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t)) $.\nSet $t = t+1$ and repeat from step 3.\nIn each step of SARSA, we need to choose the\nnext\naction according to the\ncurrent\npolicy.\nQ-Learning: Off-policy TD control\n#\nThe development of Q-learning (\nWatkins & Dayan, 1992\n) is a big breakout in the early days of Reinforcement Learning. Within one episode, it works as follows:\nInitialize $t=0$.\nStarts with $S_0$.\nAt time step $t$, we pick the action according to Q values, $A_t = \\arg\\max_{a \\in \\mathcal{A}} Q(S_t, a)$ and $\\epsilon$-greedy is commonly applied.\nAfter applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nUpdate the Q-value function: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma \\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a) - Q(S_t, A_t))$.\n$t = t+1$ and repeat from step 3.\nThe key difference from SARSA is that Q-learning does not follow the current policy to pick the second action $A_{t+1}$. It estimates $Q^*$ out of the best Q values, but which action (denoted as $a^*$) leads to this maximal Q does not matter and in the next step Q-learning may not follow $a^*$.\nThe backup diagrams for Q-learning and SARSA. (Image source: Replotted based on Figure 6.5 in Sutton & Barto (2017))\nDeep Q-Network\n#\nTheoretically, we can memorize $Q_*(.)$ for all state-action pairs in Q-learning, like in a gigantic table. However, it quickly becomes computationally infeasible when the state and action space are large. Thus people use functions (i.e. a machine learning model) to approximate Q values and this is called\nfunction approximation\n. For example, if we use a function with parameter $\\theta$ to calculate Q values, we can label Q value function as $Q(s, a; \\theta)$.\nUnfortunately Q-learning may suffer from instability and divergence when combined with an nonlinear Q-value function approximation and\nbootstrapping\n(See\nProblems #2\n).\nDeep Q-Network (“DQN”; Mnih et al. 2015) aims to greatly improve and stabilize the training procedure of Q-learning by two innovative mechanisms:\nExperience Replay\n: All the episode steps $e_t = (S_t, A_t, R_t, S_{t+1})$ are stored in one replay memory $D_t = \\{ e_1, \\dots, e_t \\}$. $D_t$ has experience tuples over many episodes. During Q-learning updates, samples are drawn at random from the replay memory and thus one sample could be used multiple times. Experience replay improves data efficiency, removes correlations in the observation sequences, and smooths over changes in the data distribution.\nPeriodically Updated Target\n: Q is optimized towards target values that are only periodically updated. The Q network is cloned and kept frozen as the optimization target every C steps (C is a hyperparameter). This modification makes the training more stable as it overcomes the short-term oscillations.\nThe loss function looks like this:\n$$\n\\mathcal{L}(\\theta) = \\mathbb{E}_{(s, a, r, s') \\sim U(D)} \\Big[ \\big( r + \\gamma \\max_{a'} Q(s', a'; \\theta^{-}) - Q(s, a; \\theta) \\big)^2 \\Big]\n$$\nwhere $U(D)$ is a uniform distribution over the replay memory D; $\\theta^{-}$ is the parameters of the frozen target Q-network.\nIn addition, it is also found to be helpful to clip the error term to be between [-1, 1]. (I always get mixed feeling with parameter clipping, as many studies have shown that it works empirically but it makes the math much less pretty. :/)\nAlgorithm for DQN with experience replay and occasionally frozen optimization target. The prepossessed sequence is the output of some processes running on the input images of Atari games. Don't worry too much about it; just consider them as input feature vectors. (Image source: Mnih et al. 2015)\nThere are many extensions of DQN to improve the original design, such as DQN with dueling architecture (Wang et al. 2016) which estimates state-value function V(s) and advantage function A(s, a) with shared network parameters.\nCombining TD and MC Learning\n#\nIn the previous\nsection\non value estimation in TD learning, we only trace one step further down the action chain when calculating the TD target. One can easily extend it to take multiple steps to estimate the return.\nLet’s label the estimated return following n steps as $G_t^{(n)}, n=1, \\dots, \\infty$, then:\n$n$\n$G_t$\nNotes\n$n=1$\n$G_t^{(1)} = R_{t+1} + \\gamma V(S_{t+1})$\nTD learning\n$n=2$\n$G_t^{(2)} = R_{t+1} + \\gamma R_{t+2} + \\gamma^2 V(S_{t+2})$\n…\n$n=n$\n$ G_t^{(n)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1} R_{t+n} + \\gamma^n V(S_{t+n}) $\n…\n$n=\\infty$\n$G_t^{(\\infty)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{T-t-1} R_T + \\gamma^{T-t} V(S_T) $\nMC estimation\nThe generalized n-step TD learning still has the\nsame\nform for updating the value function:\n$$\nV(S_t) \\leftarrow V(S_t) + \\alpha (G_t^{(n)} - V(S_t))\n$$\nWe are free to pick any $n$ in TD learning as we like. Now the question becomes what is the best $n$? Which $G_t^{(n)}$ gives us the best return approximation? A common yet smart solution is to apply a weighted sum of all possible n-step TD targets rather than to pick a single best n. The weights decay by a factor λ with n, $\\lambda^{n-1}$; the intuition is similar to\nwhy\nwe want to discount future rewards when computing the return: the more future we look into the less confident we would be. To make all the weight (n → ∞) sum up to 1, we multiply every weight by (1-λ), because:\n$$\n\\begin{aligned}\n\\text{let } S &= 1 + \\lambda + \\lambda^2 + \\dots \\\\\nS &= 1 + \\lambda(1 + \\lambda + \\lambda^2 + \\dots) \\\\\nS &= 1 + \\lambda S \\\\\nS &= 1 / (1-\\lambda)\n\\end{aligned}\n$$\nThis weighted sum of many n-step returns is called λ-return $G_t^{\\lambda} = (1-\\lambda) \\sum_{n=1}^{\\infty} \\lambda^{n-1} G_t^{(n)}$. TD learning that adopts λ-return for value updating is labeled as\nTD(λ)\n. The original version we introduced\nabove\nis equivalent to\nTD(0)\n.\nComparison of the backup diagrams of Monte-Carlo, Temporal-Difference learning, and Dynamic Programming for state value functions. (Image source: David Silver's RL course\nlecture 4\n: \"Model-Free Prediction\")\nPolicy Gradient\n#\nAll the methods we have introduced above aim to learn the state/action value function and then to select actions accordingly. Policy Gradient methods instead learn the policy directly with a parameterized function respect to $\\theta$, $\\pi(a \\vert s; \\theta)$. Let’s define the reward function (opposite of loss function) as\nthe expected return\nand train the algorithm with the goal to maximize the reward function. My\nnext post\ndescribed why the policy gradient theorem works (proof) and introduced a number of policy gradient algorithms.\nIn discrete space:\n$$\n\\mathcal{J}(\\theta) = V_{\\pi_\\theta}(S_1) = \\mathbb{E}_{\\pi_\\theta}[V_1]\n$$\nwhere $S_1$ is the initial starting state.\nOr in continuous space:\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) V_{\\pi_\\theta}(s) = \\sum_{s \\in \\mathcal{S}} \\Big( d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s, \\theta) Q_\\pi(s, a) \\Big)\n$$\nwhere $d_{\\pi_\\theta}(s)$ is stationary distribution of Markov chain for $\\pi_\\theta$. If you are unfamiliar with the definition of a “stationary distribution,” please check this\nreference\n.\nUsing\ngradient ascent\nwe can find the best θ that produces the highest return. It is natural to expect policy-based methods are more useful in continuous space, because there is an infinite number of actions and/or states to estimate the values for in continuous space and hence value-based approaches are computationally much more expensive.\nPolicy Gradient Theorem\n#\nComputing the gradient\nnumerically\ncan be done by perturbing θ by a small amount ε in the k-th dimension. It works even when $J(\\theta)$ is not differentiable (nice!), but unsurprisingly very slow.\n$$\n\\frac{\\partial \\mathcal{J}(\\theta)}{\\partial \\theta_k} \\approx \\frac{\\mathcal{J}(\\theta + \\epsilon u_k) - \\mathcal{J}(\\theta)}{\\epsilon}\n$$\nOr\nanalytically\n,\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [r] = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) R(s, a)\n$$\nActually we have nice theoretical support for (replacing $d(.)$ with $d_\\pi(.)$):\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\propto \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a)\n$$\nCheck Sec 13.1 in Sutton & Barto (2017) for why this is the case.\nThen,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n\\nabla \\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\nabla \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n&= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\frac{\\nabla \\pi(a \\vert s; \\theta)}{\\pi(a \\vert s; \\theta)} Q_\\pi(s, a) \\\\\n& = \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n& = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a)]\n\\end{aligned}\n$$\nThis result is named “Policy Gradient Theorem” which lays the theoretical foundation for various policy gradient algorithms:\n$$\n\\nabla \\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s, \\theta) Q_\\pi(s, a)]\n$$\nREINFORCE\n#\nREINFORCE, also known as Monte-Carlo policy gradient, relies on $Q_\\pi(s, a)$, an estimated return by\nMC\nmethods using episode samples, to update the policy parameter $\\theta$.\nA commonly used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to reduce the variance of gradient estimation while keeping the bias unchanged. For example, a common baseline is state-value, and if applied, we would use $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update.\nInitialize θ at random\nGenerate one episode $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$\nFor t=1, 2, … , T:\nEstimate the the return G_t since the time step t.\n$\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla \\ln \\pi(A_t \\vert S_t, \\theta)$.\nActor-Critic\n#\nIf the value function is learned in addition to the policy, we would get Actor-Critic algorithm.\nCritic\n: updates value function parameters w and depending on the algorithm it could be action-value $Q(a \\vert s; w)$ or state-value $V(s; w)$.\nActor\n: updates policy parameters θ, in the direction suggested by the critic, $\\pi(a \\vert s; \\theta)$.\nLet’s see how it works in an action-value actor-critic algorithm.\nInitialize s, θ, w at random; sample $a \\sim \\pi(a \\vert s; \\theta)$.\nFor t = 1… T:\nSample reward $r_t  \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$.\nThen sample the next action $a’ \\sim \\pi(s’, a’; \\theta)$.\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q(s, a; w) \\nabla_\\theta \\ln \\pi(a \\vert s; \\theta)$.\nCompute the correction for action-value at time t:\n$G_{t:t+1} = r_t + \\gamma Q(s’, a’; w) - Q(s, a; w)$\nand use it to update value function parameters:\n$w \\leftarrow w + \\alpha_w G_{t:t+1} \\nabla_w Q(s, a; w) $.\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\n$\\alpha_\\theta$ and $\\alpha_w$ are two learning rates for policy and value function parameter updates, respectively.\nA3C\n#\nAsynchronous Advantage Actor-Critic\n(Mnih et al., 2016), short for A3C, is a classic policy gradient method with the special focus on parallel training.\nIn A3C, the critics learn the state-value function, $V(s; w)$, while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is good for parallel training by default, i.e. on one machine with multi-core CPU.\nThe loss function for state-value is to minimize the mean squared error, $\\mathcal{J}_v (w) = (G_t - V(s; w))^2$ and we use gradient descent to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, θ and w; similar thread-specific parameters, θ’ and w'.\nInitialize the time step t = 1\nWhile T <= T_MAX:\nReset gradient: dθ = 0 and dw = 0.\nSynchronize thread-specific parameters with global ones: θ’ = θ and w’ = w.\n$t_\\text{start}$ = t and get $s_t$.\nWhile ($s_t \\neq \\text{TERMINAL}$) and ($t - t_\\text{start} <= t_\\text{max}$):\nPick the action $a_t \\sim \\pi(a_t \\vert s_t; \\theta’)$ and receive a new reward $r_t$ and a new state $s_{t+1}$.\nUpdate t = t + 1 and T = T + 1.\nInitialize the variable that holds the return estimation $$R = \\begin{cases}\n0 & \\text{if } s_t \\text{ is TERMINAL} \\\nV(s_t; w’) & \\text{otherwise}\n\\end{cases}$$.\nFor $i = t-1, \\dots, t_\\text{start}$:\n$R \\leftarrow r_i + \\gamma R$; here R is a MC measure of $G_i$.\nAccumulate gradients w.r.t. θ’: $d\\theta \\leftarrow d\\theta + \\nabla_{\\theta’} \\log \\pi(a_i \\vert s_i; \\theta’)(R - V(s_i; w’))$;\nAccumulate gradients w.r.t. w’: $dw \\leftarrow dw + \\nabla_{w’} (R - V(s_i; w’))^2$.\nUpdate synchronously θ using dθ, and w using dw.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a reformation of minibatch-based stochastic gradient update: the values of w or θ get corrected by a little bit in the direction of each training thread independently.\nEvolution Strategies\n#\nEvolution Strategies\n(ES) is a type of model-agnostic optimization approach. It learns the optimal solution by imitating Darwin’s theory of the evolution of species by natural selection. Two prerequisites for applying ES: (1) our solutions can freely interact with the environment and see whether they can solve the problem; (2) we are able to compute a\nfitness\nscore of how good each solution is. We don’t have to know the environment configuration to solve the problem.\nSay, we start with a population of random solutions. All of them are capable of interacting with the environment and only candidates with high fitness scores can survive (\nonly the fittest can survive in a competition for limited resources\n). A new generation is then created by recombining the settings (\ngene mutation\n) of high-fitness survivors. This process is repeated until the new solutions are good enough.\nVery different from the popular MDP-based approaches as what we have introduced above, ES aims to learn the policy parameter $\\theta$ without value approximation. Let’s assume the distribution over the parameter $\\theta$ is an\nisotropic\nmultivariate Gaussian with mean $\\mu$ and fixed covariance $\\sigma^2I$. The gradient of $F(\\theta)$ is calculated:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} F(\\theta) \\\\\n=& \\nabla_\\theta \\int_\\theta F(\\theta) \\Pr(\\theta) && \\text{Pr(.) is the Gaussian density function.} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\frac{\\nabla_\\theta \\Pr(\\theta)}{\\Pr(\\theta)} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\nabla_\\theta \\log \\Pr(\\theta) \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} [F(\\theta) \\nabla_\\theta \\log \\Pr(\\theta)] && \\text{Similar to how we do policy gradient update.} \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\log \\Big( \\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(\\theta - \\mu)^2}{2 \\sigma^2 }} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\Big( -\\log \\sqrt{2\\pi\\sigma^2} - \\frac{(\\theta - \\mu)^2}{2 \\sigma^2} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\frac{\\theta - \\mu}{\\sigma^2} \\Big]\n\\end{aligned}\n$$\nWe can rewrite this formula in terms of a “mean” parameter $\\theta$ (different from the $\\theta$ above; this $\\theta$ is the base gene for further mutation), $\\epsilon \\sim N(0, I)$ and therefore $\\theta + \\epsilon \\sigma \\sim N(\\theta, \\sigma^2)$. $\\epsilon$ controls how much Gaussian noises should be added to create mutation:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\epsilon \\sim N(0, I)} F(\\theta + \\sigma \\epsilon) = \\frac{1}{\\sigma} \\mathbb{E}_{\\epsilon \\sim N(0, I)} [F(\\theta + \\sigma \\epsilon) \\epsilon]\n$$\nA simple parallel evolution-strategies-based RL algorithm. Parallel workers share the random seeds so that they can reconstruct the Gaussian noises with tiny communication bandwidth. (Image source: Salimans et al. 2017.)\nES, as a black-box optimization algorithm, is another approach to RL problems (\nIn my original writing, I used the phrase “a nice alternative”;\nSeita\npointed me to this\ndiscussion\nand thus I updated my wording.\n). It has a couple of good characteristics (Salimans et al., 2017) keeping it fast and easy to train:\nES does not need value function approximation;\nES does not perform gradient back-propagation;\nES is invariant to delayed or long-term rewards;\nES is highly parallelizable with very little data communication.\nKnown Problems\n#\nExploration-Exploitation Dilemma\n#\nThe problem of exploration vs exploitation dilemma has been discussed in my previous\npost\n. When the RL problem faces an unknown environment, this issue is especially a key to finding a good solution: without enough exploration, we cannot learn the environment well enough; without enough exploitation, we cannot complete our reward optimization task.\nDifferent RL algorithms balance between exploration and exploitation in different ways. In\nMC\nmethods,\nQ-learning\nor many on-policy algorithms, the exploration is commonly implemented by\nε-greedy\n; In\nES\n, the exploration is captured by the policy parameter perturbation. Please keep this into consideration when developing a new RL algorithm.\nDeadly Triad Issue\n#\nWe do seek the efficiency and flexibility of TD methods that involve bootstrapping. However, when off-policy, nonlinear function approximation, and bootstrapping are combined in one RL algorithm, the training could be unstable and hard to converge. This issue is known as the\ndeadly triad\n(Sutton & Barto, 2017). Many architectures using deep learning models were proposed to resolve the problem, including DQN to stabilize the training with experience replay and occasionally frozen target network.\nCase Study: AlphaGo Zero\n#\nThe game of\nGo\nhas been an extremely hard problem in the field of Artificial Intelligence for decades until recent years. AlphaGo and AlphaGo Zero are two programs developed by a team at DeepMind. Both involve deep Convolutional Neural Networks (\nCNN\n) and Monte Carlo Tree Search (MCTS) and both have been approved to achieve the level of professional human Go players. Different from AlphaGo that relied on supervised learning from expert human moves, AlphaGo Zero used only reinforcement learning and self-play without human knowledge beyond the basic rules.\nThe board of Go. Two players play black and white stones alternatively on the vacant intersections of a board with 19 x 19 lines. A group of stones must have at least one open point (an intersection, called a \"liberty\") to remain on the board and must have at least two or more enclosed liberties (called \"eyes\") to stay \"alive\". No stone shall repeat a previous position.\nWith all the knowledge of RL above, let’s take a look at how AlphaGo Zero works. The main component is a deep\nCNN\nover the game board configuration (precisely, a\nResNet\nwith batch normalization and ReLU). This network outputs two values:\n$$\n(p, v) = f_\\theta(s)\n$$\n$s$: the game board configuration, 19 x 19 x 17 stacked feature planes; 17 features for each position, 8 past configurations (including current) for the current player + 8 past configurations for the opponent + 1 feature indicating the color (1=black, 0=white). We need to code the color specifically because the network is playing with itself and the colors of current player and opponents are switching between steps.\n$p$: the probability of selecting a move over 19^2 + 1 candidates (19^2 positions on the board, in addition to passing).\n$v$: the winning probability given the current setting.\nDuring self-play, MCTS further improves the action probability distribution $\\pi \\sim p(.)$ and then the action $a_t$ is sampled from this improved policy. The reward $z_t$ is a binary value indicating whether the current player\neventually\nwins the game. Each move generates an episode tuple $(s_t, \\pi_t, z_t)$ and it is saved into the replay memory. The details on MCTS are skipped for the sake of space in this post; please read the original\npaper\nif you are interested.\nAlphaGo Zero is trained by self-play while MCTS improves the output policy further in every step. (Image source: Figure 1a in Silver et al., 2017).\nThe network is trained with the samples in the replay memory to minimize the loss:\n$$\n\\mathcal{L} = (z - v)^2 - \\pi^\\top \\log p + c \\| \\theta \\|^2\n$$\nwhere $c$ is a hyperparameter controlling the intensity of L2 penalty to avoid overfitting.\nAlphaGo Zero simplified AlphaGo by removing supervised learning and merging separated policy and value networks into one. It turns out that AlphaGo Zero achieved largely improved performance with a much shorter training time! I strongly recommend reading these\ntwo\npapers\nside by side and compare the difference, super fun.\nI know this is a long read, but hopefully worth it.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com].\nSee you in the next post! :)\nCited as:\n@article{weng2018bandit,\n  title   = \"A (Long) Peek into Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-02-19-rl-overview/\"\n}\nReferences\n#\n[1] Yuxi Li.\nDeep reinforcement learning: An overview.\narXiv preprint arXiv:1701.07274. 2017.\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] Volodymyr Mnih, et al.\nAsynchronous methods for deep reinforcement learning.\nICML. 2016.\n[4] Tim Salimans, et al.\nEvolution strategies as a scalable alternative to reinforcement learning.\narXiv preprint arXiv:1703.03864 (2017).\n[5] David Silver, et al.\nMastering the game of go without human knowledge\n. Nature 550.7676 (2017): 354.\n[6] David Silver, et al.\nMastering the game of Go with deep neural networks and tree search.\nNature 529.7587 (2016): 484-489.\n[7] Volodymyr Mnih, et al.\nHuman-level control through deep reinforcement learning.\nNature 518.7540 (2015): 529.\n[8] Ziyu Wang, et al.\nDueling network architectures for deep reinforcement learning.\nICML. 2016.\n[9]\nReinforcement Learning lectures\nby David Silver on YouTube.\n[10] OpenAI Blog:\nEvolution Strategies as a Scalable Alternative to Reinforcement Learning\n[11] Frank Sehnke, et al.\nParameter-exploring policy gradients.\nNeural Networks 23.4 (2010): 551-559.\n[12] Csaba Szepesvári.\nAlgorithms for reinforcement learning.\n1st Edition. Synthesis lectures on artificial intelligence and machine learning 4.1 (2010): 1-103.\nIf you notice mistakes and errors in this post, please don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be super happy to correct them right away!",
            "metadata": {
              "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
              "description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "A (Long) Peek into Reinforcement Learning",
              "og:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
              "twitter:card": "summary",
              "twitter:title": "A (Long) Peek into Reinforcement Learning",
              "twitter:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "article:section": "posts",
              "article:published_time": "2018-02-19T00:00:00+00:00",
              "article:modified_time": "2018-02-19T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/9e1d58627b38/code/body-000.txt",
                "chars": 241,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "bytes": 58269,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-418c8992a5cc9d9deeb1.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "bytes": 107025,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d53eaab123d7a3b8d561.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "bytes": 33772,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-1a3ee27cdec9dd4e95e7.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "bytes": 55693,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8b930e0942e1d249d7cd.jpg",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "bytes": 27143,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-508e643f8751bb71fcf3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "bytes": 32728,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-aa4ac628fe85693e0ba3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "bytes": 21618,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8917c12943284b1507b6.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "bytes": 133435,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-c1fcc0568374ce65ea91.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "bytes": 35850,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-be7712dd68a63d561005.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "bytes": 128382,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d374974862f12f0f0ada.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "bytes": 91431,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-0d8b962a59d7ad31b2ef.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "bytes": 136647,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-3ceb5a7713444f264e70.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "bytes": 61555,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-070437b06f4b4d8a0287.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=2pWv7GOvuf0",
                "src": "https://youtu.be/2pWv7GOvuf0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/9e1d58627b38/videos/repair-2pWv7GOvuf0.mp4",
                "bytes": 397520008,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5292.421000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "src": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "status": "playlist_discovery_failed",
                "kind": "playlist",
                "reason": "播放列表返回空或不完整结果，保留原记录并等待重试",
                "error": "WARNING: [youtube:tab] YouTube said: The playlist does not exist.\nERROR: [youtube:tab] PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT: YouTube said: The playlist does not exist.\n",
                "retried_at": "2026-10-20T22:23:33Z"
              }
            ],
            "links": [
              {
                "href": "https://paperexplained.cn/articles/article/detail/33/",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dynamic_programming",
                "label": "Dynamic Programming",
                "type": "a"
              },
              {
                "href": "https://youtu.be/2pWv7GOvuf0",
                "label": "lecture 1",
                "type": "a"
              },
              {
                "href": "https://randomant.net/reinforcement-learning-concepts/",
                "label": "randomant.net/reinforcement-learning-concepts",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "ε-greedy",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "label": "Watkins & Dayan, 1992",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "label": "lecture 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "next post",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "reference",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolution Strategies",
                "type": "a"
              },
              {
                "href": "https://math.stackexchange.com/questions/1991961/gaussian-distribution-is-isotropic",
                "label": "isotropic",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/",
                "label": "Seita",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/r/MachineLearning/comments/6gke6a/d_requesting_openai_to_justify_the_grandiose/dir9wde/",
                "label": "discussion",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Go_(game)",
                "label": "Go",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "CNN",
                "type": "a"
              },
              {
                "href": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "label": "two",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07274.pdf",
                "label": "Deep reinforcement learning: An overview.",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Reinforcement Learning: An Introduction; 2nd Edition",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "label": "Asynchronous methods for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.03864.pdf",
                "label": "Evolution strategies as a scalable alternative to reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "label": "Human-level control through deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.06581.pdf",
                "label": "Dueling network architectures for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "label": "Reinforcement Learning lectures",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/evolution-strategies/",
                "label": "Evolution Strategies as a Scalable Alternative to Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "label": "Parameter-exploring policy gradients.",
                "type": "a"
              },
              {
                "href": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "label": "Algorithms for reinforcement learning.",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:33Z",
            "source_url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "papers": [
              {
                "status": "invalid_file_type",
                "url": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:14Z"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "retried_at": "2026-10-20T17:36:31Z"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07274.pdf",
                "bytes": 1380080,
                "reused": false,
                "local_path": "papers/repair/b6ffc91d59527939bdfc.pdf"
              },
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": true,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "bytes": 2455923,
                "reused": false,
                "local_path": "papers/repair/de6e461fa7ff09fc7981.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864.pdf",
                "bytes": 277340,
                "reused": false,
                "local_path": "papers/repair/d7a6ba3d9a896a29908d.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "bytes": 4600582,
                "reused": false,
                "local_path": "papers/repair/a86f4e3a12fbcea87e0c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06581.pdf",
                "bytes": 688509,
                "reused": false,
                "local_path": "papers/repair/f1c991f0c8eda83cb980.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "bytes": 1623436,
                "reused": false,
                "local_path": "papers/repair/fbf59542cdbde527181b.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 40855,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404；invalid_file_type；playlist_discovery_failed",
            "raw_html": "attachments/9e1d58627b38/pages/source.html",
            "local_html": "attachments/9e1d58627b38/pages/article.html",
            "body_base_path": "attachments/9e1d58627b38/pages/",
            "body_markdown_path": "attachments/9e1d58627b38/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
          "status": "partial",
          "article_id": "1c9291c74af3",
          "local_path": "series-follow/1602/repair/7ed03d41ab2c6b4d9091.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
              "bytes": 2159899,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8571ab535bf08b3eb897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
              "bytes": 36779,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/244663c064863ba3add1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
              "bytes": 163006,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/417a080a721a8da35e76.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
              "bytes": 360658,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7a8e772d26ca2075d030.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
              "bytes": 329846,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a79121328d38f1e7decb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
              "bytes": 1061108,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/217a917d5b695d69920e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
              "bytes": 3290656,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/16ff0e0557cd1ec7183b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
              "bytes": 190907,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/68ed274d29e23ec04058.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
              "bytes": 20601,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1602/repair/assets/f7ff47f8ed0c85c31c04.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
              "bytes": 194344,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d885b9f00fc903916eff.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
              "bytes": 236994,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/43b2947b31f475b9d117.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
              "bytes": 476899,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/202d6793b7b96d2f655a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
              "bytes": 401199,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/47a02b382f80dc9a2137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d314a0ab86b5abc9e45b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
              "bytes": 136297,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5bee749c4008d551aef3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
              "bytes": 198560,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9686a8baee36d438f09c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7cfc826648a35a656e03.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
              "bytes": 485628,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4f9fa106ff81362212ba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
              "bytes": 124592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3442cdcfc8a317d5e9cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
              "bytes": 392406,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d18eeaedd090128a06bf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
              "bytes": 3409897,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/82aaa856d170c7aa0cea.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Attention? Attention!",
            "keywords": "注意力机制,自注意力,多头",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "publish_date": "2018-06",
            "corpus_stage": "预训练/SFT",
            "notes": "注意力机制经典综述",
            "id": "1c9291c74af3",
            "collected_at": "2026-10-02T14:13:17",
            "title": "Attention? Attention! | Lil'Log",
            "body_markdown": "[Updated on 2018-10-28: Add\nPointer Network\nand the\nlink\nto my implementation of Transformer.]\n[Updated on 2018-11-06: Add a\nlink\nto the implementation of Transformer model.]\n[Updated on 2018-11-18: Add\nNeural Turing Machines\n.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the\nshow-attention-tell\npaper; moved it to\nSelf-Attention\nsection.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is\nhere\n.]\nAttention is, to some extent, motivated by how we pay visual attention to different regions of an image or correlate words in one sentence. Take the picture of a Shiba Inu in Fig. 1 as an example.\nA Shiba Inu in a men’s outfit. The credit of the original photo goes to Instagram\n@mensweardog\n.\nHuman visual attention allows us to focus on a certain region with “high resolution” (i.e. look at the pointy ear in the yellow box) while perceiving the surrounding image in “low resolution” (i.e. now how about the snowy background and the outfit?), and then adjust the focal point or do the inference accordingly. Given a small patch of an image, pixels in the rest provide clues what should be displayed there. We expect to see a pointy ear in the yellow box because we have seen a dog’s nose, another pointy ear on the right, and Shiba’s mystery eyes (stuff in the red boxes). However, the sweater and blanket at the bottom would not be as helpful as those doggy features.\nSimilarly, we can explain the relationship between words in one sentence or close context. When we see “eating”, we expect to encounter a food word very soon. The color term describes the food, but probably not so much with “eating” directly.\nOne word \"attends\" to other words in the same sentence differently.\nIn a nutshell, attention in deep learning can be broadly interpreted as a vector of importance weights: in order to predict or infer one element, such as a pixel in an image or a word in a sentence, we estimate using the attention vector how strongly it is correlated with (or “\nattends to\n” as you may have read in many papers) other elements and take the sum of their values weighted by the attention vector as the approximation of the target.\nWhat’s Wrong with Seq2Seq Model?\n#\nThe\nseq2seq\nmodel was born in the field of language modeling (\nSutskever, et al. 2014\n). Broadly speaking, it aims to transform an input sequence (source) to a new one (target) and both sequences can be of arbitrary lengths. Examples of transformation tasks include machine translation between multiple languages in either text or audio, question-answer dialog generation, or even parsing sentences into grammar trees.\nThe seq2seq model normally has an encoder-decoder architecture, composed of:\nAn\nencoder\nprocesses the input sequence and compresses the information into a context vector (also known as sentence embedding or “thought” vector) of a\nfixed length\n. This representation is expected to be a good summary of the meaning of the\nwhole\nsource sequence.\nA\ndecoder\nis initialized with the context vector to emit the transformed output. The early work only used the last state of the encoder network as the decoder initial state.\nBoth the encoder and decoder are recurrent neural networks, i.e. using\nLSTM or GRU\nunits.\nThe encoder-decoder model, translating the sentence \"she is eating a green apple\" to Chinese. The visualization of both encoder and decoder is unrolled in time.\nA critical and apparent disadvantage of this fixed-length context vector design is incapability of remembering long sentences. Often it has forgotten the first part once it completes processing the whole input. The attention mechanism was born (\nBahdanau et al., 2015\n) to resolve this problem.\nBorn for Translation\n#\nThe attention mechanism was born to help memorize long source sentences in neural machine translation (\nNMT\n). Rather than building a single context vector out of the encoder’s last hidden state, the secret sauce invented by attention is to create shortcuts between the context vector and the entire source input. The weights of these shortcut connections are customizable for each output element.\nWhile the context vector has access to the entire input sequence, we don’t need to worry about forgetting. The alignment between the source and target is learned and controlled by the context vector. Essentially the context vector consumes three pieces of information:\nencoder hidden states;\ndecoder hidden states;\nalignment between source and target.\nThe encoder-decoder model with additive attention mechanism in\nBahdanau et al., 2015\n.\nDefinition\n#\nNow let’s define the attention mechanism introduced in NMT in a scientific way. Say, we have a source sequence $\\mathbf{x}$ of length $n$ and try to output a target sequence $\\mathbf{y}$ of length $m$:\n$$\n\\begin{aligned}\n\\mathbf{x} &= [x_1, x_2, \\dots, x_n] \\\\\n\\mathbf{y} &= [y_1, y_2, \\dots, y_m]\n\\end{aligned}\n$$\n(Variables in bold indicate that they are vectors; same for everything else in this post.)\nThe encoder is a\nbidirectional RNN\n(or other recurrent network setting of your choice) with a forward hidden state $\\overrightarrow{\\boldsymbol{h}}_i$ and a backward one $\\overleftarrow{\\boldsymbol{h}}_i$. A simple concatenation of two represents the encoder state. The motivation is to include both the preceding and following words in the annotation of one word.\n$$\n\\boldsymbol{h}_i = [\\overrightarrow{\\boldsymbol{h}}_i^\\top; \\overleftarrow{\\boldsymbol{h}}_i^\\top]^\\top, i=1,\\dots,n\n$$\nThe decoder network has hidden state $\\boldsymbol{s}_t=f(\\boldsymbol{s}_{t-1}, y_{t-1}, \\mathbf{c}_t)$ for the output word at position t, $t=1,\\dots,m$, where the context vector $\\mathbf{c}_t$ is a sum of hidden states of the input sequence, weighted by alignment scores:\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\sum_{i=1}^n \\alpha_{t,i} \\boldsymbol{h}_i & \\small{\\text{; Context vector for output }y_t}\\\\\n\\alpha_{t,i} &= \\text{align}(y_t, x_i) & \\small{\\text{; How well two words }y_t\\text{ and }x_i\\text{ are aligned.}}\\\\\n&= \\frac{\\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_i))}{\\sum_{i'=1}^n \\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_{i'}))} & \\small{\\text{; Softmax of some predefined alignment score.}}.\n\\end{aligned}\n$$\nThe alignment model assigns a score $\\alpha_{t,i}$ to the pair of input at position i and output at position t, $(y_t, x_i)$, based on how well they match. The set of $\\{\\alpha_{t, i}\\}$ are weights defining how much of each source hidden state should be considered for each output. In Bahdanau’s paper, the alignment score $\\alpha$ is parametrized by a\nfeed-forward network\nwith a single hidden layer and this network is jointly trained with other parts of the model. The score function is therefore in the following form, given that tanh is used as the non-linear activation function:\n$$\n\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i])\n$$\nwhere both $\\mathbf{v}_a$ and $\\mathbf{W}_a$ are weight matrices to be learned in the alignment model.\nThe matrix of alignment scores is a nice byproduct to explicitly show the correlation between source and target words.\nAlignment matrix of \"L'accord sur l'Espace économique européen a été signé en août 1992\" (French) and its English translation \"The agreement on the European Economic Area was signed in August 1992\". (Image source: Fig 3 in\nBahdanau et al., 2015\n)\nCheck out this nice\ntutorial\nby Tensorflow team for more implementation instructions.\nA Family of Attention Mechanisms\n#\nWith the help of the attention, the dependencies between source and target sequences are not restricted by the in-between distance anymore! Given the big improvement by attention in machine translation, it soon got extended into the computer vision field (\nXu et al. 2015\n) and people started exploring various other forms of attention mechanisms (\nLuong, et al., 2015\n;\nBritz et al., 2017\n;\nVaswani, et al., 2017\n).\nSummary\n#\nBelow is a summary table of several popular attention mechanisms and corresponding alignment score functions:\nName\nAlignment score function\nCitation\nContent-base attention\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\text{cosine}[\\boldsymbol{s}_t, \\boldsymbol{h}_i]$\nGraves2014\nAdditive(*)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_{t-1}; \\boldsymbol{h}_i])$\nBahdanau2015\nLocation-Base\n$\\alpha_{t,i} = \\text{softmax}(\\mathbf{W}_a \\boldsymbol{s}_t)$\nNote: This simplifies the softmax alignment to only depend on the target position.\nLuong2015\nGeneral\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\mathbf{W}_a\\boldsymbol{h}_i$\nwhere $\\mathbf{W}_a$ is a trainable weight matrix in the attention layer.\nLuong2015\nDot-Product\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\boldsymbol{h}_i$\nLuong2015\nScaled Dot-Product(^)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\frac{\\boldsymbol{s}_t^\\top\\boldsymbol{h}_i}{\\sqrt{n}}$\nNote: very similar to the dot-product attention except for a scaling factor; where n is the dimension of the source hidden state.\nVaswani2017\n(*) Referred to as “concat” in Luong, et al., 2015 and as “additive attention” in Vaswani, et al., 2017.\n(^) It adds a scaling factor $1/\\sqrt{n}$, motivated by the concern when the input is large, the softmax function may have an extremely small gradient, hard for efficient learning.\nHere are a summary of broader categories of attention mechanisms:\nName\nDefinition\nCitation\nSelf-Attention(&)\nRelating different positions of the same input sequence. Theoretically the self-attention can adopt any score functions above, but just replace the target sequence with the same input sequence.\nCheng2016\nGlobal/Soft\nAttending to the entire input state space.\nXu2015\nLocal/Hard\nAttending to the part of input state space; i.e. a patch of the input image.\nXu2015\n;\nLuong2015\n(&) Also, referred to as “intra-attention” in Cheng et al., 2016 and some other papers.\nSelf-Attention\n#\nSelf-attention\n, also known as\nintra-attention\n, is an attention mechanism relating different positions of a single sequence in order to compute a representation of the same sequence. It has been shown to be very useful in machine reading, abstractive summarization, or image description generation.\nThe\nlong short-term memory network\npaper used self-attention to do machine reading. In the example below, the self-attention mechanism enables us to learn the correlation between the current words and the previous part of the sentence.\nThe current word is in red and the size of the blue shade indicates the activation level. (Image source:\nCheng et al., 2016\n)\nSoft vs Hard Attention\n#\nIn the\nshow, attend and tell\npaper, attention mechanism is applied to images to generate captions. The image is first encoded by a CNN to extract features. Then a LSTM decoder consumes the convolution features to produce descriptive words one by one, where the weights are learned through attention. The visualization of the attention weights clearly demonstrates which regions of the image the model is paying attention to so as to output a certain word.\n\"A woman is throwing a frisbee in a park.\" (Image source: Fig. 6(b) in\nXu et al. 2015\n)\nThis paper first proposed the distinction between “soft” vs “hard” attention, based on whether the attention has access to the entire image or only a patch:\nSoft\nAttention: the alignment weights are learned and placed “softly” over all patches in the source image; essentially the same type of attention as in\nBahdanau et al., 2015\n.\nPro\n: the model is smooth and differentiable.\nCon\n: expensive when the source input is large.\nHard\nAttention: only selects one patch of the image to attend to at a time.\nPro\n: less calculation at the inference time.\nCon\n: the model is non-differentiable and requires more complicated techniques such as variance reduction or reinforcement learning to train. (\nLuong, et al., 2015\n)\nGlobal vs Local Attention\n#\nLuong, et al., 2015\nproposed the “global” and “local” attention. The global attention is similar to the soft attention, while the local one is an interesting blend between\nhard and soft\n, an improvement over the hard attention to make it differentiable: the model first predicts a single aligned position for the current target word and a window centered around the source position is then used to compute a context vector.\nGlobal vs local attention (Image source: Fig 2 & 3 in\nLuong, et al., 2015\n)\nNeural Turing Machines\n#\nAlan Turing in\n1936\nproposed a minimalistic model of computation. It is composed of a infinitely long tape and a head to interact with the tape. The tape has countless cells on it, each filled with a symbol: 0, 1 or blank (\" “). The operation head can read symbols, edit symbols and move left/right on the tape. Theoretically a Turing machine can simulate any computer algorithm, irrespective of how complex or expensive the procedure might be. The infinite memory gives a Turing machine an edge to be mathematically limitless. However, infinite memory is not feasible in real modern computers and then we only consider Turing machine as a mathematical model of computation.\nHow a Turing machine looks like: a tape + a head that handles the tape. (Image source:\nhttp://aturingmachine.com/\n)\nNeural Turing Machine\n(\nNTM\n,\nGraves, Wayne & Danihelka, 2014\n) is a model architecture for coupling a neural network with external memory storage. The memory mimics the Turing machine tape and the neural network controls the operation heads to read from or write to the tape. However, the memory in NTM is finite, and thus it probably looks more like a “Neural\nvon Neumann\nMachine”.\nNTM contains two major components, a\ncontroller\nneural network and a\nmemory\nbank.\nController: is in charge of executing operations on the memory. It can be any type of neural network, feed-forward or recurrent.\nMemory: stores processed information. It is a matrix of size $N \\times M$, containing N vector rows and each has $M$ dimensions.\nIn one update iteration, the controller processes the input and interacts with the memory bank accordingly to generate output. The interaction is handled by a set of parallel\nread\nand\nwrite\nheads. Both read and write operations are “blurry” by softly attending to all the memory addresses.\nFig 10. Neural Turing Machine Architecture.\nReading and Writing\n#\nWhen reading from the memory at time t, an attention vector of size $N$, $\\mathbf{w}_t$ controls how much attention to assign to different memory locations (matrix rows). The read vector $\\mathbf{r}_t$ is a sum weighted by attention intensity:\n$$\n\\mathbf{r}_t = \\sum_{i=1}^N w_t(i)\\mathbf{M}_t(i)\\text{, where }\\sum_{i=1}^N w_t(i)=1, \\forall i: 0 \\leq w_t(i) \\leq 1\n$$\nwhere $w_t(i)$ is the $i$-th element in $\\mathbf{w}_t$ and $\\mathbf{M}_t(i)$ is the $i$-th row vector in the memory.\nWhen writing into the memory at time t, as inspired by the input and forget gates in LSTM, a write head first wipes off some old content according to an erase vector $\\mathbf{e}_t$ and then adds new information by an add vector $\\mathbf{a}_t$.\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{M}}_t(i) &= \\mathbf{M}_{t-1}(i) [\\mathbf{1} - w_t(i)\\mathbf{e}_t] &\\scriptstyle{\\text{; erase}}\\\\\n\\mathbf{M}_t(i) &= \\tilde{\\mathbf{M}}_t(i) + w_t(i) \\mathbf{a}_t &\\scriptstyle{\\text{; add}}\n\\end{aligned}\n$$\nAttention Mechanisms\n#\nIn Neural Turing Machine, how to generate the attention distribution $\\mathbf{w}_t$ depends on the addressing mechanisms: NTM uses a mixture of content-based and location-based addressings.\nContent-based addressing\nThe content-addressing creates attention vectors based on the similarity between the key vector $\\mathbf{k}_t$ extracted by the controller from the input and memory rows. The content-based attention scores are computed as cosine similarity and then normalized by softmax. In addition, NTM adds a strength multiplier $\\beta_t$ to amplify or attenuate the focus of the distribution.\n$$\nw_t^c(i) \n= \\text{softmax}(\\beta_t \\cdot \\text{cosine}[\\mathbf{k}_t, \\mathbf{M}_t(i)])\n= \\frac{\\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})}{\\sum_{j=1}^N \\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(j)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(j)\\|})}\n$$\nInterpolation\nThen an interpolation gate scalar $g_t$ is used to blend the newly generated content-based attention vector with the attention weights in the last time step:\n$$\n\\mathbf{w}_t^g = g_t \\mathbf{w}_t^c + (1 - g_t) \\mathbf{w}_{t-1} \n$$\nLocation-based addressing\nThe location-based addressing sums up the values at different positions in the attention vector, weighted by a weighting distribution over allowable integer shifts. It is equivalent to a 1-d convolution with a kernel $\\mathbf{s}_t(.)$, a function of the position offset. There are multiple ways to define this distribution. See for inspiration.\nTwo ways to represent the shift weighting distribution $\\mathbf{s}\\_t$.\nFinally the attention distribution is enhanced by a sharpening scalar $\\gamma_t \\geq 1$.\n$$\n\\begin{aligned}\n\\tilde{w}_t(i) &= \\sum_{j=1}^N w_t^g(j) s_t(i-j) & \\scriptstyle{\\text{; circular convolution}}\\\\\nw_t(i) &= \\frac{\\tilde{w}_t(i)^{\\gamma_t}}{\\sum_{j=1}^N \\tilde{w}_t(j)^{\\gamma_t}} & \\scriptstyle{\\text{; sharpen}}\n\\end{aligned}\n$$\nThe complete process of generating the attention vector $\\mathbf{w}_t$ at time step t is illustrated in All the parameters produced by the controller are unique for each head. If there are multiple read and write heads in parallel, the controller would output multiple sets.\nFlow diagram of the addressing mechanisms in Neural Turing Machine. (Image source:\nGraves, Wayne & Danihelka, 2014\n)\nPointer Network\n#\nIn problems like sorting or travelling salesman, both input and output are sequential data. Unfortunately, they cannot be easily solved by classic seq-2-seq or NMT models, given that the discrete categories of output elements are not determined in advance, but depends on the variable input size. The\nPointer Net\n(\nPtr-Net\n;\nVinyals, et al. 2015\n) is proposed to resolve this type of problems: When the output elements correspond to\npositions\nin an input sequence. Rather than using attention to blend hidden units of an encoder into a context vector (See Fig. 8), the Pointer Net applies attention over the input elements to pick one as the output at each decoder step.\nThe architecture of a Pointer Network model. (Image source:\nVinyals, et al. 2015\n)\nThe Ptr-Net outputs a sequence of integer indices, $\\boldsymbol{c} = (c_1, \\dots, c_m)$ given a sequence of input vectors $\\boldsymbol{x} = (x_1, \\dots, x_n)$ and $1 \\leq c_i \\leq n$. The model still embraces an encoder-decoder framework. The encoder and decoder hidden states are denoted as $(\\boldsymbol{h}_1, \\dots, \\boldsymbol{h}_n)$ and $(\\boldsymbol{s}_1, \\dots, \\boldsymbol{s}_m)$, respectively. Note that $\\mathbf{s}_i$ is the output gate after cell activation in the decoder. The Ptr-Net applies additive attention between states and then normalizes it by softmax to model the output conditional probability:\n$$\n\\begin{aligned}\ny_i &= p(c_i \\vert c_1, \\dots, c_{i-1}, \\boldsymbol{x}) \\\\\n    &= \\text{softmax}(\\text{score}(\\boldsymbol{s}_t; \\boldsymbol{h}_i)) = \\text{softmax}(\\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i]))\n\\end{aligned}\n$$\nThe attention mechanism is simplified, as Ptr-Net does not blend the encoder states into the output with attention weights. In this way, the output only responds to the positions but not the input content.\nTransformer\n#\n“Attention is All you Need”\n(Vaswani, et al., 2017), without a doubt, is one of the most impactful and interesting paper in 2017. It presented a lot of improvements to the soft attention and make it possible to do seq2seq modeling\nwithout\nrecurrent network units. The proposed “\ntransformer\n” model is entirely built on the self-attention mechanisms without using sequence-aligned recurrent architecture.\nThe secret recipe is carried in its model architecture.\nKey, Value and Query\n#\nThe major component in the transformer is the unit of\nmulti-head self-attention mechanism\n. The transformer views the encoded representation of the input as a set of\nkey\n-\nvalue\npairs, $(\\mathbf{K}, \\mathbf{V})$, both of dimension $n$ (input sequence length); in the context of NMT, both the keys and values are the encoder hidden states. In the decoder, the previous output is compressed into a\nquery\n($\\mathbf{Q}$ of dimension $m$) and the next output is produced by mapping this query and the set of keys and values.\nThe transformer adopts the\nscaled dot-product attention\n: the output is a weighted sum of the values, where the weight assigned to each value is determined by the dot-product of the query with all the keys:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{n}})\\mathbf{V}\n$$\nMulti-Head Self-Attention\n#\nMulti-head scaled dot-product attention mechanism. (Image source: Fig 2 in\nVaswani, et al., 2017\n)\nRather than only computing the attention once, the multi-head mechanism runs through the scaled dot-product attention multiple times in parallel. The independent attention outputs are simply concatenated and linearly transformed into the expected dimensions. I assume the motivation is because ensembling always helps? ;) According to the paper,\n“multi-head attention allows the model to jointly attend to information from different representation\nsubspaces\nat different positions. With a single attention head, averaging inhibits this.”\n$$\n\\begin{aligned}\n\\text{MultiHead}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) &= [\\text{head}_1; \\dots; \\text{head}_h]\\mathbf{W}^O \\\\\n\\text{where head}_i &= \\text{Attention}(\\mathbf{Q}\\mathbf{W}^Q_i, \\mathbf{K}\\mathbf{W}^K_i, \\mathbf{V}\\mathbf{W}^V_i)\n\\end{aligned}\n$$\nwhere $\\mathbf{W}^Q_i$, $\\mathbf{W}^K_i$, $\\mathbf{W}^V_i$, and $\\mathbf{W}^O$ are parameter matrices to be learned.\nEncoder\n#\nThe transformer’s encoder. (Image source:\nVaswani, et al., 2017\n)\nThe encoder generates an attention-based representation with capability to locate a specific piece of information from a potentially infinitely-large context.\nA stack of N=6 identical layers.\nEach layer has a\nmulti-head self-attention layer\nand a simple position-wise\nfully connected feed-forward network\n.\nEach sub-layer adopts a\nresidual\nconnection and a layer\nnormalization\n.\nAll the sub-layers output data of the same dimension $d_\\text{model} = 512$.\nDecoder\n#\nThe transformer’s decoder. (Image source:\nVaswani, et al., 2017\n)\nThe decoder is able to retrieval from the encoded representation.\nA stack of N = 6 identical layers\nEach layer has two sub-layers of multi-head attention mechanisms and one sub-layer of fully-connected feed-forward network.\nSimilar to the encoder, each sub-layer adopts a residual connection and a layer normalization.\nThe first multi-head attention sub-layer is\nmodified\nto prevent positions from attending to subsequent positions, as we don’t want to look into the future of the target sequence when predicting the current position.\nFull Architecture\n#\nFinally here is the complete view of the transformer’s architecture:\nBoth the source and target sequences first go through embedding layers to produce data of the same dimension $d_\\text{model} =512$.\nTo preserve the position information, a sinusoid-wave-based positional encoding is applied and summed with the embedding output.\nA softmax and linear layer are added to the final decoder output.\nThe full model architecture of the transformer. (Image source: Fig 1 & 2 in\nVaswani, et al., 2017\n.)\nTry to implement the transformer model is an interesting experience, here is mine:\nlilianweng/transformer-tensorflow\n. Read the comments in the code if you are interested.\nSNAIL\n#\nThe transformer has no recurrent or convolutional structure, even with the positional encoding added to the embedding vector, the sequential order is only weakly incorporated. For problems sensitive to the positional dependency like\nreinforcement learning\n, this can be a big problem.\nThe\nSimple Neural Attention\nMeta-Learner\n(\nSNAIL\n) (\nMishra et al., 2017\n) was developed partially to resolve the problem with\npositioning\nin the transformer model by combining the self-attention mechanism in transformer with\ntemporal convolutions\n. It has been demonstrated to be good at both supervised learning and reinforcement learning tasks.\nSNAIL model architecture (Image source:\nMishra et al., 2017\n)\nSNAIL was born in the field of meta-learning, which is another big topic worthy of a post by itself. But in simple words, the meta-learning model is expected to be generalizable to novel, unseen tasks in the similar distribution. Read\nthis\nnice introduction if interested.\nSelf-Attention GAN\n#\nSelf-Attention GAN\n(\nSAGAN\n;\nZhang et al., 2018\n) adds self-attention layers into\nGAN\nto enable both the generator and the discriminator to better model relationships between spatial regions.\nThe classic\nDCGAN\n(Deep Convolutional GAN) represents both discriminator and generator as multi-layer convolutional networks. However, the representation capacity of the network is restrained by the filter size, as the feature of one pixel is limited to a small local region. In order to connect regions far apart, the features have to be dilute through layers of convolutional operations and the dependencies are not guaranteed to be maintained.\nAs the (soft) self-attention in the vision context is designed to explicitly learn the relationship between one pixel and all other positions, even regions far apart, it can easily capture global dependencies. Hence GAN equipped with self-attention is expected to\nhandle details better\n, hooray!\nConvolution operation and self-attention have access to regions of very different sizes.\nThe SAGAN adopts the\nnon-local neural network\nto apply the attention computation. The convolutional image feature maps $\\mathbf{x}$ is branched out into three copies, corresponding to the concepts of\nkey, value, and query\nin the transformer:\nKey: $f(\\mathbf{x}) = \\mathbf{W}_f \\mathbf{x}$\nQuery: $g(\\mathbf{x}) = \\mathbf{W}_g \\mathbf{x}$\nValue: $h(\\mathbf{x}) = \\mathbf{W}_h \\mathbf{x}$\nThen we apply the dot-product attention to output the self-attention feature maps:\n$$\n\\begin{aligned}\n\\alpha_{i,j} &= \\text{softmax}(f(\\mathbf{x}_i)^\\top g(\\mathbf{x}_j)) \\\\\n\\mathbf{o}_j &= \\mathbf{W}_v \\Big( \\sum_{i=1}^N \\alpha_{i,j} h(\\mathbf{x}_i) \\Big)\n\\end{aligned}\n$$\nThe self-attention mechanism in SAGAN. (Image source: Fig. 2 in\nZhang et al., 2018\n)\nNote that $\\alpha_{i,j}$ is one entry in the attention map, indicating how much attention the model should pay to the $i$-th position when synthesizing the $j$-th location. $\\mathbf{W}_f$, $\\mathbf{W}_g$, and $\\mathbf{W}_h$ are all 1x1 convolution filters. If you feel that 1x1 conv sounds like a weird concept (i.e., isn’t it just to multiply the whole feature map with one number?), watch this short\ntutorial\nby Andrew Ng. The output $\\mathbf{o}_j$ is a column vector of the final output $\\mathbf{o}= (\\mathbf{o}_1, \\mathbf{o}_2, \\dots, \\mathbf{o}_j, \\dots, \\mathbf{o}_N)$.\nFurthermore, the output of the attention layer is multiplied by a scale parameter and added back to the original input feature map:\n$$\n\\mathbf{y} = \\mathbf{x}_i + \\gamma \\mathbf{o}_i\n$$\nWhile the scaling parameter $\\gamma$ is increased gradually from 0 during the training, the network is configured to first rely on the cues in the local regions and then gradually learn to assign more weight to the regions that are further away.\n128×128 example images generated by SAGAN for different classes. (Image source: Partial Fig. 6 in\nZhang et al., 2018\n)\nCited as:\n@article{weng2018attention,\n  title   = \"Attention? Attention!\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-06-24-attention/\"\n}\nReferences\n#\n[1]\n“Attention and Memory in Deep Learning and NLP.”\n- Jan 3, 2016 by Denny Britz\n[2]\n“Neural Machine Translation (seq2seq) Tutorial”\n[3] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio.\n“Neural machine translation by jointly learning to align and translate.”\nICLR 2015.\n[4] Kelvin Xu, Jimmy Ba, Ryan Kiros, Kyunghyun Cho, Aaron Courville, Ruslan Salakhudinov, Rich Zemel, and Yoshua Bengio.\n“Show, attend and tell: Neural image caption generation with visual attention.”\nICML, 2015.\n[5] Ilya Sutskever, Oriol Vinyals, and Quoc V. Le.\n“Sequence to sequence learning with neural networks.”\nNIPS 2014.\n[6] Thang Luong, Hieu Pham, Christopher D. Manning.\n“Effective Approaches to Attention-based Neural Machine Translation.”\nEMNLP 2015.\n[7] Denny Britz, Anna Goldie, Thang Luong, and Quoc Le.\n“Massive exploration of neural machine translation architectures.”\nACL 2017.\n[8] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[9] Jianpeng Cheng, Li Dong, and Mirella Lapata.\n“Long short-term memory-networks for machine reading.”\nEMNLP 2016.\n[10] Xiaolong Wang, et al.\n“Non-local Neural Networks.”\nCVPR 2018\n[11] Han Zhang, Ian Goodfellow, Dimitris Metaxas, and Augustus Odena.\n“Self-Attention Generative Adversarial Networks.”\narXiv preprint arXiv:1805.08318 (2018).\n[12] Nikhil Mishra, Mostafa Rohaninejad, Xi Chen, and Pieter Abbeel.\n“A simple neural attentive meta-learner.”\nICLR 2018.\n[13]\n“WaveNet: A Generative Model for Raw Audio”\n- Sep 8, 2016 by DeepMind.\n[14]  Oriol Vinyals, Meire Fortunato, and Navdeep Jaitly.\n“Pointer networks.”\nNIPS 2015.\n[15] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).",
            "metadata": {
              "title": "Attention? Attention! | Lil'Log",
              "description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "keywords": "architecture, attention, transformer, rnn",
              "author": "Lilian Weng",
              "og:title": "Attention? Attention!",
              "og:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
              "twitter:card": "summary",
              "twitter:title": "Attention? Attention!",
              "twitter:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "article:section": "posts",
              "article:published_time": "2018-06-24T00:00:00+00:00",
              "article:modified_time": "2018-06-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/1c9291c74af3/code/body-000.txt",
                "chars": 222,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "bytes": 2159899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-8571ab535bf08b3eb897.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "bytes": 36779,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-244663c064863ba3add1.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "bytes": 163006,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-417a080a721a8da35e76.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "bytes": 360658,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7a8e772d26ca2075d030.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "bytes": 329846,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-a79121328d38f1e7decb.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "bytes": 1061108,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-217a917d5b695d69920e.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "bytes": 3290656,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-16ff0e0557cd1ec7183b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "bytes": 190907,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-68ed274d29e23ec04058.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "bytes": 20601,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-f7ff47f8ed0c85c31c04.jpg",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d885b9f00fc903916eff.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "bytes": 236994,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-43b2947b31f475b9d117.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "bytes": 476899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-202d6793b7b96d2f655a.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "bytes": 401199,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-47a02b382f80dc9a2137.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d314a0ab86b5abc9e45b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "bytes": 136297,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-5bee749c4008d551aef3.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "bytes": 198560,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-9686a8baee36d438f09c.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7cfc826648a35a656e03.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "bytes": 485628,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-4f9fa106ff81362212ba.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "bytes": 124592,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-3442cdcfc8a317d5e9cd.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "bytes": 392406,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d18eeaedd090128a06bf.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "bytes": 3409897,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-82aaa856d170c7aa0cea.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/lilianweng/transformer-tensorflow",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03044",
                "label": "show-attention-tell",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://www.instagram.com/mensweardog/?hl=en",
                "label": "@mensweardog",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.3215",
                "label": "Sutskever, et al. 2014",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "LSTM or GRU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1409.0473.pdf",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/nlp-sequence-models/bidirectional-rnn-fyXnn",
                "label": "bidirectional RNN",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/versions/master/tutorials/seq2seq",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "label": "Xu et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.04025.pdf",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03906",
                "label": "Britz et al., 2017",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "Graves2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.4025.pdf",
                "label": "Luong2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1601.06733.pdf",
                "label": "Cheng2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.0473",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.04025",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Turing_machine",
                "label": "1936",
                "type": "a"
              },
              {
                "href": "http://aturingmachine.com/",
                "label": "http://aturingmachine.com/",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Von_Neumann_architecture",
                "label": "von Neumann",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.03134",
                "label": "Vinyals, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1512.03385.pdf",
                "label": "residual",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "http://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "Meta-Learner",
                "type": "a"
              },
              {
                "href": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "label": "Mishra et al., 2017",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/wavenet-generative-model-raw-audio/",
                "label": "temporal convolutions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1805.08318.pdf",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "DCGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1711.07971.pdf",
                "label": "non-local neural network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.08318",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/convolutional-neural-networks/networks-in-networks-and-1x1-convolutions-ZTb8x",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2016/01/attention-and-memory-in-deep-learning-and-nlp/",
                "label": "“Attention and Memory in Deep Learning and NLP.”",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/nmt",
                "label": "“Neural Machine Translation (seq2seq) Tutorial”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "label": "“Sequence to sequence learning with neural networks.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.03141",
                "label": "“A simple neural attentive meta-learner.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03044",
                "bytes": 9582640,
                "reused": false,
                "local_path": "papers/repair/cc9ae4c67126750bbe41.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.3215",
                "bytes": 112084,
                "reused": false,
                "local_path": "papers/repair/61d552395d0f0789263b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473.pdf",
                "bytes": 444482,
                "reused": false,
                "local_path": "papers/repair/ffb5ff16a013792114ac.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "bytes": 3126761,
                "reused": false,
                "local_path": "papers/repair/53e1470cf7704d6e3cb9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/dac4f1215a64e5bf890e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03906",
                "bytes": 305967,
                "reused": false,
                "local_path": "papers/repair/2864d7bf295692b04b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": false,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.4025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/538f66bff21c49b4a2af.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06733.pdf",
                "bytes": 2520829,
                "reused": false,
                "local_path": "papers/repair/eab5cb0dbe082766664e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473",
                "bytes": 444482,
                "reused": true,
                "local_path": "papers/repair/b6909588ff7b9ebf375f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025",
                "bytes": 249825,
                "reused": true,
                "local_path": "papers/repair/94d3d49016ad40753c67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.03134",
                "bytes": 469544,
                "reused": false,
                "local_path": "papers/repair/88d23cac0369adc66dcd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385.pdf",
                "bytes": 819383,
                "reused": false,
                "local_path": "papers/repair/984099b2816e5988dbb2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "retried_at": "2026-10-20T18:09:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318.pdf",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/09d96a257954f78287a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": false,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.07971.pdf",
                "bytes": 2853537,
                "reused": false,
                "local_path": "papers/repair/684df287e5824edb084a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/72f7e2aac2061b4b2acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "bytes": 142950,
                "reused": false,
                "local_path": "papers/repair/3cc5c95987280b914097.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.03141",
                "bytes": 1026799,
                "reused": false,
                "local_path": "papers/repair/75189519ab64f046e1aa.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29634,
            "expected_body_images": 21,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/1c9291c74af3/pages/source.html",
            "local_html": "attachments/1c9291c74af3/pages/article.html",
            "body_base_path": "attachments/1c9291c74af3/pages/",
            "body_markdown_path": "attachments/1c9291c74af3/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
          "status": "ok",
          "article_id": "dcd5da018bf2",
          "local_path": "series-follow/1602/repair/827224e799e103f1e0f7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9b7d412df1022e9dd836.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/25f0b2690092af605c3d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7d80cffa1089cf5d2768.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
              "bytes": 570814,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/df4282f24e52a002c1e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
              "bytes": 464230,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cab3cb57db5f98d84069.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
              "bytes": 420355,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0f97e3b0cd6e0f9d33d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
              "bytes": 128314,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ce9b993dcf304f3ee690.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
              "bytes": 49638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/aea346be74eb04186d40.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
              "bytes": 92635,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/73a84b0003e99b52aabb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
              "bytes": 244624,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/dcd62d1b6219e852f4e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/33280c015fb683b19da0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
              "bytes": 306995,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/14870bcbb3ef6e114eb5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/86a19bc020c6f7606039.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
              "bytes": 118602,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cc3c4b64a92e45404da4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a987ca8a4f296dda91fa.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family",
            "keywords": "Transformer,自注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "publish_date": "2020-04",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer家族综述（初版）",
            "id": "dcd5da018bf2",
            "collected_at": "2026-10-02T14:13:14",
            "title": "The Transformer Family | Lil'Log",
            "body_markdown": "[Updated on\n2023-01-27\n: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here:\nThe Transformer Family Version 2.0\n. Please refer to that post on this topic.]\nIt has been almost two years since my last post on\nattention\n. Recent progress on new and enhanced versions of Transformer motivates me to write another post on this specific topic, focusing on how the vanilla Transformer can be improved for longer-term attention span, less memory and computation consumption, RL task solving and more.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of length $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in the neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\mathbf{q}_i {\\mathbf{k}_j}^\\top)}{ \\sqrt{d_k} \\sum_{r \\in S_i} \\exp(\\mathbf{q}_i {\\mathbf{k}_r}^\\top) }\n$$\nSee my old\npost\nfor other types of attention if interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttention}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nTransformer\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nEncoder-Decoder Architecture\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\n(1)\nSinusoidal positional encoding\nis defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\n(2)\nLearned positional encoding\n, as its name suggested, assigns each element with a learned column vector which encodes its\nabsolute\nposition (\nGehring, et al. 2017\n).\nQuick Follow-ups\nFollowing the vanilla Transformer,\nAl-Rfou et al. (2018)\nadded a set of auxiliary losses to enable training a deep Transformer model on character-level language modeling which outperformed LSTMs. Several types of auxiliary tasks are used:\nInstead of producing only one prediction at the sequence end, every\nimmediate position\nis also asked to make a correct prediction, forcing the model to predict given smaller contexts (e.g. first couple tokens at the beginning of a context window).\nEach intermediate Transformer layer is used for making predictions as well. Lower layers are weighted to contribute less and less to the total loss as training progresses.\nEach position in the sequence can predict multiple targets, i.e. two or more predictions of the future tokens.\nAuxiliary prediction tasks used in deep Transformer for character-level language modeling. (Image source:\nAl-Rfou et al. (2018)\n)\nAdaptive Computation Time (ACT)\n#\nAdaptive Computation Time\n(short for\nACT\n;\nGraves, 2016\n) is a mechanism for dynamically deciding how many computational steps are needed in a recurrent neural network. Here is a cool\ntutorial\non ACT from distill.pub.\nLet’s say, we have a RNN model $\\mathcal{R}$ composed of input weights $W_x$, a parametric state transition function $\\mathcal{S}(.)$, a set of output weights $W_y$ and an output bias $b_y$. Given an input sequence $(x_1, \\dots, x_L)$, the output sequence $(y_1, \\dots, y_L)$ is computed by:\n$$\ns_t = \\mathcal{S}(s_{t-1}, W_x x_t), \\quad y_t = W_y s_t + b_y\\quad\\text{for }t=1, \\dots, L\n$$\nACT enables the above RNN setup to perform a variable number of steps at each input element. Multiple computational steps lead to a sequence of intermediate states $(s_t^1, \\dots, s_t^{N(t)})$ and outputs $(y_t^1, \\dots, y_t^{N(t)})$ — they all share the same state transition function $\\mathcal{S}(.)$, as well as the same output weights $W_y$ and bias $b_y$:\n$$\n\\begin{aligned}\ns_t^0 &= s_{t-1} \\\\\ns_t^n &= \\mathcal{S}(s_{t}^{n-1}, x_t^n) = \\mathcal{S}(s_{t}^{n-1}, x_t + \\delta_{n,1}) \\text{ for } n=1, \\dots, N(t)\\\\\ny_t^n &= W_y s_t^n + b_y\n\\end{aligned}\n$$\nwhere $\\delta_{n,1}$ is a binary flag indicating whether the input step has been incremented.\nThe number of steps $N(t)$ is determined by an extra sigmoidal halting unit $h$, with associated weight matrix $W_h$ and bias $b_h$, outputting a halting probability $p_t^n$ at immediate step $n$ for $t$-th input element:\n$$\nh_t^n = \\sigma(W_h s_t^n + b_h)\n$$\nIn order to allow the computation to halt after a single step, ACT introduces a small constant $\\epsilon$ (e.g. 0.01), so that whenever the cumulative probability goes above $1-\\epsilon$, the computation stops.\n$$\n\\begin{aligned}\nN(t) &= \\min(\\min\\{n': \\sum_{n=1}^{n'} h_t^n \\geq 1 -\\epsilon\\}, M) \\\\\np_t^n &= \\begin{cases}\nh_t^n & \\text{if }n < N(t) \\\\\nR(t) = 1 - \\sum_{n=1}^{N(t)-1} h_t^n & \\text{if }n= N(t)\\\\\n\\end{cases}\n\\end{aligned}\n$$\nwhere $M$ is an upper limit for the number of immediate steps allowed.\nThe final state and output are mean-field updates:\n$$\ns_t = \\sum_{n=1}^{N(t)} p_t^n s_t^n,\\quad y_t = \\sum_{n=1}^{N(t)} p_t^n y_t^n\n$$\nThe computation graph of a RNN with ACT mechanism. (Image source:\nGraves, 2016\n)\nTo avoid unnecessary pondering over each input, ACT adds a\nponder cost\n$\\mathcal{P}(x) = \\sum_{t=1}^L N(t) + R(t) $  in the loss function to encourage a smaller number of intermediate computational steps.\nImproved Attention Span\n#\nThe goal of improving attention span is to make the context that can be used in self-attention longer, more efficient and flexible.\nLonger Attention Span (Transformer-XL)\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments.\nThis\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) solves the context segmentation problem with two main modifications:\nReusing hidden states between segments.\nAdopting a new positional encoding that is suitable for reused states.\nHidden State Reuse\nThe recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both key and value rely on the extended hidden state, while the query only consumes hidden state at current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension.\nRelative Positional Encoding\nIn order to work with this new form of attention span, Transformer-XL proposed a new type of positional encoding. If using the same approach by vanilla Transformer and encoding the absolute position, the previous and current segments will be assigned with the same encoding, which is undesired.\nTo keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar, et al., (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 7) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys at positions $j \\in S_i$, where $S_i$ defineds the $i$-th token’s context window.\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clamp}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nLocalized Attention Span (Image Transformer)\n#\nThe original, also the most popular, use case for Transformer is to do language modeling. The text sequence is one-dimensional in a clearly defined chronological order and thus the attention span grows linearly with increased context size.\nHowever, if we want to use Transformer on images, it is unclear how to define the scope of context or the order.\nImage Transformer\n(\nParmer, et al 2018\n) embraces a formulation of image generation similar to sequence modeling within the Transformer framework. Additionally, Image Transformer restricts the self-attention span to only\nlocal\nneighborhoods, so that the model can scale up to process more images in parallel and keep the likelihood loss tractable.\nThe encoder-decoder architecture remains for image-conditioned generation:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThe decoder\nautoregressively\ngenerates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n(1)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n(2)\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nLess Time and Memory Cost\n#\nThis section introduces several improvements made on Transformer to reduce the computation time and memory consumption.\nSparse Attention Matrix Factorization (Sparse Transformers)\n#\nThe compute and memory cost of the vanilla Transformer grows quadratically with sequence length and thus it is hard to be applied on very long sequences.\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn anto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\n(1)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\nA_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n\\end{aligned}\n$$\n(2)\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\nA_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n\\end{aligned}\n$$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. => This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details.\nLocality-Sensitive Hashing (Reformer)\n#\nThe improvements proposed by the\nReformer\nmodel (\nKitaev, et al. 2020\n) aim to solve the following pain points in Transformer:\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nThe attention matrix on sequences of length $L$ often requires $O(L^2)$ in both memory and time.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $O(L^2)$ to $O(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 11:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nMake it Recurrent (Universal Transformer)\n#\nThe\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN.\nRather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{H}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{H}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{H}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{H}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{H}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses sinusoidal position signal but with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{H}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nStabilization for RL (GTrXL)\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Apr 2020). The transformer family. Lil’Log. https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/.\nOr\n@article{weng2020transformer,\n  title   = \"The Transformer Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Apr\",\n  url     = \"https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/\"\n}\nReference\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).",
            "metadata": {
              "title": "The Transformer Family | Lil'Log",
              "description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "keywords": "architecture, attention, transformer, foundation, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family",
              "og:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family",
              "twitter:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "article:section": "posts",
              "article:published_time": "2020-04-07T00:00:00+00:00",
              "article:modified_time": "2020-04-07T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/dcd5da018bf2/code/body-000.txt",
                "chars": 257,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-9b7d412df1022e9dd836.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-25f0b2690092af605c3d.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-7d80cffa1089cf5d2768.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "bytes": 570814,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-df4282f24e52a002c1e4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "bytes": 464230,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cab3cb57db5f98d84069.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-0f97e3b0cd6e0f9d33d1.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-ce9b993dcf304f3ee690.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-aea346be74eb04186d40.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-73a84b0003e99b52aabb.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-dcd62d1b6219e852f4e7.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-33280c015fb683b19da0.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-14870bcbb3ef6e114eb5.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-86a19bc020c6f7606039.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cc3c4b64a92e45404da4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-a987ca8a4f296dda91fa.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
                "label": "The Transformer Family Version 2.0",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08983",
                "label": "Graves, 2016",
                "type": "a"
              },
              {
                "href": "https://distill.pub/2016/augmented-rnns/",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar, et al., (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": true,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": true,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08983",
                "bytes": 6582868,
                "reused": false,
                "local_path": "papers/repair/b07529fb4c15758ccb0e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": true,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": true,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": true,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": true,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": true,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": true,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": true,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": true,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": true,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": true,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 36377,
            "expected_body_images": 15,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/dcd5da018bf2/pages/source.html",
            "local_html": "attachments/dcd5da018bf2/pages/article.html",
            "body_base_path": "attachments/dcd5da018bf2/pages/",
            "body_markdown_path": "attachments/dcd5da018bf2/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
          "status": "partial",
          "article_id": "a8dc6bf17c71",
          "local_path": "series-follow/1602/repair/3d08c3e2cf07a50c284b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
              "bytes": 1548239,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/23d602a28b9d9dda6fe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
              "bytes": 665187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/11419d5ec12fba3fb7f9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
              "bytes": 730525,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/34f37f1d8bf391fe9f42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
              "bytes": 808103,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/851555a6cfa04864e872.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
              "bytes": 184486,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1195100b0c6841a237dd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
              "bytes": 194344,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c47eeb17ebb22f866942.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
              "bytes": 273207,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9ae2425c1e62b530a443.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
              "bytes": 174582,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cb826c25071414ad89e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
              "bytes": 405772,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0167fe1ca07386abf1d2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
              "bytes": 1245251,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ae1778af670dfaca75e8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
              "bytes": 397702,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9baa7ed8723c2cae889a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
              "bytes": 102014,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f1b0701dad5bcf83ef5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
              "bytes": 195622,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7f2ae4aa3936d2a466d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
              "bytes": 286187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d947284bd0373951e25d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
              "bytes": 124913,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/830017a377b95ff33b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
              "bytes": 1295521,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d0137fe96ca3220fcf1f.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Meta-Learning: Learning to Learn Fast",
            "keywords": "元学习,小样本,MAML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "publish_date": "2018-11",
            "corpus_stage": "预训练/SFT",
            "notes": "元学习综述",
            "id": "a8dc6bf17c71",
            "collected_at": "2026-10-02T14:13:37",
            "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
            "body_markdown": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in\nChinese\n!]\nA good machine learning model often requires training with a large number of samples. Humans, in contrast, learn new concepts and skills much faster and more efficiently. Kids who have seen cats and birds only a few times can quickly tell them apart. People who know how to ride a bike are likely to discover the way to ride a motorcycle fast with little or even no demonstration. Is it possible to design a machine learning model with similar properties — learning new concepts and skills fast with a few training examples? That’s essentially what\nmeta-learning\naims to solve.\nWe expect a good meta-learning model capable of well adapting or generalizing to new tasks and new environments that have never been encountered during training time. The adaptation process, essentially a mini learning session, happens during test but with a limited exposure to the new task configurations. Eventually, the adapted model can complete new tasks. This is why meta-learning is also known as\nlearning to learn\n.\nThe tasks can be any well-defined family of machine learning problems: supervised learning, reinforcement learning, etc. For example, here are a couple concrete meta-learning tasks:\nA classifier trained on non-cat images can tell whether a given image contains a cat after seeing a handful of cat pictures.\nA game bot is able to quickly master a new game.\nA mini robot completes the desired task on an uphill surface during test even through it was only trained in a flat surface environment.\nDefine the Meta-Learning Problem\n#\nIn this post, we focus on the case when each desired task is a supervised learning problem like image classification. There is a lot of interesting literature on meta-learning with reinforcement learning problems (aka “Meta Reinforcement Learning”), but we would not cover them here.\nA Simple View\n#\nA good meta-learning model should be trained over a variety of learning tasks and optimized for the best performance on a distribution of tasks, including potentially unseen tasks. Each task is associated with a dataset $\\mathcal{D}$, containing both feature vectors and true labels. The optimal model parameters are:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\mathcal{D}\\sim p(\\mathcal{D})} [\\mathcal{L}_\\theta(\\mathcal{D})]\n$$\nIt looks very similar to a normal learning task, but\none dataset\nis considered as\none data sample\n.\nFew-shot classification\nis an instantiation of meta-learning in the field of supervised learning. The dataset $\\mathcal{D}$ is often split into two parts, a support set $S$ for learning and a prediction set $B$ for training or testing, $\\mathcal{D}=\\langle S, B\\rangle$. Often we consider a\nK-shot N-class classification\ntask: the support set contains K labelled examples for each of N classes.\nAn example of 4-shot 2-class image classification. (Image thumbnails are from\nPinterest\n)\nTraining in the Same Way as Testing\n#\nA dataset $\\mathcal{D}$ contains pairs of feature vectors and labels, $\\mathcal{D} = \\{(\\mathbf{x}_i, y_i)\\}$ and each label belongs to a known label set $\\mathcal{L}^\\text{label}$.  Let’s say, our classifier $f_\\theta$ with parameter $\\theta$ outputs a probability of a data point belonging to the class $y$ given the feature vector $\\mathbf{x}$, $P_\\theta(y\\vert\\mathbf{x})$.\nThe optimal parameters should maximize the probability of true labels across multiple training batches $B \\subset \\mathcal{D}$:\n$$\n\\begin{aligned}\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{(\\mathbf{x}, y)\\in \\mathcal{D}}[P_\\theta(y \\vert \\mathbf{x})] &\\\\\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{B\\subset \\mathcal{D}}[\\sum_{(\\mathbf{x}, y)\\in B}P_\\theta(y \\vert \\mathbf{x})] & \\scriptstyle{\\text{; trained with mini-batches.}}\n\\end{aligned}\n$$\nIn few-shot classification, the goal is to reduce the prediction error on data samples with unknown labels given a small support set for “fast learning” (think of how “fine-tuning” works). To make the training process mimics what happens during inference, we would like to “fake” datasets with a subset of labels to avoid exposing all the labels to the model and modify the optimization procedure accordingly to encourage fast learning:\nSample a subset of labels, $L\\subset\\mathcal{L}^\\text{label}$.\nSample a support set $S^L \\subset \\mathcal{D}$ and a training batch $B^L \\subset \\mathcal{D}$. Both of them only contain data points with labels belonging to the sampled label set $L$, $y \\in L, \\forall (x, y) \\in S^L, B^L$.\nThe support set is part of the model input.\nThe final optimization uses the mini-batch $B^L$ to compute the loss and update the model parameters through backpropagation, in the same way as how we use it in the supervised learning.\nYou may consider each pair of sampled dataset $(S^L, B^L)$ as one data point. The model is trained such that it can generalize to other datasets.  Symbols in red are added for meta-learning in addition to the supervised learning objective.\n$$\n\\theta = \\arg\\max_\\theta \\color{red}{E_{L\\subset\\mathcal{L}}[} E_{\\color{red}{S^L \\subset\\mathcal{D}, }B^L \\subset\\mathcal{D}} [\\sum_{(x, y)\\in B^L} P_\\theta(x, y\\color{red}{, S^L})] \\color{red}{]}\n$$\nThe idea is to some extent similar to using a pre-trained model in image classification (ImageNet) or language modeling (big text corpora) when only a limited set of task-specific data samples are available. Meta-learning takes this idea one step further, rather than fine-tuning according to one down-steam task, it optimizes the model to be good at many, if not all.\nLearner and Meta-Learner\n#\nAnother popular view of meta-learning decomposes the model update into two stages:\nA classifier $f_\\theta$ is the “learner” model, trained for operating a given task;\nIn the meantime, a optimizer $g_\\phi$ learns how to update the learner model’s parameters via the support set $S$, $\\theta’ = g_\\phi(\\theta, S)$.\nThen in final optimization step, we need to update both $\\theta$ and $\\phi$ to maximize:\n$$\n\\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})]]\n$$\nCommon Approaches\n#\nThere are three common approaches to meta-learning: metric-based, model-based, and optimization-based. Oriol Vinyals has a nice summary in his\ntalk\nat meta-learning symposium @ NIPS 2018:\n| ————- | ————- | ————- | ————- |\nModel-based\nMetric-based\nOptimization-based\nKey idea\nRNN; memory\nMetric learning\nGradient descent\nHow $P_\\theta(y \\vert \\mathbf{x})$ is modeled?\n$f_\\theta(\\mathbf{x}, S)$\n$\\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i$ (*)\n$P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})$\n(*) $k_\\theta$ is a kernel function measuring the similarity between $\\mathbf{x}_i$ and $\\mathbf{x}$.\nNext we are gonna review classic models in each approach.\nMetric-Based\n#\nThe core idea in metric-based meta-learning is similar to nearest neighbors algorithms (i.e.,\nk-NN\nclassificer and\nk-means\nclustering) and\nkernel density estimation\n. The predicted probability over a set of known labels $y$ is a weighted sum of labels of support set samples. The weight is generated by a kernel function $k_\\theta$, measuring the similarity between two data samples.\n$$\nP_\\theta(y \\vert \\mathbf{x}, S) = \\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i \n$$\nTo learn a good kernel is crucial to the success of a metric-based meta-learning model.\nMetric learning\nis well aligned with this intention, as it aims to learn a metric or distance function over objects. The notion of a good metric is problem-dependent. It should represent the relationship between inputs in the task space and facilitate problem solving.\nAll the models introduced below learn embedding vectors of input data explicitly and use them to design proper kernel functions.\nConvolutional Siamese Neural Network\n#\nThe\nSiamese Neural Network\nis composed of two twin networks and their outputs are jointly trained on top with a function to learn the relationship between pairs of input data samples. The twin networks are identical, sharing the same weights and network parameters. In other words, both refer to the same embedding network that learns an efficient embedding to reveal relationship between pairs of data points.\nKoch, Zemel & Salakhutdinov (2015)\nproposed a method to use the siamese neural network to do one-shot image classification. First, the siamese network is trained for a verification task for telling whether two input images are in the same class. It outputs the probability of two images belonging to the same class. Then, during test time, the siamese network processes all the image pairs between a test image and every image in the support set. The final prediction is the class of the support image with the highest probability.\nThe architecture of convolutional siamese neural network for few-show image classification.\nFirst, convolutional siamese network learns to encode two images into feature vectors via a embedding function $f_\\theta$ which contains a couple of convolutional layers.\nThe L1-distance between two embeddings is $\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert$.\nThe distance is converted to a probability $p$ by a linear feedforward layer and sigmoid. It is the probability of whether two images are drawn from the same class.\nIntuitively the loss is cross entropy because the label is binary.\n$$\n\\begin{aligned}\np(\\mathbf{x}_i, \\mathbf{x}_j) &= \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert) \\\\\n\\mathcal{L}(B) &= \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} \\mathbf{1}_{y_i=y_j}\\log p(\\mathbf{x}_i, \\mathbf{x}_j) + (1-\\mathbf{1}_{y_i=y_j})\\log (1-p(\\mathbf{x}_i, \\mathbf{x}_j))\n\\end{aligned}\n$$\nImages in the training batch $B$ can be augmented with distortion. Of course, you can replace the L1 distance with other distance metric, L2, cosine, etc. Just make sure they are differential and then everything else works the same.\nGiven a support set $S$ and a test image $\\mathbf{x}$, the final predicted class is:\n$$\n\\hat{c}_S(\\mathbf{x}) = c(\\arg\\max_{\\mathbf{x}_i \\in S} P(\\mathbf{x}, \\mathbf{x}_i))\n$$\nwhere $c(\\mathbf{x})$ is the class label of an image $\\mathbf{x}$ and $\\hat{c}(.)$ is the predicted label.\nThe assumption is that the learned embedding can be generalized to be useful for measuring the distance between images of unknown categories. This is the same assumption behind transfer learning via the adoption of a pre-trained model; for example, the convolutional features learned in the model pre-trained with ImageNet are expected to help other image tasks. However, the benefit of a pre-trained model decreases when the new task diverges from the original task that the model was trained on.\nMatching Networks\n#\nThe task of\nMatching Networks\n(\nVinyals et al., 2016\n) is to learn a classifier $c_S$ for any given (small) support set $S=\\{x_i, y_i\\}_{i=1}^k$ (\nk-shot\nclassification). This classifier defines a probability distribution over output labels $y$ given a test example $\\mathbf{x}$. Similar to other metric-based models, the classifier output is defined as a sum of labels of support samples weighted by attention kernel $a(\\mathbf{x}, \\mathbf{x}_i)$ - which should be proportional to the similarity between $\\mathbf{x}$ and $\\mathbf{x}_i$.\nThe architecture of Matching Networks. (Image source:\noriginal paper\n)\n$$\nc_S(\\mathbf{x}) = P(y \\vert \\mathbf{x}, S) = \\sum_{i=1}^k a(\\mathbf{x}, \\mathbf{x}_i) y_i\n\\text{, where }S=\\{(\\mathbf{x}_i, y_i)\\}_{i=1}^k\n$$\nThe attention kernel depends on two embedding functions, $f$ and $g$, for encoding the test sample and the support set samples respectively. The attention weight between two data points is the cosine similarity, $\\text{cosine}(.)$, between their embedding vectors, normalized by softmax:\n$$\na(\\mathbf{x}, \\mathbf{x}_i) = \\frac{\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_i))}{\\sum_{j=1}^k\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_j))}\n$$\nSimple Embedding\n#\nIn the simple version, an embedding function is a neural network with a single data sample as input. Potentially we can set $f=g$.\nFull Context Embeddings\n#\nThe embedding vectors are critical inputs for building a good classifier. Taking a single data point as input might not be enough to efficiently gauge the entire feature space. Therefore, the Matching Network model further proposed to enhance the embedding functions by taking as input the whole support set $S$ in addition to the original input, so that the learned embedding can be adjusted based on the relationship with other support samples.\n$g_\\theta(\\mathbf{x}_i, S)$ uses a bidirectional LSTM to encode $\\mathbf{x}_i$ in the context of the entire support set $S$.\n$f_\\theta(\\mathbf{x}, S)$ encodes the test sample $\\mathbf{x}$ visa an LSTM with read attention over the support set $S$.\nFirst the test sample goes through a simple neural network, such as a CNN, to extract basic features, $f’(\\mathbf{x})$.\nThen an LSTM is trained with a read attention vector over the support set as part of the hidden state:\n$$\n  \\begin{aligned}\n  \\hat{\\mathbf{h}}_t, \\mathbf{c}_t &= \\text{LSTM}(f'(\\mathbf{x}), [\\mathbf{h}_{t-1}, \\mathbf{r}_{t-1}], \\mathbf{c}_{t-1}) \\\\\n  \\mathbf{h}_t &= \\hat{\\mathbf{h}}_t + f'(\\mathbf{x}) \\\\\n  \\mathbf{r}_{t-1} &= \\sum_{i=1}^k a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) g(\\mathbf{x}_i) \\\\\n  a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) &= \\text{softmax}(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i)) = \\frac{\\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i))}{\\sum_{j=1}^k \\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_j))}\n  \\end{aligned}\n  $$\nEventually $f(\\mathbf{x}, S)=\\mathbf{h}_K$ if we do K steps of “read”.\nThis embedding method is called “Full Contextual Embeddings (FCE)”. Interestingly it does help improve the performance on a hard task (few-shot classification on mini ImageNet), but makes no difference on a simple task (Omniglot).\nThe training process in Matching Networks is designed to match inference at test time, see the details in the earlier\nsection\n. It is worthy of mentioning that the Matching Networks paper refined the idea that training and testing conditions should match.\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_\\theta(y\\vert\\mathbf{x}, S^L)]]\n$$\nRelation Network\n#\nRelation Network (RN)\n(\nSung et al., 2018\n) is similar to\nsiamese network\nbut with a few differences:\nThe relationship is not captured by a simple L1 distance in the feature space, but predicted by a CNN classifier $g_\\phi$. The relation score between a pair of inputs, $\\mathbf{x}_i$ and $\\mathbf{x}_j$, is $r_{ij} = g_\\phi([\\mathbf{x}_i, \\mathbf{x}_j])$ where $[.,.]$ is concatenation.\nThe objective function is MSE loss instead of cross-entropy, because conceptually RN focuses more on predicting relation scores which is more like regression, rather than binary classification, $\\mathcal{L}(B) = \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} (r_{ij} - \\mathbf{1}_{y_i=y_j})^2$.\nRelation Network architecture for a 5-way 1-shot problem with one query example. (Image source:\noriginal paper\n)\n(Note: There is another\nRelation Network\nfor relational reasoning, proposed by DeepMind. Don’t get confused.)\nPrototypical Networks\n#\nPrototypical Networks\n(\nSnell, Swersky & Zemel, 2017\n) use an embedding function $f_\\theta$ to encode each input into a $M$-dimensional feature vector. A\nprototype\nfeature vector is defined for every class $c \\in \\mathcal{C}$, as the mean vector of the embedded support data samples in this class.\n$$\n\\mathbf{v}_c = \\frac{1}{|S_c|} \\sum_{(\\mathbf{x}_i, y_i) \\in S_c} f_\\theta(\\mathbf{x}_i)\n$$\nPrototypical networks in the few-shot and zero-shot scenarios. (Image source:\noriginal paper\n)\nThe distribution over classes for a given test input $\\mathbf{x}$ is a softmax over the inverse of distances between the test data embedding and prototype vectors.\n$$\nP(y=c\\vert\\mathbf{x})=\\text{softmax}(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c)) = \\frac{\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c))}{\\sum_{c' \\in \\mathcal{C}}\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_{c'}))}\n$$\nwhere $d_\\varphi$ can be any distance function as long as $\\varphi$ is differentiable. In the paper, they used the squared euclidean distance.\nThe loss function is the negative log-likelihood: $\\mathcal{L}(\\theta) = -\\log P_\\theta(y=c\\vert\\mathbf{x})$.\nModel-Based\n#\nModel-based meta-learning models make no assumption on the form of $P_\\theta(y\\vert\\mathbf{x})$. Rather it depends on a model designed specifically for fast learning — a model that updates its parameters rapidly with a few training steps. This rapid parameter update can be achieved by its internal architecture or controlled by another meta-learner model.\nMemory-Augmented Neural Networks\n#\nA family of model architectures use external memory storage to facilitate the learning process of neural networks, including\nNeural Turing Machines\nand\nMemory Networks\n. With an explicit storage buffer, it is easier for the network to rapidly incorporate new information and not to forget in the future. Such a model is known as\nMANN\n, short for “\nMemory-Augmented Neural Network\n”.  Note that recurrent neural networks with only\ninternal memory\nsuch as vanilla RNN or LSTM are not MANNs.\nBecause MANN is expected to encode new information fast and thus to adapt to new tasks after only a few samples, it fits well for meta-learning. Taking the Neural Turing Machine (NTM) as the base model,\nSantoro et al. (2016)\nproposed a set of modifications on the training setup and the memory retrieval mechanisms (or “addressing mechanisms”, deciding how to assign attention weights to memory vectors). Please go through\nthe NTM section\nin my other post first if you are not familiar with this matter before reading forward.\nAs a quick recap, NTM couples a controller neural network with external memory storage. The controller learns to read and write memory rows by soft attention, while the memory serves as a knowledge repository. The attention weights are generated by its addressing mechanism: content-based + location based.\nThe architecture of Neural Turing Machine (NTM). The memory at time t, $\\mathbf{M}\\_t$ is a matrix of size $N \\times M$, containing N vector rows and each has M dimensions.\nMANN for Meta-Learning\n#\nTo use MANN for meta-learning tasks, we need to train it in a way that the memory can encode and capture information of new tasks fast and, in the meantime, any stored representation is easily and stably accessible.\nThe training described in\nSantoro et al., 2016\nhappens in an interesting way so that the memory is forced to hold information for longer until the appropriate labels are presented later. In each training episode, the truth label $y_t$ is presented with\none step offset\n, $(\\mathbf{x}_{t+1}, y_t)$: it is the true label for the input at the previous time step t, but presented as part of the input at time step t+1.\nTask setup in MANN for meta-learning (Image source:\noriginal paper\n).\nIn this way, MANN is motivated to memorize the information of a new dataset, because the memory has to hold the current input until the label is present later and then retrieve the old information to make a prediction accordingly.\nNext let us see how the memory is updated for efficient information retrieval and storage.\nAddressing Mechanism for Meta-Learning\n#\nAside from the training process, a new pure content-based addressing mechanism is utilized to make the model better suitable for meta-learning.\n» How to read from memory?\nThe read attention is constructed purely based on the content similarity.\nFirst, a key feature vector $\\mathbf{k}_t$ is produced at the time step t by the controller as a function of the input $\\mathbf{x}$. Similar to NTM, a read weighting vector $\\mathbf{w}_t^r$ of N elements is computed as the cosine similarity between the key vector and every memory vector row, normalized by softmax. The read vector $\\mathbf{r}_t$ is a sum of memory records weighted by such weightings:\n$$\n\\mathbf{r}_i = \\sum_{i=1}^N w_t^r(i)\\mathbf{M}_t(i)\n\\text{, where } w_t^r(i) = \\text{softmax}(\\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})\n$$\nwhere $M_t$ is the memory matrix at time t and $M_t(i)$ is the i-th row in this matrix.\n» How to write into memory?\nThe addressing mechanism for writing newly received information into memory operates a lot like the\ncache replacement\npolicy. The\nLeast Recently Used Access (LRUA)\nwriter is designed for MANN to better work in the scenario of meta-learning. A LRUA write head prefers to write new content to either the\nleast used\nmemory location or the\nmost recently used\nmemory location.\nRarely used locations: so that we can preserve frequently used information (see\nLFU\n);\nThe last used location: the motivation is that once a piece of information is retrieved once, it probably won’t be called again for a while (see\nMRU\n).\nThere are many cache replacement algorithms and each of them could potentially replace the design here with better performance in different use cases. Furthermore, it would be a good idea to learn the memory usage pattern and addressing strategies rather than arbitrarily set it.\nThe preference of LRUA is carried out in a way that everything is differentiable:\nThe usage weight $\\mathbf{w}^u_t$ at time t is a sum of current read and write vectors, in addition to the decayed last usage weight, $\\gamma \\mathbf{w}^u_{t-1}$, where $\\gamma$ is a decay factor.\nThe write vector is an interpolation between the previous read weight (prefer “the last used location”) and the previous least-used weight (prefer “rarely used location”). The interpolation parameter is the sigmoid of a hyperparameter $\\alpha$.\nThe least-used weight $\\mathbf{w}^{lu}$ is scaled according to usage weights $\\mathbf{w}_t^u$, in which any dimension remains at 1 if smaller than the n-th smallest element in the vector and 0 otherwise.\n$$\n\\begin{aligned}\n\\mathbf{w}_t^u &= \\gamma \\mathbf{w}_{t-1}^u + \\mathbf{w}_t^r + \\mathbf{w}_t^w \\\\\n\\mathbf{w}_t^r &= \\text{softmax}(\\text{cosine}(\\mathbf{k}_t, \\mathbf{M}_t(i))) \\\\\n\\mathbf{w}_t^w &= \\sigma(\\alpha)\\mathbf{w}_{t-1}^r + (1-\\sigma(\\alpha))\\mathbf{w}^{lu}_{t-1}\\\\\n\\mathbf{w}_t^{lu} &= \\mathbf{1}_{w_t^u(i) \\leq m(\\mathbf{w}_t^u, n)}\n\\text{, where }m(\\mathbf{w}_t^u, n)\\text{ is the }n\\text{-th smallest element in vector }\\mathbf{w}_t^u\\text{.}\n\\end{aligned}\n$$\nFinally, after the least used memory location, indicated by $\\mathbf{w}_t^{lu}$, is set to zero, every memory row is updated:\n$$\n\\mathbf{M}_t(i) = \\mathbf{M}_{t-1}(i) + w_t^w(i)\\mathbf{k}_t, \\forall i\n$$\nMeta Networks\n#\nMeta Networks\n(\nMunkhdalai & Yu, 2017\n), short for\nMetaNet\n, is a meta-learning model with architecture and training process designed for\nrapid\ngeneralization across tasks.\nFast Weights\n#\nThe rapid generalization of MetaNet relies on “fast weights”. There are a handful of papers on this topic, but I haven’t read all of them in detail and I failed to find a very concrete definition, only a vague agreement on the concept. Normally weights in the neural networks are updated by stochastic gradient descent in an objective function and this process is known to be slow. One faster way to learn is to utilize one neural network to predict the parameters of another neural network and the generated weights are called\nfast weights\n. In comparison, the ordinary SGD-based weights are named\nslow weights\n.\nIn MetaNet, loss gradients are used as\nmeta information\nto populate models that learn fast weights. Slow and fast weights are combined to make predictions in neural networks.\nCombining slow and fast weights in a MLP. $\\bigoplus$ is element-wise sum. (Image source:\noriginal paper\n).\nModel Components\n#\nDisclaimer: Below you will find my annotations are different from those in the paper. imo, the paper is poorly written, but the idea is still interesting. So I’m presenting the idea in my own language.\nKey components of MetaNet are:\nAn embedding function $f_\\theta$, parameterized by $\\theta$, encodes raw inputs into feature vectors. Similar to\nSiamese Neural Network\n, these embeddings are trained to be useful for telling whether two inputs are of the same class (verification task).\nA base learner model $g_\\phi$, parameterized by weights $\\phi$, completes the actual learning task.\nIf we stop here, it looks just like\nRelation Network\n. MetaNet, in addition, explicitly models the fast weights of both functions and then aggregates them back into the model (See Fig. 8).\nTherefore we need additional two functions to output fast weights for $f$ and $g$ respectively.\n$F_w$: a LSTM parameterized by $w$ for learning fast weights $\\theta^+$ of the embedding function $f$. It takes as input gradients of $f$’s embedding loss for verification task.\n$G_v$: a neural network parameterized by $v$ learning fast weights $\\phi^+$ for the base learner $g$ from its loss gradients. In MetaNet, the learner’s loss gradients are viewed as the\nmeta information\nof the task.\nOk, now let’s see how meta networks are trained. The training data contains multiple pairs of datasets: a support set $S=\\{\\mathbf{x}’_i, y’_i\\}_{i=1}^K$ and a test set  $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$. Recall that we have four networks and four sets of model parameters to learn, $(\\theta, \\phi, w, v)$.\nFig.9. The MetaNet architecture.\nTraining Process\n#\nSample a random pair of inputs at each time step t from the support set $S$, $(\\mathbf{x}’_i, y’_i)$ and $(\\mathbf{x}’_j, y_j)$. Let $\\mathbf{x}_{(t,1)}=\\mathbf{x}’_i$ and $\\mathbf{x}_{(t,2)}=\\mathbf{x}’_j$.\nfor $t = 1, \\dots, K$:\na. Compute a loss for representation learning; i.e., cross entropy for the verification task:\n$\\mathcal{L}^\\text{emb}_t = \\mathbf{1}_{y’_i=y’_j} \\log P_t + (1 - \\mathbf{1}_{y’_i=y’_j})\\log(1 - P_t)\\text{, where }P_t = \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_{(t,1)}) - f_\\theta(\\mathbf{x}_{(t,2)})\\vert)$\nCompute the task-level fast weights:\n$\\theta^+ = F_w(\\nabla_\\theta \\mathcal{L}^\\text{emb}_1, \\dots, \\mathcal{L}^\\text{emb}_T)$\nNext go through examples in the support set $S$ and compute the example-level fast weights. Meanwhile, update the memory with learned representations.\nfor $i=1, \\dots, K$:\na. The base learner outputs a probability distribution: $P(\\hat{y}_i \\vert \\mathbf{x}_i) = g_\\phi(\\mathbf{x}_i)$ and the loss can be cross-entropy or MSE: $\\mathcal{L}^\\text{task}_i = y’_i \\log g_\\phi(\\mathbf{x}’_i) + (1- y’_i) \\log (1 - g_\\phi(\\mathbf{x}’_i))$\nb. Extract meta information (loss gradients) of the task and compute the example-level fast weights:\n$\\phi_i^+ = G_v(\\nabla_\\phi\\mathcal{L}^\\text{task}_i)$\nThen store $\\phi^+_i$ into $i$-th location of the “value” memory $\\mathbf{M}$.\nd. Encode the support sample into a task-specific input representation using both slow and fast weights: $r’_i = f_{\\theta, \\theta^+}(\\mathbf{x}’_i)$\nThen store $r’_i$ into $i$-th location of the “key” memory $\\mathbf{R}$.\nFinally it is the time to construct the training loss using the test set $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$.\nStarts with $\\mathcal{L}_\\text{train}=0$:\nfor $j=1, \\dots, L$:\na. Encode the test sample into a task-specific input representation:\n$r_j = f_{\\theta, \\theta^+}(\\mathbf{x}_j)$\nb. The fast weights are computed by attending to representations of support set samples in memory $\\mathbf{R}$. The attention function is of your choice. Here MetaNet uses cosine similarity:\n$$\n \\begin{aligned}\n a_j &= \\text{cosine}(\\mathbf{R}, r_j) = [\\frac{r'_1\\cdot r_j}{\\|r'_1\\|\\cdot\\|r_j\\|}, \\dots, \\frac{r'_N\\cdot r_j}{\\|r'_N\\|\\cdot\\|r_j\\|}]\\\\\n \\phi^+_j &= \\text{softmax}(a_j)^\\top \\mathbf{M}\n \\end{aligned}\n $$\nc. Update the training loss: $\\mathcal{L}_\\text{train} \\leftarrow \\mathcal{L}_\\text{train} + \\mathcal{L}^\\text{task}(g_{\\phi, \\phi^+}(\\mathbf{x}_i), y_i) $\nUpdate all the parameters $(\\theta, \\phi, w, v)$ using $\\mathcal{L}_\\text{train}$.\nOptimization-Based\n#\nDeep learning models learn through backpropagation of gradients. However, the gradient-based optimization is neither designed to cope with a small number of training samples, nor to converge within a small number of optimization steps. Is there a way to adjust the optimization algorithm so that the model can be good at learning with a few examples? This is what optimization-based approach meta-learning algorithms intend for.\nLSTM Meta-Learner\n#\nThe optimization algorithm can be explicitly modeled.\nRavi & Larochelle (2017)\ndid so and named it “meta-learner”, while the original model for handling the task is called “learner”. The goal of the meta-learner is to efficiently update the learner’s parameters using a small support set so that the learner can adapt to the new task quickly.\nLet’s denote the learner model as $M_\\theta$ parameterized by $\\theta$, the meta-learner as $R_\\Theta$ with parameters $\\Theta$, and the loss function $\\mathcal{L}$.\nWhy LSTM?\n#\nThe meta-learner is modeled as a LSTM, because:\nThere is similarity between the gradient-based update in backpropagation and the cell-state update in LSTM.\nKnowing a history of gradients benefits the gradient update; think about how\nmomentum\nworks.\nThe update for the learner’s parameters at time step t with a learning rate $\\alpha_t$ is:\n$$\n\\theta_t = \\theta_{t-1} - \\alpha_t \\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n$$\nIt has the same form as the cell state update in LSTM, if we set forget gate $f_t=1$, input gate $i_t = \\alpha_t$, cell state $c_t = \\theta_t$, and new cell state $\\tilde{c}_t = -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t$:\n$$\n\\begin{aligned}\nc_t &= f_t \\odot c_{t-1} + i_t \\odot \\tilde{c}_t\\\\\n    &= \\theta_{t-1} - \\alpha_t\\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n\\end{aligned}\n$$\nWhile fixing $f_t=1$ and $i_t=\\alpha_t$ might not be the optimal, both of them can be learnable and adaptable to different datasets.\n$$\n\\begin{aligned}\nf_t &= \\sigma(\\mathbf{W}_f \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, f_{t-1}] + \\mathbf{b}_f) & \\scriptstyle{\\text{; how much to forget the old value of parameters.}}\\\\\ni_t &= \\sigma(\\mathbf{W}_i \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, i_{t-1}] + \\mathbf{b}_i) & \\scriptstyle{\\text{; corresponding to the learning rate at time step t.}}\\\\\n\\tilde{\\theta}_t &= -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t &\\\\\n\\theta_t &= f_t \\odot \\theta_{t-1} + i_t \\odot \\tilde{\\theta}_t &\\\\\n\\end{aligned}\n$$\nModel Setup\n#\nHow the learner $M\\_\\theta$ and the meta-learner $R\\_\\Theta$ are trained. (Image source:\noriginal paper\nwith more annotations)\nThe training process mimics what happens during test, since it has been proved to be beneficial in\nMatching Networks\n. During each training epoch, we first sample a dataset $\\mathcal{D} = (\\mathcal{D}_\\text{train}, \\mathcal{D}_\\text{test}) \\in \\hat{\\mathcal{D}}_\\text{meta-train}$ and then sample mini-batches out of $\\mathcal{D}_\\text{train}$ to update $\\theta$ for $T$ rounds. The final state of the learner parameter $\\theta_T$ is used to train the meta-learner on the test data $\\mathcal{D}_\\text{test}$.\nTwo implementation details to pay extra attention to:\nHow to compress the parameter space in LSTM meta-learner? As the meta-learner is modeling parameters of another neural network, it would have hundreds of thousands of variables to learn. Following the\nidea\nof sharing parameters across coordinates,\nTo simplify the training process, the meta-learner assumes that the loss $\\mathcal{L}_t$ and the gradient $\\nabla_{\\theta_{t-1}} \\mathcal{L}_t$ are independent.\nMAML\n#\nMAML\n, short for\nModel-Agnostic Meta-Learning\n(\nFinn, et al. 2017\n) is a fairly general optimization algorithm, compatible with any model that learns through gradient descent.\nLet’s say our model is $f_\\theta$ with parameters $\\theta$. Given a task $\\tau_i$ and its associated dataset $(\\mathcal{D}^{(i)}_\\text{train}, \\mathcal{D}^{(i)}_\\text{test})$, we can update the model parameters by one or more gradient descent steps (the following example only contains one step):\n$$\n\\theta'_i = \\theta - \\alpha \\nabla_\\theta\\mathcal{L}^{(0)}_{\\tau_i}(f_\\theta)\n$$\nwhere $\\mathcal{L}^{(0)}$ is the loss computed using the mini data batch with id (0).\nDiagram of MAML. (Image source:\noriginal paper\n)\nWell, the above formula only optimizes for one task. To achieve a good generalization across a variety of tasks, we would like to find the optimal $\\theta^*$ so that the task-specific fine-tuning is more efficient. Now, we sample a new data batch with id (1) for updating the meta-objective. The loss, denoted as $\\mathcal{L}^{(1)}$, depends on the mini batch (1). The superscripts in $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ only indicate different data batches, and they refer to the same loss objective for the same task.\n$$\n\\begin{aligned}\n\\theta^* \n&= \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta'_i}) = \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\\\\n\\theta &\\leftarrow \\theta - \\beta \\nabla_{\\theta} \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\scriptstyle{\\text{; updating rule}}\n\\end{aligned}\n$$\nThe general form of MAML algorithm. (Image source:\noriginal paper\n)\nFirst-Order MAML\n#\nThe meta-optimization step above relies on second derivatives. To make the computation less expensive, a modified version of MAML omits second derivatives, resulting in a simplified and cheaper implementation, known as\nFirst-Order MAML (FOMAML)\n.\nLet’s consider the case of performing $k$ inner gradient steps, $k\\geq1$. Starting with the initial model parameter $\\theta_\\text{meta}$:\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)\\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_1)\\\\\n&\\dots\\\\\n\\theta_k &= \\theta_{k-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{k-1})\n\\end{aligned}\n$$\nThen in the outer loop, we sample a new data batch for updating the meta-objective.\n$$\n\\begin{aligned}\n\\theta_\\text{meta} &\\leftarrow \\theta_\\text{meta} - \\beta g_\\text{MAML} & \\scriptstyle{\\text{; update for meta-objective}} \\\\[2mm]\n\\text{where } g_\\text{MAML}\n&= \\nabla_{\\theta} \\mathcal{L}^{(1)}(\\theta_k) &\\\\[2mm]\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot (\\nabla_{\\theta_{k-1}} \\theta_k) \\dots (\\nabla_{\\theta_0} \\theta_1) \\cdot (\\nabla_{\\theta} \\theta_0) & \\scriptstyle{\\text{; following the chain rule}} \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\Big( \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} \\theta_i \\Big) \\cdot I &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} (\\theta_{i-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1})) &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))) &\n\\end{aligned}\n$$\nThe MAML gradient is:\n$$\ng_\\text{MAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha \\color{red}{\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))})\n$$\nThe First-Order MAML ignores the second derivative part in red. It is simplified as follows, equivalent to the derivative of the last inner gradient update result.\n$$\ng_\\text{FOMAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k)\n$$\nReptile\n#\nReptile\n(\nNichol, Achiam & Schulman, 2018\n) is a remarkably simple meta-learning optimization algorithm. It is similar to MAML in many ways, given that both rely on meta-optimization through gradient descent and both are model-agnostic.\nThe Reptile works by repeatedly:\nsampling a task,\ntraining on it by multiple gradient descent steps,\nand then moving the model weights towards the new parameters.\nSee the algorithm below:\n$\\text{SGD}(\\mathcal{L}_{\\tau_i}, \\theta, k)$ performs stochastic gradient update for k steps on the loss $\\mathcal{L}_{\\tau_i}$ starting with initial parameter $\\theta$ and returns the final parameter vector. The batch version samples multiple tasks instead of one within each iteration. The reptile gradient is defined as $(\\theta - W)/\\alpha$, where $\\alpha$ is the stepsize used by the SGD operation.\nThe batched version of Reptile algorithm. (Image source:\noriginal paper\n)\nAt a glance, the algorithm looks a lot like an ordinary SGD. However, because the task-specific optimization can take more than one step. it eventually makes $\\text{SGD}(\\mathbb{E}\n_\\tau[\\mathcal{L}_{\\tau}], \\theta, k)$ diverge from $\\mathbb{E}_\\tau [\\text{SGD}(\\mathcal{L}_{\\tau}, \\theta, k)]$ when k > 1.\nThe Optimization Assumption\n#\nAssuming that a task $\\tau \\sim p(\\tau)$ has a manifold of optimal network configuration, $\\mathcal{W}_{\\tau}^*$. The model $f_\\theta$ achieves the best performance for task $\\tau$ when $\\theta$ lays on the surface of $\\mathcal{W}_{\\tau}^*$. To find a solution that is good across tasks, we would like to find a parameter close to all the optimal manifolds of all tasks:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\tau \\sim p(\\tau)} [\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_\\tau^*)^2]\n$$\nThe Reptile algorithm updates the parameter alternatively to be closer to the optimal manifolds of different tasks. (Image source:\noriginal paper\n)\nLet’s use the L2 distance as $\\text{dist}(.)$ and the distance between a point $\\theta$ and a set $\\mathcal{W}_\\tau^*$ equals to the distance between $\\theta$ and a point $W_{\\tau}^*(\\theta)$ on the manifold that is closest to $\\theta$:\n$$\n\\text{dist}(\\theta, \\mathcal{W}_{\\tau}^*) = \\text{dist}(\\theta, W_{\\tau}^*(\\theta)) \\text{, where }W_{\\tau}^*(\\theta) = \\arg\\min_{W\\in\\mathcal{W}_{\\tau}^*} \\text{dist}(\\theta, W)\n$$\nThe gradient of the squared euclidean distance is:\n$$\n\\begin{aligned}\n\\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2]\n&= \\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\nabla_\\theta[\\frac{1}{2}(\\theta - W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\theta - W_{\\tau_i}^*(\\theta) & \\scriptstyle{\\text{; See notes.}}\n\\end{aligned}\n$$\nNotes: According to the Reptile paper,\n“the gradient of the squared euclidean distance between a point $\\Theta$ and a set $S$ is the vector $2(\\Theta − p)$, where p is the closest point in $S$ to $\\Theta$”\n. Technically the closest point in $S$ is also a function of $\\Theta$, but I’m not sure why the gradient does not need to worry about the derivative of $p$. (Please feel free to leave me a comment or send me an email about this if you have ideas.)\nThus the update rule for one stochastic gradient step is:\n$$\n\\theta = \\theta - \\alpha \\nabla_\\theta[\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2] = \\theta - \\alpha(\\theta - W_{\\tau_i}^*(\\theta)) = (1-\\alpha)\\theta + \\alpha W_{\\tau_i}^*(\\theta)\n$$\nThe closest point on the optimal task manifold $W_{\\tau_i}^*(\\theta)$ cannot be computed exactly, but Reptile approximates it using $\\text{SGD}(\\mathcal{L}_\\tau, \\theta, k)$.\nReptile vs FOMAML\n#\nTo demonstrate the deeper connection between Reptile and MAML, let’s expand the update formula with an example performing two gradient steps, k=2 in $\\text{SGD}(.)$. Same as defined\nabove\n, $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ are losses using different mini-batches of data. For ease of reading, we adopt two simplified annotations: $g^{(i)}_j = \\nabla_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$ and $H^{(i)}_j = \\nabla^2_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$.\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)= \\theta_0 - \\alpha g^{(0)}_0 \\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(1)}(\\theta_1) = \\theta_0 - \\alpha g^{(0)}_0 - \\alpha g^{(1)}_1\n\\end{aligned}\n$$\nAccording to the\nearly section\n, the gradient of FOMAML is the last inner gradient update result. Therefore, when k=1:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) = g^{(1)}_1 \\\\\ng_\\text{MAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) \\cdot (I - \\alpha\\nabla^2_{\\theta} \\mathcal{L}^{(0)}(\\theta_0)) = g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1\n\\end{aligned}\n$$\nThe Reptile gradient is defined as:\n$$\ng_\\text{Reptile} = (\\theta_0 - \\theta_2) / \\alpha = g^{(0)}_0 + g^{(1)}_1\n$$\nUp to now we have:\nReptile versus FOMAML in one loop of meta-optimization. (Image source:\nslides\non Reptile by Yoonho Lee.)\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 \\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\ng_\\text{Reptile} &= g^{(0)}_0 + g^{(1)}_1\n\\end{aligned}\n$$\nNext let’s try further expand $g^{(1)}_1$ using\nTaylor expansion\n. Recall that Taylor expansion of a function $f(x)$ that is differentiable at a number $a$ is:\n$$\nf(x) = f(a) + \\frac{f'(a)}{1!}(x-a) + \\frac{f''(a)}{2!}(x-a)^2 + \\dots = \\sum_{i=0}^\\infty \\frac{f^{(i)}(a)}{i!}(x-a)^i\n$$\nWe can consider $\\nabla_{\\theta}\\mathcal{L}^{(1)}(.)$ as a function and $\\theta_0$ as a value point. The Taylor expansion of $g_1^{(1)}$ at the value point $\\theta_0$ is:\n$$\n\\begin{aligned}\ng_1^{(1)} &= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_1) \\\\\n&= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_0) + \\nabla^2_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0) + \\frac{1}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0)^2 + \\dots & \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + \\frac{\\alpha^2}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0) (g_0^{(0)})^2 + \\dots & \\scriptstyle{\\text{; because }\\theta_1-\\theta_0=-\\alpha g_0^{(0)}} \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nPlug in the expanded form of $g_1^{(1)}$ into the MAML gradients with one step inner gradient update:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 = g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2) - \\alpha H^{(0)}_0 (g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2))\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + \\alpha^2 \\alpha H^{(0)}_0 H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\n\\end{aligned}\n$$\nThe Reptile gradient becomes:\n$$\n\\begin{aligned}\ng_\\text{Reptile} \n&= g^{(0)}_0 + g^{(1)}_1 \\\\\n&= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nSo far we have the formula of three types of gradients:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\\\\\ng_\\text{Reptile}  &= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nDuring training, we often average over multiple data batches. In our example, the mini batches (0) and (1) are interchangeable since both are drawn at random. The expectation $\\mathbb{E}_{\\tau,0,1}$ is averaged over two data batches, ids (0) and (1), for task $\\tau$.\nLet,\n$A = \\mathbb{E}_{\\tau,0,1} [g_0^{(0)}] = \\mathbb{E}_{\\tau,0,1} [g_0^{(1)}]$; it is the average gradient of task loss. We expect to improve the model parameter to achieve better task performance by following this direction pointed by $A$.\n$B = \\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)} + H^{(0)}_0 g_0^{(1)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [\\nabla_\\theta(g^{(0)}_0 g_0^{(1)})]$; it is the direction (gradient) that increases the inner product of gradients of two different mini batches for the same task. We expect to improve the model parameter to achieve better generalization over different data by following this direction pointed by $B$.\nTo conclude, both MAML and Reptile aim to optimize for the same goal, better task performance (guided by A) and better generalization (guided by B), when the gradient update is approximated by first three leading terms.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\tau,1,2}[g_\\text{FOMAML}] &= A - \\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{MAML}] &= A - 2\\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{Reptile}]  &= 2A - \\alpha B + O(\\alpha^2)\n\\end{aligned}\n$$\nIt is not clear to me whether the ignored term $O(\\alpha^2)$ might play a big impact on the parameter learning. But given that FOMAML is able to obtain a similar performance as the full version of MAML, it might be safe to say higher-level derivatives would not be critical during gradient descent update.\nCited as:\n@article{weng2018metalearning,\n  title   = \"Meta-Learning: Learning to Learn Fast\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-11-30-meta-learning/\"\n}\nReference\n#\n[1] Brenden M. Lake, Ruslan Salakhutdinov, and Joshua B. Tenenbaum.\n“Human-level concept learning through probabilistic program induction.”\nScience 350.6266 (2015): 1332-1338.\n[2] Oriol Vinyals’ talk on\n“Model vs Optimization Meta Learning”\n[3] Gregory Koch, Richard Zemel, and Ruslan Salakhutdinov.\n“Siamese neural networks for one-shot image recognition.”\nICML Deep Learning Workshop. 2015.\n[4] Oriol Vinyals, et al.\n“Matching networks for one shot learning.”\nNIPS. 2016.\n[5] Flood Sung, et al.\n“Learning to compare: Relation network for few-shot learning.”\nCVPR. 2018.\n[6] Jake Snell, Kevin Swersky, and Richard Zemel.\n“Prototypical Networks for Few-shot Learning.”\nCVPR. 2018.\n[7] Adam Santoro, et al.\n“Meta-learning with memory-augmented neural networks.”\nICML. 2016.\n[8] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).\n[9] Tsendsuren Munkhdalai and Hong Yu.\n“Meta Networks.”\nICML. 2017.\n[10] Sachin Ravi and Hugo Larochelle.\n“Optimization as a Model for Few-Shot Learning.”\nICLR. 2017.\n[11] Chelsea Finn’s BAIR blog on\n“Learning to Learn”\n.\n[12] Chelsea Finn, Pieter Abbeel, and Sergey Levine.\n“Model-agnostic meta-learning for fast adaptation of deep networks.”\nICML 2017.\n[13] Alex Nichol, Joshua Achiam, John Schulman.\n“On First-Order Meta-Learning Algorithms.”\narXiv preprint arXiv:1803.02999 (2018).\n[14]\nSlides on Reptile\nby Yoonho Lee.",
            "metadata": {
              "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
              "description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "keywords": "meta-learning, long-read",
              "author": "Lilian Weng",
              "og:title": "Meta-Learning: Learning to Learn Fast",
              "og:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
              "twitter:card": "summary",
              "twitter:title": "Meta-Learning: Learning to Learn Fast",
              "twitter:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "article:section": "posts",
              "article:published_time": "2018-11-30T00:00:00+00:00",
              "article:modified_time": "2018-11-30T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/a8dc6bf17c71/code/body-000.txt",
                "chars": 245,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "bytes": 1548239,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-23d602a28b9d9dda6fe1.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "bytes": 665187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-11419d5ec12fba3fb7f9.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "bytes": 730525,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-34f37f1d8bf391fe9f42.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "bytes": 808103,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-851555a6cfa04864e872.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "bytes": 184486,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-1195100b0c6841a237dd.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-c47eeb17ebb22f866942.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "bytes": 273207,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9ae2425c1e62b530a443.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "bytes": 174582,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-cb826c25071414ad89e4.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "bytes": 405772,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-0167fe1ca07386abf1d2.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "bytes": 1245251,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-ae1778af670dfaca75e8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "bytes": 397702,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9baa7ed8723c2cae889a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "bytes": 102014,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-f1b0701dad5bcf83ef5a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "bytes": 195622,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-7f2ae4aa3936d2a466d8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "bytes": 286187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d947284bd0373951e25d.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "bytes": 124913,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-830017a377b95ff33b98.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "bytes": 1295521,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d0137fe96ca3220fcf1f.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://wei-tianhao.github.io/blog/2019/09/17/meta-learning.html",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "label": "learning to learn",
                "type": "a"
              },
              {
                "href": "https://www.pinterest.com/",
                "label": "Pinterest",
                "type": "a"
              },
              {
                "href": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "k-NN",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-means_clustering",
                "label": "k-means",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_density_estimation",
                "label": "kernel density estimation",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Similarity_learning",
                "label": "Metric learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "label": "Siamese Neural Network",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "label": "Koch, Zemel & Salakhutdinov (2015)",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "label": "Sung et al., 2018",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/neural-approach-relational-reasoning/",
                "label": "Relation Network",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "label": "Snell, Swersky & Zemel, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "Neural Turing Machines",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.3916",
                "label": "Memory Networks",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "label": "Santoro et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cache_replacement_policies",
                "label": "cache replacement",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Least_frequently_used",
                "label": "LFU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.00837",
                "label": "Munkhdalai & Yu, 2017",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll",
                "label": "Ravi & Larochelle (2017)",
                "type": "a"
              },
              {
                "href": "http://ruder.io/optimizing-gradient-descent/index.html",
                "label": "momentum",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll)",
                "label": "original paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04474",
                "label": "idea",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol, Achiam & Schulman, 2018",
                "type": "a"
              },
              {
                "href": "https://www.slideshare.net/YoonhoLee4/on-firstorder-metalearning-algorithms",
                "label": "slides",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Taylor_series",
                "label": "Taylor expansion",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "“Neural turing machines.”",
                "type": "a"
              },
              {
                "href": "https://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "“Learning to Learn”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:39Z",
            "source_url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "bytes": 1826353,
                "reused": false,
                "local_path": "papers/repair/da4e56c26698557aa61c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='metalearning-symposium.ml', port=80): Max retries exceeded with url: /files/vinyals.pdf (Caused by NameResolutionError(\"HTTPConnection(host='metalearning-s",
                "retried_at": "2026-10-20T22:24:44Z"
              },
              {
                "status": "http_404",
                "url": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "retried_at": "2026-10-20T18:04:05Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "bytes": 766340,
                "reused": false,
                "local_path": "papers/repair/fde088adb2e69f52cd16.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": false,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "bytes": 798122,
                "reused": false,
                "local_path": "papers/repair/1dce78ce43bce934d7c8.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "bytes": 536399,
                "reused": false,
                "local_path": "papers/repair/33350b7fc96a8da3fa63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.3916",
                "bytes": 215900,
                "reused": false,
                "local_path": "papers/repair/e6bb14affb9d1f13f660.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "bytes": 1648270,
                "reused": false,
                "local_path": "papers/repair/b9ba58828decfbd2ad1e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00837",
                "bytes": 455366,
                "reused": false,
                "local_path": "papers/repair/b15e9ef4f202cbfada2c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04474",
                "bytes": 2702892,
                "reused": false,
                "local_path": "papers/repair/76aa0aeb7717cd2e1f8f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": false,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": true,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46235,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/a8dc6bf17c71/pages/source.html",
            "local_html": "attachments/a8dc6bf17c71/pages/article.html",
            "body_base_path": "attachments/a8dc6bf17c71/pages/",
            "body_markdown_path": "attachments/a8dc6bf17c71/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
          "status": "partial",
          "article_id": "ebc73787cbe5",
          "local_path": "series-follow/1602/repair/ffba49f79f0eef15a925.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
              "bytes": 259350,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/394ec3f8b6a6ccc3dace.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
              "bytes": 205392,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9c60abbe659d28457d7a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
              "bytes": 275060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a8004105b4a88c05a952.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
              "bytes": 581593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7bc12620d13d41e17f0a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
              "bytes": 215084,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a1617c1aadd4262ae84a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
              "bytes": 181566,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/01ca9a7ea1e7d1cd82a2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
              "bytes": 294810,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a362a645159f0dafa82d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
              "bytes": 860130,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/fafbbe0c69813ea86bf2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
              "bytes": 742699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d58e26716f1f269dae8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
              "bytes": 300409,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5e0d3d90650b6cca848e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
              "bytes": 497568,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a29af53d479214903180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
              "bytes": 332210,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0061164751ee7e193a70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
              "bytes": 253972,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/58ac4a854eb578c151aa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
              "bytes": 567524,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6b398117113938e66d50.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Policy Gradient Algorithms",
            "keywords": "策略梯度,PG,强化学习",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "publish_date": "2018-04",
            "corpus_stage": "强化学习/对齐",
            "notes": "策略梯度算法大全（REINFORCE、PPO等）",
            "id": "ebc73787cbe5",
            "collected_at": "2026-10-02T14:13:21",
            "title": "Policy Gradient Algorithms | Lil'Log",
            "body_markdown": "[Updated on 2018-06-30: add two new policy gradient methods,\nSAC\nand\nD4PG\n.]\n[Updated on 2018-09-30: add a new policy gradient method,\nTD3\n.]\n[Updated on 2019-02-09: add\nSAC with automatically adjusted temperature\n].\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in\nKorean\n].\n[Updated on 2019-09-12: add a new policy gradient method\nSVPG\n.]\n[Updated on 2019-12-22: add a new policy gradient method\nIMPALA\n.]\n[Updated on 2020-10-15: add a new policy gradient method\nPPG\n& some new discussion in\nPPO\n.]\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in\nChinese1\n&\nChinese2\n].\nWhat is Policy Gradient\n#\nPolicy gradient is an approach to solve reinforcement learning problems. If you haven’t looked into the field of reinforcement learning, please first read the section\n“A (Long) Peek into Reinforcement Learning » Key Concepts”\nfor the problem definition and key concepts.\nNotations\n#\nHere is a list of notations to help you read through equations in the post easily.\nSymbol\nMeaning\n$s \\in \\mathcal{S}$\nStates.\n$a \\in \\mathcal{A}$\nActions.\n$r \\in \\mathcal{R}$\nRewards.\n$S_t, A_t, R_t$\nState, action, and reward at time step $t$ of one trajectory. I may occasionally use $s_t, a_t, r_t$ as well.\n$\\gamma$\nDiscount factor; penalty to uncertainty of future rewards; $0<\\gamma \\leq 1$.\n$G_t$\nReturn; or discounted future reward; $G_t = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}$.\n$P(s’, r \\vert s, a)$\nTransition probability of getting to the next state $s’$ from the current state $s$ with action $a$ and reward $r$.\n$\\pi(a \\vert s)$\nStochastic policy (agent behavior strategy); $\\pi_\\theta(.)$ is a policy parameterized by $\\theta$.\n$\\mu(s)$\nDeterministic policy; we can also label this as $\\pi(s)$, but using a different letter gives better distinction so that we can easily tell when the policy is stochastic or deterministic without further explanation. Either $\\pi$ or $\\mu$ is what a reinforcement learning algorithm aims to learn.\n$V(s)$\nState-value function measures the expected return of state $s$; $V_w(.)$ is a value function parameterized by $w$.\n$V^\\pi(s)$\nThe value of state $s$ when we follow a policy $\\pi$; $V^\\pi (s) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s]$.\n$Q(s, a)$\nAction-value function is similar to $V(s)$, but it assesses the expected return of a pair of state and action $(s, a)$; $Q_w(.)$ is a action value function parameterized by $w$.\n$Q^\\pi(s, a)$\nSimilar to $V^\\pi(.)$, the value of (state, action) pair when we follow a policy $\\pi$; $Q^\\pi(s, a) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s, A_t = a]$.\n$A(s, a)$\nAdvantage function, $A(s, a) = Q(s, a) - V(s)$; it can be considered as another version of Q-value with lower variance by taking the state-value off as the baseline.\nPolicy Gradient\n#\nThe goal of reinforcement learning is to find an optimal behavior strategy for the agent to obtain optimal rewards. The\npolicy gradient\nmethods target at modeling and optimizing the policy directly. The policy is usually modeled with a parameterized function respect to $\\theta$, $\\pi_\\theta(a \\vert s)$. The value of the reward (objective) function depends on this policy and then various algorithms can be applied to optimize $\\theta$ for the best reward.\nThe reward function is defined as:\n$$\nJ(\\theta) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) V^\\pi(s) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a)\n$$\nwhere $d^\\pi(s)$ is the stationary distribution of Markov chain for $\\pi_\\theta$ (on-policy state distribution under $\\pi$). For simplicity, the parameter $\\theta$ would be omitted for the policy $\\pi_\\theta$ when the policy is present in the subscript of other functions; for example, $d^{\\pi}$ and $Q^\\pi$ should be $d^{\\pi_\\theta}$ and $Q^{\\pi_\\theta}$ if written in full.\nImagine that you can travel along the Markov chain’s states forever, and eventually, as the time progresses, the probability of you ending up with one state becomes unchanged — this is the stationary probability for $\\pi_\\theta$. $d^\\pi(s) = \\lim_{t \\to \\infty} P(s_t = s \\vert s_0, \\pi_\\theta)$ is the probability that $s_t=s$ when starting from $s_0$ and following policy $\\pi_\\theta$ for t steps. Actually, the existence of the stationary distribution of Markov chain is one main reason for why PageRank algorithm works. If you want to read more, check\nthis\n.\nIt is natural to expect policy-based methods are more useful in the continuous space. Because there is an infinite number of actions and (or) states to estimate the values for and hence value-based approaches are way too expensive computationally in the continuous space. For example, in\ngeneralized policy iteration\n, the policy improvement step $\\arg\\max_{a \\in \\mathcal{A}} Q^\\pi(s, a)$ requires a full scan of the action space, suffering from the\ncurse of dimensionality\n.\nUsing\ngradient ascent\n, we can move $\\theta$ toward the direction suggested by the gradient $\\nabla_\\theta J(\\theta)$ to find the best $\\theta$ for $\\pi_\\theta$ that produces the highest return.\nPolicy Gradient Theorem\n#\nComputing the gradient $\\nabla_\\theta J(\\theta)$ is tricky because it depends on both the action selection (directly determined by $\\pi_\\theta$) and the stationary distribution of states following the target selection behavior (indirectly determined by $\\pi_\\theta$). Given that the environment is generally unknown, it is difficult to estimate the effect on the state distribution by a policy update.\nLuckily, the\npolicy gradient theorem\ncomes to save the world! Woohoo! It provides a nice reformation of the derivative of the objective function to not involve the derivative of the state distribution $d^\\pi(.)$ and simplify the gradient computation $\\nabla_\\theta J(\\theta)$ a lot.\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\nabla_\\theta \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\\\\n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \n\\end{aligned}\n$$\nProof of Policy Gradient Theorem\n#\nThis session is pretty dense, as it is the time for us to go through the proof (\nSutton & Barto, 2017\n; Sec. 13.1) and figure out why the policy gradient theorem is correct.\nWe first start with the derivative of the state value function:\n$$\n\\begin{aligned}\n& \\nabla_\\theta V^\\pi(s) \\\\\n=& \\nabla_\\theta \\Big(\\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s)Q^\\pi(s, a) \\Big) & \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta Q^\\pi(s, a)} \\Big) & \\scriptstyle{\\text{; Derivative product rule.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta \\sum_{s', r} P(s',r \\vert s,a)(r + V^\\pi(s'))} \\Big) & \\scriptstyle{\\text{; Extend } Q^\\pi \\text{ with future state value.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s', r} P(s',r \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{P(s',r \\vert s,a) \\text{ or } r \\text{ is not a func of }\\theta}\\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s'} P(s' \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{\\text{; Because }  P(s' \\vert s, a) = \\sum_r P(s', r \\vert s, a)}\n\\end{aligned}\n$$\nNow we have:\n$$\n\\color{red}{\\nabla_\\theta V^\\pi(s)} \n= \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\Big)\n$$\nThis equation has a nice recursive form (see the red parts!) and the future state value function $V^\\pi(s’)$ can be repeated unrolled by following the same equation.\nLet’s consider the following visitation sequence and label the probability of transitioning from state s to state x with policy $\\pi_\\theta$ after k step as $\\rho^\\pi(s \\to x, k)$.\n$$\ns \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s)} s' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s')} s'' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s'')} \\dots\n$$\nWhen k = 0: $\\rho^\\pi(s \\to s, k=0) = 1$.\nWhen k = 1, we scan through all possible actions and sum up the transition probabilities to the target state: $\\rho^\\pi(s \\to s’, k=1) = \\sum_a \\pi_\\theta(a \\vert s) P(s’ \\vert s, a)$.\nImagine that the goal is to go from state s to x after k+1 steps while following policy $\\pi_\\theta$. We can first travel from s to a middle point s’ (any state can be a middle point, $s’ \\in \\mathcal{S}$) after k steps and then go to the final state x during the last step. In this way, we are able to update the visitation probability recursively: $\\rho^\\pi(s \\to x, k+1) = \\sum_{s’} \\rho^\\pi(s \\to s’, k) \\rho^\\pi(s’ \\to x, 1)$.\nThen we go back to unroll the recursive representation of $\\nabla_\\theta V^\\pi(s)$! Let $\\phi(s) = \\sum_{a \\in \\mathcal{A}} \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a)$ to simplify the maths. If we keep on extending $\\nabla_\\theta V^\\pi(.)$ infinitely, it is easy to find out that we can transition from the starting state s to any state after any number of steps in this unrolling process and by summing up all the visitation probabilities, we get $\\nabla_\\theta V^\\pi(s)$!\n$$\n\\begin{aligned}\n& \\color{red}{\\nabla_\\theta V^\\pi(s)} \\\\\n=& \\phi(s) + \\sum_a \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\sum_a \\pi_\\theta(a \\vert s) P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s')Q^\\pi(s', a) + \\pi_\\theta(a \\vert s') \\sum_{s'} P(s'' \\vert s',a) \\nabla_\\theta V^\\pi(s'') \\Big)} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{[ \\phi(s') + \\sum_{s''} \\rho^\\pi(s' \\to s'', 1) \\nabla_\\theta V^\\pi(s'')]} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\color{red}{\\nabla_\\theta V^\\pi(s'')} \\scriptstyle{\\text{ ; Consider }s'\\text{ as the middle point for }s \\to s''}\\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\phi(s'') + \\sum_{s'''} \\rho^\\pi(s \\to s''', 3)\\color{red}{\\nabla_\\theta V^\\pi(s''')} \\\\\n=& \\dots \\scriptstyle{\\text{; Repeatedly unrolling the part of }\\nabla_\\theta V^\\pi(.)} \\\\\n=& \\sum_{x\\in\\mathcal{S}}\\sum_{k=0}^\\infty \\rho^\\pi(s \\to x, k) \\phi(x)\n\\end{aligned}\n$$\nThe nice rewriting above allows us to exclude the derivative of Q-value function, $\\nabla_\\theta Q^\\pi(s, a)$. By plugging it into the objective function $J(\\theta)$, we are getting the following:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta V^\\pi(s_0) & \\scriptstyle{\\text{; Starting from a random state } s_0} \\\\\n&= \\sum_{s}\\color{blue}{\\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)} \\phi(s) &\\scriptstyle{\\text{; Let }\\color{blue}{\\eta(s) = \\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)}} \\\\\n&= \\sum_{s}\\eta(s) \\phi(s) & \\\\\n&= \\Big( {\\sum_s \\eta(s)} \\Big)\\sum_{s}\\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\text{; Normalize } \\eta(s), s\\in\\mathcal{S} \\text{ to be a probability distribution.}}\\\\\n&\\propto \\sum_s \\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\sum_s \\eta(s)\\text{  is a constant}} \\\\\n&= \\sum_s d^\\pi(s) \\sum_a \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) & \\scriptstyle{d^\\pi(s) = \\frac{\\eta(s)}{\\sum_s \\eta(s)}\\text{ is stationary distribution.}}\n\\end{aligned}\n$$\nIn the episodic case, the constant of proportionality ($\\sum_s \\eta(s)$) is the average length of an episode; in the continuing case, it is 1 (\nSutton & Barto, 2017\n; Sec. 13.2). The gradient can be further written as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s)  &\\\\\n&= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} &\\\\\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\scriptstyle{\\text{; Because } (\\ln x)' = 1/x}\n\\end{aligned}\n$$\nWhere $\\mathbb{E}_\\pi$ refers to $\\mathbb{E}_{s \\sim d_\\pi, a \\sim \\pi_\\theta}$ when both state and action distributions follow the policy $\\pi_\\theta$ (on policy).\nThe policy gradient theorem lays the theoretical foundation for various policy gradient algorithms. This vanilla policy gradient update has no bias but high variance. Many following algorithms were proposed to reduce the variance while keeping the bias unchanged.\n$$\n\\nabla_\\theta J(\\theta)  = \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)]\n$$\nHere is a nice summary of a general form of policy gradient methods borrowed from the\nGAE\n(general advantage estimation) paper (\nSchulman et al., 2016\n) and this\npost\nthoroughly discussed several components in GAE , highly recommended.\nA general form of policy gradient methods. (Image source:\nSchulman et al., 2016\n)\nPolicy Gradient Algorithms\n#\nTons of policy gradient algorithms have been proposed during recent years and there is no way for me to exhaust them. I’m introducing some of them that I happened to know and read about.\nREINFORCE\n#\nREINFORCE\n(Monte-Carlo policy gradient) relies on an estimated return by\nMonte-Carlo\nmethods using episode samples to update the policy parameter $\\theta$. REINFORCE works because the expectation of the sample gradient is equal to the actual gradient:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\\\\n&= \\mathbb{E}_\\pi [G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)] & \\scriptstyle{\\text{; Because } Q^\\pi(S_t, A_t) = \\mathbb{E}_\\pi[G_t \\vert S_t, A_t]}\n\\end{aligned}\n$$\nTherefore we are able to measure $G_t$ from real sample trajectories and use that to update our policy gradient. It relies on a full trajectory and that’s why it is a Monte-Carlo method.\nThe process is pretty straightforward:\nInitialize the policy parameter $\\theta$ at random.\nGenerate one trajectory on policy $\\pi_\\theta$: $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$.\nFor t=1, 2, … , T:\nEstimate the the return $G_t$;\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)$\nA widely used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to\nreduce the variance of gradient estimation while keeping the bias unchanged\n(Remember we always want to do this when possible). For example, a common baseline is to subtract state-value from action-value, and if applied, we would use advantage $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update. This\npost\nnicely explained why a baseline works for reducing the variance, in addition to a set of fundamentals of policy gradient.\nActor-Critic\n#\nTwo main components in policy gradient are the policy model and the value function. It makes a lot of sense to learn the value function in addition to the policy, since knowing the value function can assist the policy update, such as by reducing gradient variance in vanilla policy gradients, and that is exactly what the\nActor-Critic\nmethod does.\nActor-critic methods consist of two models, which may optionally share parameters:\nCritic\nupdates the value function parameters w and depending on the algorithm it could be action-value $Q_w(a \\vert s)$ or state-value $V_w(s)$.\nActor\nupdates the policy parameters $\\theta$ for $\\pi_\\theta(a \\vert s)$, in the direction suggested by the critic.\nLet’s see how it works in a simple action-value actor-critic algorithm.\nInitialize $s, \\theta, w$ at random; sample $a \\sim \\pi_\\theta(a \\vert s)$.\nFor $t = 1 \\dots T$:\nSample reward $r_t \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$;\nThen sample the next action $a’ \\sim \\pi_\\theta(a’ \\vert s’)$;\nUpdate the policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q_w(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)$;\nCompute the correction (TD error) for action-value at time t:\n$\\delta_t = r_t + \\gamma Q_w(s’, a’) - Q_w(s, a)$\nand use it to update the parameters of action-value function:\n$w \\leftarrow w + \\alpha_w \\delta_t \\nabla_w Q_w(s, a)$\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\nTwo learning rates, $\\alpha_\\theta$ and $\\alpha_w$, are predefined for policy and value function parameter updates respectively.\nOff-Policy Policy Gradient\n#\nBoth REINFORCE and the vanilla version of actor-critic method are on-policy: training samples are collected according to the target policy — the very same policy that we try to optimize for. Off policy methods, however, result in several additional advantages:\nThe off-policy approach does not require full trajectories and can reuse any past episodes (\n“experience replay”\n) for much better sample efficiency.\nThe sample collection follows a behavior policy different from the target policy, bringing better\nexploration\n.\nNow let’s see how off-policy policy gradient is computed. The behavior policy for collecting samples is a known policy (predefined just like a hyperparameter), labelled as $\\beta(a \\vert s)$. The objective function sums up the reward over the state distribution defined by this behavior policy:\n$$\nJ(\\theta)\n= \\sum_{s \\in \\mathcal{S}} d^\\beta(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)\n= \\mathbb{E}_{s \\sim d^\\beta} \\big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\big]\n$$\nwhere $d^\\beta(s)$ is the stationary distribution of the behavior policy $\\beta$; recall that $d^\\beta(s) = \\lim_{t \\to \\infty} P(S_t = s \\vert S_0, \\beta)$; and $Q^\\pi$ is the action-value function estimated with regard to the target policy $\\pi$ (not the behavior policy!).\nGiven that the training observations are sampled by $a \\sim \\beta(a \\vert s)$, we can rewrite the gradient as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)  \\Big] & \\\\ \n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\big( Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) + \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)} \\big) \\Big] & \\scriptstyle{\\text{; Derivative product rule.}}\\\\\n&\\stackrel{(i)}{\\approx} \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; Ignore the red part: } \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)}}. \\\\\n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} \\Big] & \\\\\n&= \\mathbb{E}_\\beta \\Big[\\frac{\\color{blue}{\\pi_\\theta(a \\vert s)}}{\\color{blue}{\\beta(a \\vert s)}} Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; The blue part is the importance weight.}}\n\\end{aligned}\n$$\nwhere $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$ is the\nimportance weight\n. Because $Q^\\pi$ is a function of the target policy and thus a function of policy parameter $\\theta$,  we should take the derivative of $\\nabla_\\theta Q^\\pi(s, a)$ as well according to the product rule. However, it is super hard to compute $\\nabla_\\theta Q^\\pi(s, a)$ in reality. Fortunately if we use an approximated gradient with the gradient of Q ignored, we still guarantee the policy improvement and eventually achieve the true local minimum. This is justified in the proof\nhere\n(Degris, White & Sutton, 2012).\nIn summary, when applying policy gradient in the off-policy setting, we can simple adjust it with a weighted sum and the weight is the ratio of the target policy to the behavior policy, $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$.\nA3C\n#\n[\npaper\n|\ncode\n]\nAsynchronous Advantage Actor-Critic\n(\nMnih et al., 2016\n), short for\nA3C\n, is a classic policy gradient method with a special focus on parallel training.\nIn A3C, the critics learn the value function while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is designed to work well for parallel training.\nLet’s use the state-value function as an example. The loss function for state value is to minimize the mean squared error, $J_v(w) = (G_t - V_w(s))^2$ and gradient descent can be applied to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, $\\theta$ and $w$; similar thread-specific parameters, $\\theta’$ and $w’$.\nInitialize the time step $t = 1$\nWhile $T \\leq T_\\text{MAX}$:\nReset gradient: $\\mathrm{d}\\theta = 0$ and $\\mathrm{d}w = 0$.\nSynchronize thread-specific parameters with global ones: $\\theta’ = \\theta$ and $w’ = w$.\n$t_\\text{start}$ = t and sample a starting state $s_t$.\nWhile ($s_t$ != TERMINAL) and $t - t_\\text{start} \\leq t_\\text{max}$:\nPick the action $A_t \\sim \\pi_{\\theta’}(A_t \\vert S_t)$ and receive a new reward $R_t$ and a new state $s_{t+1}$.\nUpdate $t = t + 1$ and $T = T + 1$\nInitialize the variable that holds the return estimation\n$$\n R = \\begin{cases} \n 0 & \\text{if } s_t \\text{ is TERMINAL} \\\\\n V_{w'}(s_t) & \\text{otherwise}\n \\end{cases}\n $$\n6. For $i = t-1, \\dots, t\\_\\text{start}$:\n     1. $R \\leftarrow \\gamma R + R\\_i$; here R is a MC measure of $G\\_i$.\n     2. Accumulate gradients w.r.t. $\\theta'$: $d\\theta \\leftarrow d\\theta + \\nabla\\_{\\theta'} \\log \\pi\\_{\\theta'}(a\\_i \\vert s\\_i)(R - V\\_{w'}(s\\_i))$;\nAccumulate gradients w.r.t. w': $dw \\leftarrow dw + 2 (R - V\\_{w'}(s\\_i)) \\nabla\\_{w'} (R - V\\_{w'}(s\\_i))$.\nUpdate asynchronously $\\theta$ using $\\mathrm{d}\\theta$, and $w$ using $\\mathrm{d}w$.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a parallelized reformation of minibatch-based stochastic gradient update: the values of $w$ or $\\theta$ get corrected by a little bit in the direction of each training thread independently.\nA2C\n#\n[\npaper\n|\ncode\n]\nA2C\nis a synchronous, deterministic version of A3C; that’s why it is named as “A2C” with the first “A” (“asynchronous”) removed. In A3C each agent talks to the global parameters independently, so it is possible sometimes the thread-specific agents would be playing with policies of different versions and therefore the aggregated update would not be optimal. To resolve the inconsistency, a coordinator in A2C waits for all the parallel actors to finish their work before updating the global parameters and then in the next iteration parallel actors starts from the same policy. The synchronized gradient update keeps the training more cohesive and potentially to make convergence faster.\nA2C has been\nshown\nto be able to utilize GPUs more efficiently and work better with large batch sizes while achieving same or better performance than A3C.\nThe architecture of A3C versus A2C.\nDPG\n#\n[\npaper\n|code]\nIn methods described above, the policy function $\\pi(. \\vert s)$ is always modeled as a probability distribution over actions $\\mathcal{A}$ given the current state and thus it is\nstochastic\n.\nDeterministic policy gradient (DPG)\ninstead models the policy as a deterministic decision: $a = \\mu(s)$. It may look bizarre — how can you calculate the gradient of the action probability when it outputs a single action? Let’s look into it step by step.\nRefresh on a few notations to facilitate the discussion:\n$\\rho_0(s)$: The initial distribution over states\n$\\rho^\\mu(s \\to s’, k)$: Starting from state s, the visitation probability density at state s’ after moving k steps by policy $\\mu$.\n$\\rho^\\mu(s’)$: Discounted state distribution, defined as $\\rho^\\mu(s’) = \\int_\\mathcal{S} \\sum_{k=1}^\\infty \\gamma^{k-1} \\rho_0(s) \\rho^\\mu(s \\to s’, k) ds$.\nThe objective function to optimize for is listed as follows:\n$$\nJ(\\theta) = \\int_\\mathcal{S} \\rho^\\mu(s) Q(s, \\mu_\\theta(s)) ds\n$$\nDeterministic policy gradient theorem\n: Now it is the time to compute the gradient! According to the chain rule, we first take the gradient of Q w.r.t. the action a and then take the gradient of the deterministic policy function $\\mu$ w.r.t. $\\theta$:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\int_\\mathcal{S} \\rho^\\mu(s) \\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)} ds \\\\\n&= \\mathbb{E}_{s \\sim \\rho^\\mu} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}]\n\\end{aligned}\n$$\nWe can consider the deterministic policy as a\nspecial case\nof the stochastic one, when the probability distribution contains only one extreme non-zero value over one action. Actually, in the DPG\npaper\n, the authors have shown that if the stochastic policy $\\pi_{\\mu_\\theta, \\sigma}$ is re-parameterized by a deterministic policy $\\mu_\\theta$ and a variation variable $\\sigma$, the stochastic policy is eventually equivalent to the deterministic case when $\\sigma=0$. Compared to the deterministic policy, we expect the stochastic policy to require more samples as it integrates the data over the whole state and action space.\nThe deterministic policy gradient theorem can be plugged into common policy gradient frameworks.\nLet’s consider an example of on-policy actor-critic algorithm to showcase the procedure. In each iteration of on-policy actor-critic, two actions are taken deterministically $a = \\mu_\\theta(s)$ and the\nSARSA\nupdate on policy parameters relies on the new gradient that we just computed above:\n$$\n\\begin{aligned}\n\\delta_t &= R_t + \\gamma Q_w(s_{t+1}, a_{t+1}) - Q_w(s_t, a_t) & \\small{\\text{; TD error in SARSA}}\\\\\nw_{t+1} &= w_t + \\alpha_w \\delta_t \\nabla_w Q_w(s_t, a_t) & \\\\\n\\theta_{t+1} &= \\theta_t + \\alpha_\\theta \\color{red}{\\nabla_a Q_w(s_t, a_t) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}} & \\small{\\text{; Deterministic policy gradient theorem}}\n\\end{aligned}\n$$\nHowever, unless there is sufficient noise in the environment, it is very hard to guarantee enough\nexploration\ndue to the determinacy of the policy. We can either add noise into the policy (ironically this makes it nondeterministic!) or learn it off-policy-ly by following a different stochastic behavior policy to collect samples.\nSay, in the off-policy approach, the training trajectories are generated by a stochastic policy $\\beta(a \\vert s)$ and thus the state distribution follows the corresponding discounted state density $\\rho^\\beta$:\n$$\n\\begin{aligned}\nJ_\\beta(\\theta) &= \\int_\\mathcal{S} \\rho^\\beta Q^\\mu(s, \\mu_\\theta(s)) ds \\\\\n\\nabla_\\theta J_\\beta(\\theta) &= \\mathbb{E}_{s \\sim \\rho^\\beta} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s)  \\rvert_{a=\\mu_\\theta(s)} ]\n\\end{aligned}\n$$\nNote that because the policy is deterministic, we only need $Q^\\mu(s, \\mu_\\theta(s))$ rather than $\\sum_a \\pi(a \\vert s) Q^\\pi(s, a)$ as the estimated reward of a given state s.\nIn the off-policy approach with a stochastic policy, importance sampling is often used to correct the mismatch between behavior and target policies, as what we have described\nabove\n. However, because the deterministic policy gradient removes the integral over actions, we can avoid importance sampling.\nDDPG\n#\n[\npaper\n|\ncode\n]\nDDPG\n(\nLillicrap, et al., 2015\n), short for\nDeep Deterministic Policy Gradient\n, is a model-free off-policy actor-critic algorithm, combining\nDPG\nwith\nDQN\n. Recall that DQN (Deep Q-Network) stabilizes the learning of Q-function by experience replay and the frozen target network. The original DQN works in discrete space, and DDPG extends it to continuous space with the actor-critic framework while learning a deterministic policy.\nIn order to do better exploration, an exploration policy $\\mu’$ is constructed by adding noise $\\mathcal{N}$:\n$$\n\\mu'(s) = \\mu_\\theta(s) + \\mathcal{N}\n$$\nIn addition, DDPG does soft updates (“conservative policy iteration”) on the parameters of both actor and critic, with $\\tau \\ll 1$: $\\theta’ \\leftarrow \\tau \\theta + (1 - \\tau) \\theta’$. In this way, the target network values are constrained to change slowly, different from the design in DQN that the target network stays frozen for some period of time.\nOne detail in the paper that is particularly useful in robotics is on how to normalize the different physical units of low dimensional features. For example, a model is designed to learn a policy with the robot’s positions and velocities as input; these physical statistics are different by nature and even statistics of the same type may vary a lot across multiple robots.\nBatch normalization\nis applied to fix it by normalizing every dimension across samples in one minibatch.\nFig 3. DDPG Algorithm. (Image source:\nLillicrap, et al., 2015\n)\nD4PG\n#\n[\npaper\n|code (Search “github d4pg” and you will see a few.)]\nDistributed Distributional DDPG (D4PG)\napplies a set of improvements on DDPG to make it run in the distributional fashion.\n(1)\nDistributional Critic\n: The critic estimates the expected Q value as a random variable ~ a distribution $Z_w$ parameterized by $w$ and therefore $Q_w(s, a) = \\mathbb{E} Z_w(x, a)$. The loss for learning the distribution parameter is to minimize some measure of the distance between two distributions — distributional TD error: $L(w) = \\mathbb{E}[d(\\mathcal{T}_{\\mu_\\theta}, Z_{w’}(s, a), Z_w(s, a)]$, where $\\mathcal{T}_{\\mu_\\theta}$ is the Bellman operator.\nThe deterministic policy gradient update becomes:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\approx \\mathbb{E}_{\\rho^\\mu} [\\nabla_a Q_w(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; gradient update in DPG}} \\\\\n&= \\mathbb{E}_{\\rho^\\mu} [\\mathbb{E}[\\nabla_a Z_w(s, a)] \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; expectation of the Q-value distribution.}}\n\\end{aligned}\n$$\n(2)\n$N$-step returns\n: When calculating the TD error, D4PG computes $N$-step TD target rather than one-step to incorporate rewards in more future steps. Thus the new TD target is:\n$$\nr(s_0, a_0) + \\mathbb{E}[\\sum_{n=1}^{N-1} r(s_n, a_n) + \\gamma^N Q(s_N, \\mu_\\theta(s_N)) \\vert s_0, a_0 ]\n$$\n(3)\nMultiple Distributed Parallel Actors\n: D4PG utilizes $K$ independent actors, gathering experience in parallel and feeding data into the same replay buffer.\n(4)\nPrioritized Experience Replay (\nPER\n)\n: The last piece of modification is to do sampling from the replay buffer of size $R$ with an non-uniform probability $p_i$. In this way, a sample $i$ has the probability $(Rp_i)^{-1}$ to be selected and thus the importance weight is $(Rp_i)^{-1}$.\nD4PG algorithm (Image source:\nBarth-Maron, et al. 2018\n); Note that in the original paper, the variable letters are chosen slightly differently from what in the post; i.e. I use $\\mu(.)$ for representing a deterministic policy instead of $\\pi(.)$.\nMADDPG\n#\n[\npaper\n|\ncode\n]\nMulti-agent DDPG\n(\nMADDPG\n) (\nLowe et al., 2017\n) extends DDPG to an environment where multiple agents are coordinating to complete tasks with only local information. In the viewpoint of one agent, the environment is non-stationary as policies of other agents are quickly upgraded and remain unknown. MADDPG is an actor-critic model redesigned particularly for handling such a changing environment and interactions between agents.\nThe problem can be formalized in the multi-agent version of MDP, also known as\nMarkov games\n. MADDPG is proposed for partially observable Markov games. Say, there are N agents in total with a set of states $\\mathcal{S}$. Each agent owns a set of possible action, $\\mathcal{A}_1, \\dots, \\mathcal{A}_N$, and a set of observation, $\\mathcal{O}_1, \\dots, \\mathcal{O}_N$. The state transition function involves all states, action and observation spaces  $\\mathcal{T}: \\mathcal{S} \\times \\mathcal{A}_1 \\times \\dots \\mathcal{A}_N \\mapsto \\mathcal{S}$. Each agent’s stochastic policy only involves its own state and action: $\\pi_{\\theta_i}: \\mathcal{O}_i \\times \\mathcal{A}_i \\mapsto [0, 1]$, a probability distribution over actions given its own observation, or a deterministic policy: $\\mu_{\\theta_i}: \\mathcal{O}_i \\mapsto \\mathcal{A}_i$.\nLet $\\vec{o} = {o_1, \\dots, o_N}$, $\\vec{\\mu} = {\\mu_1, \\dots, \\mu_N}$ and the policies are parameterized by $\\vec{\\theta} = {\\theta_1, \\dots, \\theta_N}$.\nThe critic in MADDPG learns a centralized action-value function $Q^\\vec{\\mu}_i(\\vec{o}, a_1, \\dots, a_N)$ for the i-th agent, where $a_1 \\in \\mathcal{A}_1, \\dots, a_N \\in \\mathcal{A}_N$ are actions of all agents. Each $Q^\\vec{\\mu}_i$ is learned separately for $i=1, \\dots, N$ and therefore multiple agents can have arbitrary reward structures, including conflicting rewards in a competitive setting. Meanwhile, multiple actors, one for each agent, are exploring and upgrading the policy parameters $\\theta_i$ on their own.\nActor update\n:\n$$\n\\nabla_{\\theta_i} J(\\theta_i) = \\mathbb{E}_{\\vec{o}, a \\sim \\mathcal{D}} [\\nabla_{a_i} Q^{\\vec{\\mu}}_i (\\vec{o}, a_1, \\dots, a_N) \\nabla_{\\theta_i} \\mu_{\\theta_i}(o_i) \\rvert_{a_i=\\mu_{\\theta_i}(o_i)} ]\n$$\nWhere $\\mathcal{D}$ is the memory buffer for experience replay, containing multiple episode samples $(\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}’)$ — given current observation $\\vec{o}$, agents take action $a_1, \\dots, a_N$ and get rewards $r_1, \\dots, r_N$, leading to the new observation $\\vec{o}’$.\nCritic update\n:\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta_i) &= \\mathbb{E}_{\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}'}[ (Q^{\\vec{\\mu}}_i(\\vec{o}, a_1, \\dots, a_N) - y)^2 ] & \\\\\n\\text{where } y &= r_i + \\gamma Q^{\\vec{\\mu}'}_i (\\vec{o}', a'_1, \\dots, a'_N) \\rvert_{a'_j = \\mu'_{\\theta_j}} & \\scriptstyle{\\text{; TD target!}}\n\\end{aligned}\n$$\nwhere $\\vec{\\mu}’$ are the target policies with delayed softly-updated parameters.\nIf the policies $\\vec{\\mu}$ are unknown during the critic update, we can ask each agent to learn and evolve its own approximation of others’ policies. Using the approximated policies, MADDPG still can learn efficiently although the inferred policies might not be accurate.\nTo mitigate the high variance triggered by the interaction between competing or collaborating agents in the environment, MADDPG proposed one more element -\npolicy ensembles\n:\nTrain K policies for one agent;\nPick a random policy for episode rollouts;\nTake an ensemble of these K policies to do gradient update.\nIn summary, MADDPG added three additional ingredients on top of DDPG to make it adapt to the multi-agent environment:\nCentralized critic + decentralized actors;\nActors are able to use estimated policies of other agents for learning;\nPolicy ensembling is good for reducing variance.\nThe architecture design of MADDPG. (Image source:\nLowe et al., 2017\n)\nTRPO\n#\n[\npaper\n|\ncode\n]\nTo improve training stability, we should avoid parameter updates that change the policy too much at one step.\nTrust region policy optimization (TRPO)\n(\nSchulman, et al., 2015\n) carries out this idea by enforcing a\nKL divergence\nconstraint on the size of policy update at each iteration.\nConsider the case when we are doing off-policy RL, the policy $\\beta$ used for collecting trajectories on rollout workers is different from the policy $\\pi$ to optimize for. The objective function in an off-policy model measures the total advantage over the state visitation distribution and actions, while the mismatch between the training data distribution and the true policy state distribution is compensated by importance sampling estimator:\n$$\n\\begin{aligned}\nJ(\\theta)\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\pi_\\theta(a \\vert s) \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\\\\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\scriptstyle{\\text{; Importance sampling}} \\\\\n&= \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\beta} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big] &\n\\end{aligned}\n$$\nwhere $\\theta_\\text{old}$ is the policy parameters before the update and thus known to us; $\\rho^{\\pi_{\\theta_\\text{old}}}$ is defined in the same way as\nabove\n; $\\beta(a \\vert s)$ is the behavior policy for collecting trajectories. Noted that we use an estimated advantage $\\hat{A}(.)$ rather than the true advantage function $A(.)$ because the true rewards are usually unknown.\nWhen training on policy, theoretically the policy for collecting data is same as the policy that we want to optimize. However, when rollout workers and optimizers are running in parallel asynchronously, the behavior policy can get stale. TRPO considers this subtle difference: It labels the behavior policy as $\\pi_{\\theta_\\text{old}}(a \\vert s)$ and thus the objective function becomes:\n$$\nJ(\\theta) = \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\pi_{\\theta_\\text{old}}} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big]\n$$\nTRPO aims to maximize the objective function $J(\\theta)$ subject to,\ntrust region constraint\nwhich enforces the distance between old and new policies measured by\nKL-divergence\nto be small enough, within a parameter δ:\n$$\n\\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}} [D_\\text{KL}(\\pi_{\\theta_\\text{old}}(.\\vert s) \\| \\pi_\\theta(.\\vert s)] \\leq \\delta\n$$\nIn this way, the old and new policies would not diverge too much when this hard constraint is met. While still, TRPO can guarantee a monotonic improvement over policy iteration (Neat, right?). Please read the proof in the\npaper\nif interested :)\nPPO\n#\n[\npaper\n|\ncode\n]\nGiven that TRPO is relatively complicated and we still want to implement a similar constraint,\nproximal policy optimization (PPO)\nsimplifies it by using a clipped surrogate objective while retaining similar performance.\nFirst, let’s denote the probability ratio between old and new policies as:\n$$\nr(\\theta) = \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)}\n$$\nThen, the objective function of TRPO (on policy) becomes:\n$$\nJ^\\text{TRPO} (\\theta) = \\mathbb{E} [ r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a) ]\n$$\nWithout a limitation on the distance between $\\theta_\\text{old}$ and $\\theta$, to maximize $J^\\text{TRPO} (\\theta)$ would lead to instability with extremely large parameter updates and big policy ratios. PPO imposes the constraint by forcing $r(\\theta)$ to stay within a small interval around 1, precisely $[1-\\epsilon, 1+\\epsilon]$, where $\\epsilon$ is a hyperparameter.\n$$\nJ^\\text{CLIP} (\\theta) = \\mathbb{E} [ \\min( r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a), \\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon) \\hat{A}_{\\theta_\\text{old}}(s, a))]\n$$\nThe function $\\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon)$ clips the ratio to be no more than $1+\\epsilon$ and no less than $1-\\epsilon$. The objective function of PPO takes the minimum one between the original value and the clipped version and therefore we lose the motivation for increasing the policy update to extremes for better rewards.\nWhen applying PPO on the network architecture with shared parameters for both policy (actor) and value (critic) functions, in addition to the clipped reward, the objective function is augmented with an error term on the value estimation (formula in red) and an entropy term (formula in blue) to encourage sufficient exploration.\n$$\nJ^\\text{CLIP'} (\\theta) = \\mathbb{E} [ J^\\text{CLIP} (\\theta) - \\color{red}{c_1 (V_\\theta(s) - V_\\text{target})^2} + \\color{blue}{c_2 H(s, \\pi_\\theta(.))} ]\n$$\nwhere Both $c_1$ and $c_2$ are two hyperparameter constants.\nPPO has been tested on a set of benchmark tasks and proved to produce awesome results with much greater simplicity.\nIn a later paper by\nHsu et al., 2020\n, two common design choices in PPO are revisited, precisely (1) clipped probability ratio for policy regularization and (2) parameterize policy action space by continuous Gaussian or discrete softmax distribution. They first identified three failure modes in PPO and proposed replacements for these two designs.\nThe failure modes are:\nOn continuous action spaces, standard PPO is unstable when rewards vanish outside bounded support.\nOn discrete action spaces with sparse high rewards, standard PPO often gets stuck at suboptimal actions.\nThe policy is sensitive to initialization when there are locally optimal actions close to initialization.\nDiscretizing the action space or use Beta distribution helps avoid failure mode 1&3 associated with Gaussian policy. Using KL regularization (same motivation as in\nTRPO\n) as an alternative surrogate model helps resolve failure mode 1&2.\nPPG\n#\n[\npaper\n|\ncode\n]\nSharing parameters between policy and value networks have pros and cons. It allows policy and value functions to share the learned features with each other, but it may cause conflicts between competing objectives and demands the same data for training two networks at the same time.\nPhasic policy gradient\n(\nPPG\n;\nCobbe, et al 2020\n) modifies the traditional on-policy\nactor-critic\npolicy gradient algorithm. precisely\nPPO\n, to have separate training phases for policy and value functions. In two alternating phases:\nThe\npolicy phase\n: updates the policy network by optimizing the PPO\nobjective\n$L^\\text{CLIP} (\\theta)$;\nThe\nauxiliary phase\n: optimizes an auxiliary objective alongside a behavioral cloning loss. In the paper, value function error is the sole auxiliary objective, but it can be quite general and includes any other additional auxiliary losses.\n$$\n\\begin{aligned}\nL^\\text{joint} &= L^\\text{aux} + \\beta_\\text{clone} \\cdot \\mathbb{E}_t[\\text{KL}[\\pi_{\\theta_\\text{old}}(\\cdot\\mid s_t), \\pi_\\theta(\\cdot\\mid s_t)]] \\\\\nL^\\text{aux} &= L^\\text{value} = \\mathbb{E}_t \\big[\\frac{1}{2}\\big( V_w(s_t) - \\hat{V}_t^\\text{targ} \\big)^2\\big]\n\\end{aligned}\n$$\nwhere $\\beta_\\text{clone}$ is a hyperparameter for controlling how much we would like to keep the policy not diverge too much from its original behavior while optimizing the auxiliary objectives.\nThe algorithm of PPG. (Image source:\nCobbe, et al 2020\n)\nwhere\n$N_\\pi$ is the number of policy update iterations in the policy phase. Note that the policy phase performs multiple iterations of updates per single auxiliary phase.\n$E_\\pi$ and $E_V$ control the sample reuse (i.e. the number of training epochs performed across data in the reply buffer) for the policy and value functions, respectively. Note that this happens within the policy phase and thus $E_V$ affects the learning of true value function not the auxiliary value function.\n$E_\\text{aux}$ defines the sample reuse in the auxiliary phrase. In PPG, value function optimization can tolerate a much higher level sample reuse; for example, in the experiments of the paper, $E_\\text{aux} = 6$ while $E_\\pi = E_V = 1$.\nPPG leads to a significant improvement on sample efficiency compared to PPO.\nThe mean normalized performance of PPG vs PPO on the\nProcgen\nbenchmark. (Image source:\nCobbe, et al 2020\n)\nACER\n#\n[\npaper\n|\ncode\n]\nACER\n, short for\nactor-critic with experience replay\n(\nWang, et al., 2017\n), is an off-policy actor-critic model with experience replay, greatly increasing the sample efficiency and decreasing the data correlation. A3C builds up the foundation for ACER, but it is on policy; ACER is A3C’s off-policy counterpart. The major obstacle to making A3C off policy is how to control the stability of the off-policy estimator. ACER proposes three designs to overcome it:\nUse Retrace Q-value estimation;\nTruncate the importance weights with bias correction;\nApply efficient TRPO.\nRetrace Q-value Estimation\nRetrace\nis an off-policy return-based Q-value estimation algorithm with a nice guarantee for convergence for any target and behavior policy pair $(\\pi, \\beta)$, plus good data efficiency.\nRecall how TD learning works for prediction:\nCompute TD error: $\\delta_t = R_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(S_{t+1}, a) - Q(S_t, A_t)$; the term $r_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(s_{t+1}, a) $ is known as “TD target”. The expectation $\\mathbb{E}_{a \\sim \\pi}$ is used because for the future step the best estimation we can make is what the return would be if we follow the current policy $\\pi$.\nUpdate the value by correcting the error to move toward the goal: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha \\delta_t$. In other words, the incremental update on Q is proportional to the TD error: $\\Delta Q(S_t, A_t) = \\alpha \\delta_t$.\nWhen the rollout is off policy, we need to apply importance sampling on the Q update:\n$$\n\\Delta Q^\\text{imp}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)} \\delta_t\n$$\nThe product of importance weights looks pretty scary when we start imagining how it can cause super high variance and even explode. Retrace Q-value estimation method modifies $\\Delta Q$ to have importance weights truncated by no more than a constant $c$:\n$$\n\\Delta Q^\\text{ret}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\min(c, \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)})  \\delta_t\n$$\nACER uses $Q^\\text{ret}$ as the target to train the critic by minimizing the L2 error term: $(Q^\\text{ret}(s, a) - Q(s, a))^2$.\nImportance weights truncation\nTo reduce the high variance of the policy gradient $\\hat{g}$, ACER truncates the importance weights by a constant c, plus a correction term. The label $\\hat{g}_t^\\text{acer}$ is the ACER policy gradient at time t.\n$$\n\\begin{aligned}\n\\hat{g}_t^\\text{acer}\n= & \\omega_t \\big( Q^\\text{ret}(S_t, A_t) - V_{\\theta_v}(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t) \n  & \\scriptstyle{\\text{; Let }\\omega_t=\\frac{\\pi(A_t \\vert S_t)}{\\beta(A_t \\vert S_t)}} \\\\\n= & \\color{blue}{\\min(c, \\omega_t) \\big( Q^\\text{ret}(S_t, A_t) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)} \\\\\n  & + \\color{red}{\\mathbb{E}_{a \\sim \\pi} \\big[ \\max(0, \\frac{\\omega_t(a) - c}{\\omega_t(a)}) \\big( Q_w(S_t, a) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert S_t) \\big]}\n  & \\scriptstyle{\\text{; Let }\\omega_t (a) =\\frac{\\pi(a \\vert S_t)}{\\beta(a \\vert S_t)}}\n\\end{aligned}\n$$\nwhere $Q_w(.)$ and $V_w(.)$ are value functions predicted by the critic with parameter w. The first term (blue) contains the clipped important weight. The clipping helps reduce the variance, in addition to subtracting state value function $V_w(.)$ as a baseline. The second term (red) makes a correction to achieve unbiased estimation.\nEfficient TRPO\nFurthermore, ACER adopts the idea of TRPO but with a small adjustment to make it more computationally efficient: rather than measuring the KL divergence between policies before and after one update, ACER maintains a running average of past policies and forces the updated policy to not deviate far from this average.\nThe ACER\npaper\nis pretty dense with many equations. Hopefully, with the prior knowledge on TD learning, Q-learning, importance sampling and TRPO, you will find the\npaper\nslightly easier to follow :)\nACTKR\n#\n[\npaper\n|\ncode\n]\nACKTR (actor-critic using Kronecker-factored trust region)\n(\nYuhuai Wu, et al., 2017\n) proposed to use Kronecker-factored approximation curvature (\nK-FAC\n) to do the gradient update for both the critic and actor. K-FAC made an improvement on the computation of\nnatural gradient\n, which is quite different from our\nstandard gradient\n.\nHere\nis a nice, intuitive explanation of natural gradient. One sentence summary is probably:\n“we first consider all combinations of parameters that result in a new network a constant KL divergence away from the old network. This constant value can be viewed as the step size or learning rate. Out of all these possible combinations, we choose the one that minimizes our loss function.”\nI listed ACTKR here mainly for the completeness of this post, but I would not dive into details, as it involves a lot of theoretical knowledge on natural gradient and optimization methods. If interested, check these papers/posts, before reading the ACKTR paper:\nAmari.\nNatural Gradient Works Efficiently in Learning\n. 1998\nKakade.\nA Natural Policy Gradient\n. 2002\nA intuitive explanation of natural gradient descent\nWiki: Kronecker product\nMartens & Grosse.\nOptimizing neural networks with kronecker-factored approximate curvature.\n2015.\nHere is a high level summary from the K-FAC\npaper\n:\n“This approximation is built in two stages. In the first, the rows and columns of the Fisher are divided into groups, each of which corresponds to all the weights in a given layer, and this gives rise to a block-partitioning of the matrix. These blocks are then approximated as Kronecker products between much smaller matrices, which we show is equivalent to making certain approximating assumptions regarding the statistics of the network’s gradients.\nIn the second stage, this matrix is further approximated as having an inverse which is either block-diagonal or block-tridiagonal. We justify this approximation through a careful examination of the relationships between inverse covariances, tree-structured graphical models, and linear regression. Notably, this justification doesn’t apply to the Fisher itself, and our experiments confirm that while the inverse Fisher does indeed possess this structure (approximately), the Fisher itself does not.”\nSAC\n#\n[\npaper\n|\ncode\n]\nSoft Actor-Critic (SAC)\n(\nHaarnoja et al. 2018\n) incorporates the entropy measure of the policy into the reward to encourage exploration: we expect to learn a policy that acts as randomly as possible while it is still able to succeed at the task. It is an off-policy actor-critic model following the maximum entropy reinforcement learning framework. A precedent work is\nSoft Q-learning\n.\nThree key components in SAC:\nAn\nactor-critic\narchitecture with separate policy and value function networks;\nAn\noff-policy\nformulation that enables reuse of previously collected data for efficiency;\nEntropy maximization to enable stability and exploration.\nThe policy is trained with the objective to maximize the expected return and the entropy at the same time:\n$$\nJ(\\theta) = \\sum_{t=1}^T \\mathbb{E}_{(s_t, a_t) \\sim \\rho_{\\pi_\\theta}} [r(s_t, a_t) + \\alpha \\mathcal{H}(\\pi_\\theta(.\\vert s_t))]\n$$\nwhere $\\mathcal{H}(.)$ is the entropy measure and $\\alpha$ controls how important the entropy term is, known as\ntemperature\nparameter. The entropy maximization leads to policies that can (1) explore more and (2) capture multiple modes of near-optimal strategies (i.e., if there exist multiple options that seem to be equally good, the policy should assign each with an equal probability to be chosen).\nPrecisely, SAC aims to learn three functions:\nThe policy with parameter $\\theta$, $\\pi_\\theta$.\nSoft Q-value function parameterized by $w$, $Q_w$.\nSoft state value function parameterized by $\\psi$, $V_\\psi$; theoretically we can infer $V$ by knowing $Q$ and $\\pi$, but in practice, it helps stabilize the training.\nSoft Q-value and soft state value are defined as:\n$$\n\\begin{aligned}\nQ(s_t, a_t) &= r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_{\\pi}(s)} [V(s_{t+1})] & \\text{; according to Bellman equation.}\\\\\n\\text{where }V(s_t) &= \\mathbb{E}_{a_t \\sim \\pi} [Q(s_t, a_t) - \\alpha \\log \\pi(a_t \\vert s_t)] & \\text{; soft state value function.}\n\\end{aligned}\n$$\n$$\n\\text{Thus, } Q(s_t, a_t) = r(s_t, a_t) + \\gamma \\mathbb{E}_{(s_{t+1}, a_{t+1}) \\sim \\rho_{\\pi}} [Q(s_{t+1}, a_{t+1}) - \\alpha \\log \\pi(a_{t+1} \\vert s_{t+1})]\n$$\n$\\rho_\\pi(s)$ and $\\rho_\\pi(s, a)$ denote the state and the state-action marginals of the state distribution induced by the policy $\\pi(a \\vert s)$; see the similar definitions in\nDPG\nsection.\nThe soft state value function is trained to minimize the mean squared error:\n$$\n\\begin{aligned}\nJ_V(\\psi) &= \\mathbb{E}_{s_t \\sim \\mathcal{D}} [\\frac{1}{2} \\big(V_\\psi(s_t) - \\mathbb{E}[Q_w(s_t, a_t) - \\log \\pi_\\theta(a_t \\vert s_t)] \\big)^2] \\\\\n\\text{with gradient: }\\nabla_\\psi J_V(\\psi) &= \\nabla_\\psi V_\\psi(s_t)\\big( V_\\psi(s_t) - Q_w(s_t, a_t) + \\log \\pi_\\theta (a_t \\vert s_t) \\big)\n\\end{aligned}\n$$\nwhere $\\mathcal{D}$ is the replay buffer.\nThe soft Q function is trained to minimize the soft Bellman residual:\n$$\n\\begin{aligned}\nJ_Q(w) &= \\mathbb{E}_{(s_t, a_t) \\sim \\mathcal{D}} [\\frac{1}{2}\\big( Q_w(s_t, a_t) - (r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_\\pi(s)}[V_{\\bar{\\psi}}(s_{t+1})]) \\big)^2] \\\\\n\\text{with gradient: } \\nabla_w J_Q(w) &= \\nabla_w Q_w(s_t, a_t) \\big( Q_w(s_t, a_t) - r(s_t, a_t) - \\gamma V_{\\bar{\\psi}}(s_{t+1})\\big) \n\\end{aligned}\n$$\nwhere $\\bar{\\psi}$ is the target value function which is the exponential moving average (or only gets updated periodically in a “hard” way), just like how the parameter of the target Q network is treated in\nDQN\nto stabilize the training.\nSAC updates the policy to minimize the\nKL-divergence\n:\n$$\n\\begin{aligned}\n\\pi_\\text{new} \n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\Big( \\pi'(.\\vert s_t) \\| \\frac{\\exp(Q^{\\pi_\\text{old}}(s_t, .))}{Z^{\\pi_\\text{old}}(s_t)} \\Big) \\\\[6pt]\n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\big( \\pi'(.\\vert s_t) \\| \\exp(Q^{\\pi_\\text{old}}(s_t, .) - \\log Z^{\\pi_\\text{old}}(s_t)) \\big) \\\\[6pt]\n\\text{objective for update: } J_\\pi(\\theta) &= \\nabla_\\theta D_\\text{KL} \\big( \\pi_\\theta(. \\vert s_t) \\| \\exp(Q_w(s_t, .) - \\log Z_w(s_t)) \\big) \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} \\Big[ - \\log \\big( \\frac{\\exp(Q_w(s_t, a_t) - \\log Z_w(s_t))}{\\pi_\\theta(a_t \\vert s_t)} \\big) \\Big] \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} [ \\log \\pi_\\theta(a_t \\vert s_t) - Q_w(s_t, a_t) + \\log Z_w(s_t) ]\n\\end{aligned}\n$$\nwhere $\\Pi$ is the set of potential policies that we can model our policy as to keep them tractable; for example, $\\Pi$ can be the family of Gaussian mixture distributions, expensive to model but highly expressive and still tractable. $Z^{\\pi_\\text{old}}(s_t)$ is the partition function to normalize the distribution. It is usually intractable but does not contribute to the gradient. How to minimize $J_\\pi(\\theta)$ depends our choice of $\\Pi$.\nThis update guarantees that $Q^{\\pi_\\text{new}}(s_t, a_t) \\geq Q^{\\pi_\\text{old}}(s_t, a_t)$, please check the proof on this lemma in the Appendix B.2 in the original\npaper\n.\nOnce we have defined the objective functions and gradients for soft action-state value, soft state value and the policy network, the soft actor-critic algorithm is straightforward:\nThe soft actor-critic algorithm. (Image source:\noriginal paper\n)\nSAC with Automatically Adjusted Temperature\n#\n[\npaper\n|\ncode\n]\nSAC is brittle with respect to the temperature parameter. Unfortunately it is difficult to adjust temperature, because the entropy can vary unpredictably both across tasks and during training as the policy becomes better. An improvement on SAC formulates a constrained optimization problem: while maximizing the expected return, the policy should satisfy a minimum entropy constraint:\n$$\n\\max_{\\pi_0, \\dots, \\pi_T} \\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big] \\text{s.t. } \\forall t\\text{, } \\mathcal{H}(\\pi_t) \\geq \\mathcal{H}_0\n$$\nwhere $\\mathcal{H}_0$ is a predefined minimum policy entropy threshold.\nThe expected return $\\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big]$ can be decomposed into a sum of rewards at all the time steps. Because the policy $\\pi_t$ at time t has no effect on the policy at the earlier time step, $\\pi_{t-1}$, we can maximize the return at different steps backward in time — this is essentially\nDP\n.\n$$\n\\underbrace{\\max_{\\pi_0} \\Big( \\mathbb{E}[r(s_0, a_0)]+ \\underbrace{\\max_{\\pi_1} \\Big(\\mathbb{E}[...] + \\underbrace{\\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T)]}_\\text{1st maximization} \\Big)}_\\text{second but last maximization} \\Big)}_\\text{last maximization}\n$$\nwhere we consider $\\gamma=1$.\nSo we start the optimization from the last timestep $T$:\n$$\n\\text{maximize } \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] \\text{ s.t. } \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 \\geq 0\n$$\nFirst, let us define the following functions:\n$$\n\\begin{aligned}\nh(\\pi_T) &= \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 = \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0\\\\\nf(\\pi_T) &= \\begin{cases}\n\\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ], & \\text{if }h(\\pi_T) \\geq 0 \\\\\n-\\infty, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nAnd the optimization becomes:\n$$\n\\text{maximize } f(\\pi_T) \\text{ s.t. } h(\\pi_T) \\geq 0\n$$\nTo solve the maximization optimization with inequality constraint, we can construct a\nLagrangian expression\nwith a Lagrange multiplier (also known as “dual variable”), $\\alpha_T$:\n$$\nL(\\pi_T, \\alpha_T) = f(\\pi_T) + \\alpha_T h(\\pi_T)\n$$\nConsidering the case when we try to\nminimize $L(\\pi_T, \\alpha_T)$ with respect to $\\alpha_T$\n- given a particular value $\\pi_T$,\nIf the constraint is satisfied, $h(\\pi_T) \\geq 0$, at best we can set $\\alpha_T=0$ since we have no control over the value of $f(\\pi_T)$. Thus, $L(\\pi_T, 0) = f(\\pi_T)$.\nIf the constraint is invalidated, $h(\\pi_T) < 0$, we can achieve $L(\\pi_T, \\alpha_T) \\to -\\infty$ by taking  $\\alpha_T \\to \\infty$. Thus, $L(\\pi_T, \\infty) = -\\infty = f(\\pi_T)$.\nIn either case, we can recover the following equation,\n$$\nf(\\pi_T) = \\min_{\\alpha_T \\geq 0} L(\\pi_T, \\alpha_T)\n$$\nAt the same time, we want to maximize $f(\\pi_T)$,\n$$\n\\max_{\\pi_T} f(\\pi_T) = \\min_{\\alpha_T \\geq 0} \\max_{\\pi_T} L(\\pi_T, \\alpha_T)\n$$\nTherefore, to maximize $f(\\pi_T)$, the dual problem is listed as below. Note that to make sure $\\max_{\\pi_T} f(\\pi_T)$ is properly maximized and would not become $-\\infty$, the constraint has to be satisfied.\n$$\n\\begin{aligned}\n\\max_{\\pi_T} \\mathbb{E}[ r(s_T, a_T) ]\n&= \\max_{\\pi_T} f(\\pi_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} L(\\pi_T, \\alpha_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} f(\\pi_T) + \\alpha_T h(\\pi_T) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] + \\alpha_T ( \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  - \\alpha_T \\log \\pi_T(a_T\\vert s_T)] - \\alpha_T \\mathcal{H}_0 \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ]\n\\end{aligned}\n$$\nWe could compute the optimal $\\pi_T$ and $\\alpha_T$ iteratively. First given the current $\\alpha_T$, get the best policy $\\pi_T^{*}$ that maximizes $L(\\pi_T^{*}, \\alpha_T)$. Then plug in $\\pi_T^{*}$ and compute $\\alpha_T^{*}$ that minimizes $L(\\pi_T^{*}, \\alpha_T)$. Assuming we have one neural network for policy and one network for temperature parameter, the iterative update process is more aligned with how we update network parameters during training.\n$$\n\\begin{aligned}\n\\pi^{*}_T\n&= \\arg\\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ] \\\\\n\\color{blue}{\\alpha^{*}_T}\n&\\color{blue}{=} \\color{blue}{\\arg\\min_{\\alpha_T \\geq 0} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [\\alpha_T \\mathcal{H}(\\pi^{*}_T) - \\alpha_T \\mathcal{H}_0 ]}\n\\end{aligned}\n$$\n$$\n\\text{Thus, }\\max_{\\pi_T} \\mathbb{E} [ r(s_T, a_T) ] \n= \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [ r(s_T, a_T)  + \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) - \\alpha^{*}_T \\mathcal{H}_0 ]\n$$\nNow let’s go back to the soft Q value function:\n$$\n\\begin{aligned}\nQ_{T-1}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [Q(s_T, a_T) - \\alpha_T \\log \\pi(a_T \\vert s_T)] \\\\\n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [r(s_T, a_T)] + \\alpha_T \\mathcal{H}(\\pi_T) \\\\\nQ_{T-1}^{*}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\max_{\\pi_T} \\mathbb{E} [r(s_T, a_T)] +  \\alpha_T \\mathcal{H}(\\pi^{*}_T) & \\text{; plug in the optimal }\\pi_T^{*}\n\\end{aligned}\n$$\nTherefore the expected return is as follows, when we take one step further back to the time step $T-1$:\n$$\n\\begin{aligned}\n&\\max_{\\pi_{T-1}}\\Big(\\mathbb{E}[r(s_{T-1}, a_{T-1})] + \\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T] \\Big) \\\\\n&= \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) \\Big) & \\text{; should s.t. } \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\geq 0 \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) + \\alpha_{T-1} \\big( \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\big) \\Big) & \\text{; dual problem w/ Lagrangian.} \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 \\Big) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T)\n\\end{aligned}\n$$\nSimilar to the previous step,\n$$\n\\begin{aligned}\n\\pi^{*}_{T-1} &= \\arg\\max_{\\pi_{T-1}} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_\\pi} [Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1} \\mathcal{H}_0 ] \\\\\n\\color{green}{\\alpha^{*}_{T-1}} &\\color{green}{=} \\color{green}{\\arg\\min_{\\alpha_{T-1} \\geq 0} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_{\\pi^{*}}} [ \\alpha_{T-1} \\mathcal{H}(\\pi^{*}_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 ]}\n\\end{aligned}\n$$\nThe equation for updating $\\alpha_{T-1}$ in\ngreen\nhas the same format as the equation for updating $\\alpha_{T-1}$ in\nblue\nabove. By repeating this process, we can learn the optimal temperature parameter in every step by minimizing the same objective function:\n$$\nJ(\\alpha) = \\mathbb{E}_{a_t \\sim \\pi_t} [-\\alpha \\log \\pi_t(a_t \\mid s_t) - \\alpha \\mathcal{H}_0]\n$$\nThe final algorithm is same as SAC except for learning $\\alpha$ explicitly with respect to the objective $J(\\alpha)$ (see Fig. 7):\nThe soft actor-critic algorithm with automatically adjusted temperature. (Image source:\noriginal paper\n)\nTD3\n#\n[\npaper\n|\ncode\n]\nThe Q-learning algorithm is commonly known to suffer from the overestimation of the value function. This overestimation can propagate through the training iterations and negatively affect the policy. This property directly motivated\nDouble Q-learning\nand\nDouble DQN\n: the action selection and Q-value update are decoupled by using two value networks.\nTwin Delayed Deep Deterministic\n(short for\nTD3\n;\nFujimoto et al., 2018\n) applied a couple of tricks on\nDDPG\nto prevent the overestimation of the value function:\n(1)\nClipped Double Q-learning\n: In Double Q-Learning, the action selection and Q-value estimation are made by two networks separately. In the DDPG setting, given two deterministic actors $(\\mu_{\\theta_1}, \\mu_{\\theta_2})$ with two corresponding critics $(Q_{w_1}, Q_{w_2})$, the Double Q-learning Bellman targets look like:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma Q_{w_2}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma Q_{w_1}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\nHowever, due to the slow changing policy, these two networks could be too similar to make independent decisions. The\nClipped Double Q-learning\ninstead uses the minimum estimation among two so as to favor underestimation bias which is hard to propagate through training:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma \\min_{i=1,2}Q_{w_i}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma \\min_{i=1,2} Q_{w_i}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\n(2)\nDelayed update of Target and Policy Networks\n:  In the\nactor-critic\nmodel, policy and value updates are deeply coupled: Value estimates diverge through overestimation when the policy is poor, and the policy will become poor if the value estimate itself is inaccurate.\nTo reduce the variance, TD3 updates the policy at a lower frequency than the Q-function. The policy network stays the same until the value error is small enough after several updates. The idea is similar to how the periodically-updated target network stay as a stable objective in\nDQN\n.\n(3)\nTarget Policy Smoothing\n: Given a concern with deterministic policies that they can overfit to narrow peaks in the value function, TD3 introduced a smoothing regularization strategy on the value function: adding a small amount of clipped random noises to the selected action and averaging over mini-batches.\n$$\n\\begin{aligned}\ny &= r + \\gamma Q_w (s', \\mu_{\\theta}(s') + \\epsilon) & \\\\\n\\epsilon &\\sim \\text{clip}(\\mathcal{N}(0, \\sigma), -c, +c) & \\scriptstyle{\\text{ ; clipped random noises.}}\n\\end{aligned}\n$$\nThis approach mimics the idea of\nSARSA\nupdate and enforces that similar actions should have similar values.\nHere is the final algorithm:\nTD3 Algorithm. (Image source:\nFujimoto et al., 2018\n)\nSVPG\n#\n[\npaper\n|\ncode\nfor SVPG]\nStein Variational Policy Gradient (\nSVPG\n;\nLiu et al, 2017\n) applies the\nStein\nvariational gradient descent (\nSVGD\n;\nLiu and Wang, 2016\n) algorithm to update the policy parameter $\\theta$.\nIn the setup of maximum entropy policy optimization, $\\theta$ is considered as a random variable $\\theta \\sim q(\\theta)$ and the model is expected to learn this distribution $q(\\theta)$. Assuming we know a prior on how $q$ might look like, $q_0$, and we would like to guide the learning process to not make $\\theta$ too far away from $q_0$ by optimizing the following objective function:\n$$\n\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0)\n$$\nwhere $\\mathbb{E}_{\\theta \\sim q} [R(\\theta)]$ is the expected reward when $\\theta \\sim q(\\theta)$ and $D_\\text{KL}$ is the KL divergence.\nIf we don’t have any prior information, we might set $q_0$ as a uniform distribution and set $q_0(\\theta)$ to a constant. Then the above objective function becomes\nSAC\n, where the entropy term encourages exploration:\n$$\n\\begin{aligned}\n\\hat{J}(\\theta) \n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha \\mathbb{E}_{\\theta \\sim q} [\\log q(\\theta) - \\log q_0(\\theta)] \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] + \\alpha H(q(\\theta))\n\\end{aligned}\n$$\nLet’s take the derivative of $\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q|q_0)$ w.r.t. $q$:\n$$\n\\begin{aligned}\n\\nabla_q \\hat{J}(\\theta) \n&= \\nabla_q \\big( \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\big) \\\\\n&= \\nabla_q \\int_\\theta \\big( q(\\theta) J(\\theta) - \\alpha q(\\theta)\\log q(\\theta) + \\alpha q(\\theta) \\log q_0(\\theta) \\big) \\\\\n&= \\int_\\theta \\big( J(\\theta) - \\alpha \\log q(\\theta) -\\alpha + \\alpha \\log q_0(\\theta) \\big) \\\\\n&= 0\n\\end{aligned}\n$$\nThe optimal distribution is:\n$$\n\\log q^{*}(\\theta) = \\frac{1}{\\alpha} J(\\theta) + \\log q_0(\\theta) - 1 \\text{ thus } \\underbrace{ q^{*}(\\theta) }_\\textrm{\"posterior\"} \\propto \\underbrace{\\exp ( J(\\theta) / \\alpha )}_\\textrm{\"likelihood\"} \\underbrace{q_0(\\theta)}_\\textrm{prior}\n$$\nThe temperature $\\alpha$ decides a tradeoff between exploitation and exploration. When $\\alpha \\rightarrow 0$, $\\theta$ is updated only according to the expected return $J(\\theta)$. When $\\alpha \\rightarrow \\infty$, $\\theta$ always follows the prior belief.\nWhen using the SVGD method to estimate the target posterior distribution $q(\\theta)$, it relies on a set of particle $\\{\\theta_i\\}_{i=1}^n$ (independently trained policy agents) and each is updated:\n$$\n\\theta_i \\gets \\theta_i + \\epsilon \\phi^{*}(\\theta_i) \\text{ where } \\phi^{*} = \\max_{\\phi \\in \\mathcal{H}} \\{ - \\nabla_\\epsilon D_\\text{KL} (q'_{[\\theta + \\epsilon \\phi(\\theta)]} \\| q) \\text{ s.t. } \\|\\phi\\|_{\\mathcal{H}} \\leq 1\\} \n$$\nwhere $\\epsilon$ is a learning rate and $\\phi^{*}$ is the unit ball of a\nRKHS\n(reproducing kernel Hilbert space) $\\mathcal{H}$ of $\\theta$-shaped value vectors that maximally decreases the KL divergence between the particles and the target distribution. $q’(.)$ is the distribution of $\\theta + \\epsilon \\phi(\\theta)$.\nComparing different gradient-based update methods:\nMethod\nUpdate space\nPlain gradient\n$\\Delta \\theta$ on the parameter space\nNatural gradient\n$\\Delta \\theta$ on the search distribution space\nSVGD\n$\\Delta \\theta$ on the kernel function space (edited)\nOne\nestimation\nof $\\phi^{*}$ has the following form. A positive definite kernel $k(\\vartheta, \\theta)$, i.e. a Gaussian\nradial basis function\n, measures the similarity between particles.\n$$\n\\begin{aligned}\n\\phi^{*}(\\theta_i) \n&= \\mathbb{E}_{\\vartheta \\sim q'} [\\nabla_\\vartheta \\log q(\\vartheta) k(\\vartheta, \\theta_i) + \\nabla_\\vartheta k(\\vartheta, \\theta_i)]\\\\\n&= \\frac{1}{n} \\sum_{j=1}^n [\\color{red}{\\nabla_{\\theta_j} \\log q(\\theta_j) k(\\theta_j, \\theta_i)} + \\color{green}{\\nabla_{\\theta_j} k(\\theta_j, \\theta_i)}] & \\scriptstyle{\\text{;approximate }q'\\text{ with current particle values}}\n\\end{aligned}\n$$\nThe first term in\nred\nencourages $\\theta_i$ learning towards the high probability regions of $q$ that is shared across similar particles. => to be similar to other particles\nThe second term in\ngreen\npushes particles away from each other and therefore diversifies the policy. => to be dissimilar to other particles\nUsually the temperature $\\alpha$ follows an annealing scheme so that the training process does more exploration at the beginning but more exploitation at a later stage.\nIMPALA\n#\n[\npaper\n|\ncode\n]\nIn order to scale up RL training to achieve a very high throughput,\nIMPALA\n(“Importance Weighted Actor-Learner Architecture”) framework decouples acting from learning on top of basic actor-critic setup and learns from all experience trajectories with\nV-trace\noff-policy correction.\nMultiple actors generate experience in parallel, while the learner optimizes both policy and value function parameters using all the generated experience. Actors update their parameters with the latest policy from the learner periodically. Because acting and learning are decoupled, we can add many more actor machines to generate a lot more trajectories per time unit. As the training policy and the behavior policy are not totally synchronized, there is a\ngap\nbetween them and thus we need off-policy corrections.\nLet the value function $V_\\theta$ parameterized by $\\theta$ and the policy $\\pi_\\phi$ parameterized by $\\phi$. Also we know the trajectories in the replay buffer are collected by a slightly older policy $\\mu$.\nAt the training time $t$, given $(s_t, a_t, s_{t+1}, r_t)$, the value function parameter $\\theta$ is learned through an L2 loss between the current value and a V-trace value target. The $n$-step V-trace target is defined as:\n$$\n\\begin{aligned}\nv_t  &= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\delta_i V} \\\\\n&= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\rho_i (r_i + \\gamma V_\\theta(s_{i+1}) - V_\\theta(s_i))}\n\\end{aligned}\n$$\nwhere the\nred\npart $\\delta_i V$ is a temporal difference for $V$. $\\rho_i = \\min\\big(\\bar{\\rho}, \\frac{\\pi(a_i \\vert s_i)}{\\mu(a_i \\vert s_i)}\\big)$ and $c_j = \\min\\big(\\bar{c}, \\frac{\\pi(a_j \\vert s_j)}{\\mu(a_j \\vert s_j)}\\big)$ are\ntruncated\nimportance sampling (IS)\nweights\n. The product of $c_t, \\dots, c_{i-1}$ measures how much a temporal difference $\\delta_i V$ observed at time $i$ impacts the update of the value function at a previous time $t$. In the on-policy case, we have $\\rho_i=1$ and $c_j=1$ (assuming $\\bar{c} \\geq 1$) and therefore the V-trace target becomes on-policy $n$-step Bellman target.\n$\\bar{\\rho}$ and $\\bar{c}$ are two truncation constants with $\\bar{\\rho} \\geq \\bar{c}$. $\\bar{\\rho}$ impacts the fixed-point of the value function we converge to and $\\bar{c}$ impacts the speed of convergence. When $\\bar{\\rho} =\\infty$ (untruncated), we converge to the value function of the target policy $V^\\pi$; when $\\bar{\\rho}$ is close to 0, we evaluate the value function of the behavior policy $V^\\mu$; when in-between, we evaluate a policy between $\\pi$ and $\\mu$.\nThe value function parameter is therefore updated in the direction of:\n$$\n\\Delta\\theta = (v_t - V_\\theta(s_t))\\nabla_\\theta V_\\theta(s_t)\n$$\nThe policy parameter $\\phi$ is updated through policy gradient,\n$$\n\\begin{aligned}\n\\Delta \\phi \n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) + \\nabla_\\phi H(\\pi_\\phi)\\\\\n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) - \\nabla_\\phi \\sum_a \\pi_\\phi(a\\vert s_t)\\log \\pi_\\phi(a\\vert s_t)\n\\end{aligned}\n$$\nwhere $r_t + \\gamma v_{t+1}$ is the estimated Q value, from which a state-dependent baseline $V_\\theta(s_t)$ is subtracted. $H(\\pi_\\phi)$ is an entropy bonus to encourage exploration.\nIn the experiments, IMPALA is used to train one agent over multiple tasks. Two different model architectures are involved, a shallow model (left) and a deep residual model (right).\nQuick Summary\n#\nAfter reading through all the algorithms above, I list a few building blocks or principles that seem to be common among them:\nTry to reduce the variance and keep the bias unchanged to stabilize learning.\nOff-policy gives us better exploration and helps us use data samples more efficiently.\nExperience replay (training data sampled from a replay memory buffer);\nTarget network that is either frozen periodically or updated slower than the actively learned policy network;\nBatch normalization;\nEntropy-regularized reward;\nThe critic and actor can share lower layer parameters of the network and two output heads for policy and value functions.\nIt is possible to learn with deterministic policy rather than stochastic one.\nPut constraint on the divergence between policy updates.\nNew optimization methods (such as K-FAC).\nEntropy maximization of the policy helps encourage exploration.\nTry not to overestimate the value function.\nThink twice whether the policy and value network should share parameters.\nTBA more.\nCited as:\n@article{weng2018PG,\n  title   = \"Policy Gradient Algorithms\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-04-08-policy-gradient/\"\n}\nReferences\n#\n[1] jeremykun.com\nMarkov Chain Monte Carlo Without all the Bullshit\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] John Schulman, et al.\n“High-dimensional continuous control using generalized advantage estimation.”\nICLR 2016.\n[4] Thomas Degris, Martha White, and Richard S. Sutton.\n“Off-policy actor-critic.”\nICML 2012.\n[5] timvieira.github.io\nImportance sampling\n[6] Mnih, Volodymyr, et al.\n“Asynchronous methods for deep reinforcement learning.”\nICML. 2016.\n[7] David Silver, et al.\n“Deterministic policy gradient algorithms.”\nICML. 2014.\n[8] Timothy P. Lillicrap, et al.\n“Continuous control with deep reinforcement learning.”\narXiv preprint arXiv:1509.02971 (2015).\n[9] Ryan Lowe, et al.\n“Multi-agent actor-critic for mixed cooperative-competitive environments.”\nNIPS. 2017.\n[10] John Schulman, et al.\n“Trust region policy optimization.”\nICML. 2015.\n[11] Ziyu Wang, et al.\n“Sample efficient actor-critic with experience replay.”\nICLR 2017.\n[12] Rémi Munos, Tom Stepleton, Anna Harutyunyan, and Marc Bellemare.\n“Safe and efficient off-policy reinforcement learning”\nNIPS. 2016.\n[13] Yuhuai Wu, et al.\n“Scalable trust-region method for deep reinforcement learning using Kronecker-factored approximation.”\nNIPS. 2017.\n[14] kvfrans.com\nA intuitive explanation of natural gradient descent\n[15] Sham Kakade.\n“A Natural Policy Gradient.”\n. NIPS. 2002.\n[16]\n“Going Deeper Into Reinforcement Learning: Fundamentals of Policy Gradients.”\n- Seita’s Place, Mar 2017.\n[17]\n“Notes on the Generalized Advantage Estimation Paper.”\n- Seita’s Place, Apr, 2017.\n[18] Gabriel Barth-Maron, et al.\n“Distributed Distributional Deterministic Policy Gradients.”\nICLR 2018 poster.\n[19] Tuomas Haarnoja, Aurick Zhou, Pieter Abbeel, and Sergey Levine.\n“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”\narXiv preprint arXiv:1801.01290 (2018).\n[20] Scott Fujimoto, Herke van Hoof, and Dave Meger.\n“Addressing Function Approximation Error in Actor-Critic Methods.”\narXiv preprint arXiv:1802.09477 (2018).\n[21] Tuomas Haarnoja, et al.\n“Soft Actor-Critic Algorithms and Applications.”\narXiv preprint arXiv:1812.05905 (2018).\n[22] David Knowles.\n“Lagrangian Duality for Dummies”\nNov 13, 2010.\n[23] Yang Liu, et al.\n“Stein variational policy gradient.”\narXiv preprint arXiv:1704.02399 (2017).\n[24] Qiang Liu and Dilin Wang.\n“Stein variational gradient descent: A general purpose bayesian inference algorithm.”\nNIPS. 2016.\n[25] Lasse Espeholt, et al.\n“IMPALA: Scalable Distributed Deep-RL with Importance Weighted Actor-Learner Architectures”\narXiv preprint 1802.01561 (2018).\n[26] Karl Cobbe, et al.\n“Phasic Policy Gradient.”\narXiv preprint arXiv:2009.04416 (2020).\n[27] Chloe Ching-Yun Hsu, et al.\n“Revisiting Design Choices in Proximal Policy Optimization.”\narXiv preprint arXiv:2009.10897 (2020).",
            "metadata": {
              "title": "Policy Gradient Algorithms | Lil'Log",
              "description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "Policy Gradient Algorithms",
              "og:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
              "twitter:card": "summary",
              "twitter:title": "Policy Gradient Algorithms",
              "twitter:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "article:section": "posts",
              "article:published_time": "2018-04-08T00:00:00+00:00",
              "article:modified_time": "2018-04-08T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/ebc73787cbe5/code/body-000.txt",
                "chars": 226,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "bytes": 259350,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-394ec3f8b6a6ccc3dace.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "bytes": 205392,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-9c60abbe659d28457d7a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "bytes": 275060,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a8004105b4a88c05a952.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "bytes": 581593,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-7bc12620d13d41e17f0a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "bytes": 215084,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a1617c1aadd4262ae84a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "bytes": 181566,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-01ca9a7ea1e7d1cd82a2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "bytes": 294810,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a362a645159f0dafa82d.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "bytes": 860130,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-fafbbe0c69813ea86bf2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "bytes": 742699,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-d58e26716f1f269dae8a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "bytes": 300409,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-5e0d3d90650b6cca848e.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "bytes": 497568,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a29af53d479214903180.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "bytes": 332210,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-0061164751ee7e193a70.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "bytes": 253972,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-58ac4a854eb578c151aa.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "bytes": 567524,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-6b398117113938e66d50.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://talkingaboutme.tistory.com/entry/RL-Policy-Gradient-Algorithms",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://tomaxent.com/2019/04/14/%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6%E6%96%B9%E6%B3%95/",
                "label": "Chinese1",
                "type": "a"
              },
              {
                "href": "https://paperexplained.cn/articles/article/detail/31/",
                "label": "Chinese2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "“A (Long) Peek into Reinforcement Learning » Key Concepts”",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "this",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Curse_of_dimensionality",
                "label": "curse of dimensionality",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Sutton & Barto, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.02438.pdf",
                "label": "GAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/04/02/notes-on-the-generalized-advantage-estimation-paper/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/03/28/going-deeper-into-reinforcement-learning-fundamentals-of-policy-gradients/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://timvieira.github.io/blog/post/2014/12/21/importance-sampling/",
                "label": "importance weight",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1205.4839.pdf",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.01783",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dennybritz/reinforcement-learning/tree/master/PolicyGradient/a3c",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/blob/master/baselines/a2c/a2c.py",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/baselines-acktr-a2c/",
                "label": "shown",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1509.02971.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "label": "Batch normalization",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=SyZipzbCb",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05952",
                "label": "PER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1706.02275.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/maddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1502.05477.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/trpo_mpi",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "KL divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL-divergence",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.06347.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ppo1",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.10897",
                "label": "Hsu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.04416",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/phasic-policy-gradient",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.01588",
                "label": "Procgen",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.01224.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acer",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "label": "Retrace",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1708.05144.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acktr",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.05671.pdf",
                "label": "K-FAC",
                "type": "a"
              },
              {
                "href": "http://kvfrans.com/a-intuitive-explanation-of-natural-gradient-descent/",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.452.7280&rep=rep1&type=pdf",
                "label": "Natural Gradient Works Efficiently in Learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "label": "A Natural Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kronecker_product",
                "label": "Wiki: Kronecker product",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/martens15.pdf",
                "label": "Optimizing neural networks with kronecker-factored approximate curvature.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.01290",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/haarnoja/sac",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.08165",
                "label": "Soft Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.05905",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rail-berkeley/softlearning",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "label": "Lagrangian expression",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.09477",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sfujim/TD3",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/3964-double-q-learning",
                "label": "Double Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1509.06461",
                "label": "Double DQN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dilinwang820/Stein-Variational-Gradient-Descent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://www.cs.dartmouth.edu/~qliu/stein.html",
                "label": "Stein",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1608.04471",
                "label": "Liu and Wang, 2016",
                "type": "a"
              },
              {
                "href": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "label": "RKHS",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "Natural gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Radial_basis_function",
                "label": "radial basis function",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01561",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/deepmind/scalable_agent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.08617.pdf",
                "label": "“Distributed Distributional Deterministic Policy Gradients.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1801.01290.pdf",
                "label": "“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "label": "“Stein variational gradient descent: A general purpose bayesian inference algorithm.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "papers": [
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": false,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438.pdf",
                "bytes": 1798117,
                "reused": false,
                "local_path": "papers/repair/be9d8b8466e33236e35e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1205.4839.pdf",
                "bytes": 1610077,
                "reused": false,
                "local_path": "papers/repair/5ab0424e24a7205667b6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.01783",
                "bytes": 2302720,
                "reused": true,
                "local_path": "papers/repair/4ebd69e62e1319a151ba.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:39:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.02971.pdf",
                "bytes": 663643,
                "reused": false,
                "local_path": "papers/repair/cdfdf91c078ecbc5323f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "bytes": 318669,
                "reused": false,
                "local_path": "papers/repair/278c974d701b74b5258e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05952",
                "bytes": 1685573,
                "reused": false,
                "local_path": "papers/repair/232c5d788b53c3e83f28.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.02275.pdf",
                "bytes": 1502182,
                "reused": false,
                "local_path": "papers/repair/472ab942fc65a818d588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.05477.pdf",
                "bytes": 1026237,
                "reused": false,
                "local_path": "papers/repair/40909aa64b5fd4aacb8a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.06347.pdf",
                "bytes": 2923532,
                "reused": false,
                "local_path": "papers/repair/9e750b40bed5bcd1df74.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.10897",
                "bytes": 2074951,
                "reused": false,
                "local_path": "papers/repair/cb042047afd4ec37247c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.04416",
                "bytes": 2019980,
                "reused": false,
                "local_path": "papers/repair/e6984c4570bddcc10cbe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.01588",
                "bytes": 5158205,
                "reused": false,
                "local_path": "papers/repair/3231a0847e3982baa0a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01224.pdf",
                "bytes": 1856923,
                "reused": false,
                "local_path": "papers/repair/49a104905756e51b1082.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "bytes": 309421,
                "reused": false,
                "local_path": "papers/repair/a3c6ca6c0f5fa7ac392b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05144.pdf",
                "bytes": 5151566,
                "reused": false,
                "local_path": "papers/repair/17bd1711b6b1c975cd6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.05671.pdf",
                "bytes": 1801721,
                "reused": false,
                "local_path": "papers/repair/8348cabb06fa9a77e970.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "bytes": 1517587,
                "reused": false,
                "local_path": "papers/repair/5e5447a001f6bb409591.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/martens15.pdf",
                "bytes": 866438,
                "reused": false,
                "local_path": "papers/repair/cf98bb852a85a8c5a9be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/27be080213df12bc727f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.08165",
                "bytes": 3634452,
                "reused": false,
                "local_path": "papers/repair/cc481afce087c678bd26.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.05905",
                "bytes": 6750542,
                "reused": false,
                "local_path": "papers/repair/eb681f8429e54c661586.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "bytes": 157901,
                "reused": false,
                "local_path": "papers/repair/6d312b63b4d7133c0639.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.09477",
                "bytes": 2744342,
                "reused": false,
                "local_path": "papers/repair/b1cc41c6920f45d34ed8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.06461",
                "bytes": 789062,
                "reused": false,
                "local_path": "papers/repair/1b6dc947b906b3bd9192.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": false,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1608.04471",
                "bytes": 595069,
                "reused": false,
                "local_path": "papers/repair/55aec624e4d940526da7.pdf"
              },
              {
                "status": "download_error",
                "url": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "reason": "ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))",
                "retried_at": "2026-10-20T22:23:38Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01561",
                "bytes": 5601159,
                "reused": false,
                "local_path": "papers/repair/14d26b190854999d5443.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.08617.pdf",
                "bytes": 7734735,
                "reused": false,
                "local_path": "papers/repair/2db1af3554211ce5fb37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290.pdf",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/b36e949651aa96489b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "bytes": 477157,
                "reused": false,
                "local_path": "papers/repair/bb0557ad03965422dda1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 76635,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/ebc73787cbe5/pages/source.html",
            "local_html": "attachments/ebc73787cbe5/pages/article.html",
            "body_base_path": "attachments/ebc73787cbe5/pages/",
            "body_markdown_path": "attachments/ebc73787cbe5/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
          "status": "partial",
          "article_id": "8a21c0acfb00",
          "local_path": "series-follow/1602/repair/d28ee743c76f5eaa3eb7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
              "bytes": 337534,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4166a5ced4caf6791370.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
              "bytes": 147142,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d50c93dfe76da4d51e52.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
              "bytes": 94880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c273a3bd2d035c6f2911.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
              "bytes": 121482,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1602/repair/assets/ec939fa4e1c720a45f69.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
              "bytes": 113689,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/63a237a784c9d55c73a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
              "bytes": 65056,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3b94a58b47770eed7ab3.png"
            }
          ],
          "article": {
            "id": "8a21c0acfb00",
            "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "bytes": 337534,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-4166a5ced4caf6791370.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "bytes": 147142,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-d50c93dfe76da4d51e52.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "bytes": 94880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-c273a3bd2d035c6f2911.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "bytes": 121482,
                "reused": false,
                "content_type": "image/jpeg",
                "local_path": "attachments/8a21c0acfb00/images/body-ec939fa4e1c720a45f69.jpg",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "bytes": 113689,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-63a237a784c9d55c73a0.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "bytes": 65056,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-3b94a58b47770eed7ab3.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=sGuiWX07sKw",
                "src": "https://youtu.be/sGuiWX07sKw",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/8a21c0acfb00/videos/repair-sGuiWX07sKw.mp4",
                "bytes": 1536006447,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5957.781000",
                "reused": false
              }
            ],
            "body_markdown": "The algorithms are implemented for Bernoulli bandit in\nlilianweng/multi-armed-bandit\n.\nExploitation vs Exploration\n#\nThe exploration vs exploitation dilemma exists in many aspects of our life. Say, your favorite restaurant is right around the corner. If you go there every day, you would be confident of what you will get, but miss the chances of discovering an even better option. If you try new places all the time, very likely you are gonna have to eat unpleasant food from time to time. Similarly, online advisors try to balance between the known most attractive ads and the new ads that might be even more successful.\nA real-life example of the exploration vs exploitation dilemma: where to eat? (Image source: UC Berkeley AI course\nslide\n,\nlecture 11\n.)\nIf we have learned all the information about the environment, we are able to find the best strategy by even just simulating brute-force, let alone many other smart approaches. The dilemma comes from the\nincomplete\ninformation: we need to gather enough information to make best overall decisions while keeping the risk under control. With exploitation, we take advantage of the best option we know. With exploration, we take some risk to collect information about unknown options. The best long-term strategy may involve short-term sacrifices. For example, one exploration trial could be a total failure, but it warns us of not taking that action too often in the future.\nWhat is Multi-Armed Bandit?\n#\nThe\nmulti-armed bandit\nproblem is a classic problem that well demonstrates the exploration vs exploitation dilemma. Imagine you are in a casino facing multiple slot machines and each is configured with an unknown probability of how likely you can get a reward at one play. The question is:\nWhat is the best strategy to achieve highest long-term rewards?\nIn this post, we will only discuss the setting of having an infinite number of trials. The restriction on a finite number of trials introduces a new type of exploration problem. For instance, if the number of trials is smaller than the number of slot machines, we cannot even try every machine to estimate the reward probability (!) and hence we have to behave smartly w.r.t. a limited set of knowledge and resources (i.e. time).\nAn illustration of how a Bernoulli multi-armed bandit works. The reward probabilities are **unknown** to the player.\nA naive approach can be that you continue to playing with one machine for many many rounds so as to eventually estimate the “true” reward probability according to the\nlaw of large numbers\n. However, this is quite wasteful and surely does not guarantee the best long-term reward.\nDefinition\n#\nNow let’s give it a scientific definition.\nA Bernoulli multi-armed bandit can be described as a tuple of $\\langle \\mathcal{A}, \\mathcal{R} \\rangle$, where:\nWe have $K$ machines with reward probabilities, $\\{ \\theta_1, \\dots, \\theta_K \\}$.\nAt each time step t, we take an action a on one slot machine and receive a reward r.\n$\\mathcal{A}$ is a set of actions, each referring to the interaction with one slot machine. The value of action a is the expected reward, $Q(a) = \\mathbb{E} [r \\vert a] = \\theta$. If action $a_t$ at the time step t is on the i-th machine, then $Q(a_t) = \\theta_i$.\n$\\mathcal{R}$ is a reward function. In the case of Bernoulli bandit, we observe a reward r in a\nstochastic\nfashion. At the time step t, $r_t = \\mathcal{R}(a_t)$ may return reward 1 with a probability $Q(a_t)$ or 0 otherwise.\nIt is a simplified version of\nMarkov decision process\n, as there is no state $\\mathcal{S}$.\nThe goal is to maximize the cumulative reward $\\sum_{t=1}^T r_t$.\nIf we know the optimal action with the best reward, then the goal is same as to minimize the potential\nregret\nor loss by not picking the optimal action.\nThe optimal reward probability $\\theta^{*}$ of the optimal action $a^{*}$ is:\n$$\n\\theta^{*}=Q(a^{*})=\\max_{a \\in \\mathcal{A}} Q(a) = \\max_{1 \\leq i \\leq K} \\theta_i\n$$\nOur loss function is the total regret we might have by not selecting the optimal action up to the time step T:\n$$\n\\mathcal{L}_T = \\mathbb{E} \\Big[ \\sum_{t=1}^T \\big( \\theta^{*} - Q(a_t) \\big) \\Big]\n$$\nBandit Strategies\n#\nBased on how we do exploration, there several ways to solve the multi-armed bandit.\nNo exploration: the most naive approach and a bad one.\nExploration at random\nExploration smartly with preference to uncertainty\nε-Greedy Algorithm\n#\nThe ε-greedy algorithm takes the best action most of the time, but does random exploration occasionally. The action value is estimated according to the past experience by averaging the rewards associated with the target action a that we have observed so far (up to the current time step t):\n$$\n\\hat{Q}_t(a) = \\frac{1}{N_t(a)} \\sum_{\\tau=1}^t r_\\tau \\mathbb{1}[a_\\tau = a]\n$$\nwhere $\\mathbb{1}$ is a binary indicator function and $N_t(a)$ is how many times the action a has been selected so far, $N_t(a) = \\sum_{\\tau=1}^t \\mathbb{1}[a_\\tau = a]$.\nAccording to the ε-greedy algorithm, with a small probability $\\epsilon$ we take a random action, but otherwise (which should be the most of the time, probability 1-$\\epsilon$) we pick the best action that we have learnt so far: $\\hat{a}^{*}_t = \\arg\\max_{a \\in \\mathcal{A}} \\hat{Q}_t(a)$.\nCheck my toy implementation\nhere\n.\nUpper Confidence Bounds\n#\nRandom exploration gives us an opportunity to try out options that we have not known much about. However, due to the randomness, it is possible we end up exploring a bad action which we have confirmed in the past (bad luck!). To avoid such inefficient exploration, one approach is to decrease the parameter ε in time and the other is to be optimistic about options with\nhigh uncertainty\nand thus to prefer actions for which we haven’t had a confident value estimation yet. Or in other words, we favor exploration of actions with a strong potential to have a optimal value.\nThe Upper Confidence Bounds (UCB) algorithm measures this potential by an upper confidence bound of the reward value, $\\hat{U}_t(a)$, so that the true value is below with bound $Q(a) \\leq \\hat{Q}_t(a) + \\hat{U}_t(a)$ with high probability. The upper bound $\\hat{U}_t(a)$ is a function of $N_t(a)$; a larger number of trials $N_t(a)$ should give us a smaller bound $\\hat{U}_t(a)$.\nIn UCB algorithm, we always select the greediest action to maximize the upper confidence bound:\n$$\na^{UCB}_t = argmax_{a \\in \\mathcal{A}} \\hat{Q}_t(a) + \\hat{U}_t(a)\n$$\nNow, the question is\nhow to estimate the upper confidence bound\n.\nHoeffding’s Inequality\n#\nIf we do not want to assign any prior knowledge on how the distribution looks like, we can get help from\n“Hoeffding’s Inequality”\n— a theorem applicable to any bounded distribution.\nLet $X_1, \\dots, X_t$ be i.i.d. (independent and identically distributed) random variables and they are all bounded by the interval [0, 1]. The sample mean is $\\overline{X}_t = \\frac{1}{t}\\sum_{\\tau=1}^t X_\\tau$. Then for $u > 0$, we have:\n$$\n\\mathbb{P} [ \\mathbb{E}[X] > \\overline{X}_t + u] \\leq e^{-2tu^2}\n$$\nGiven one target action $a$, let us consider:\n$r_t(a)$ as the random variables,\n$Q(a)$ as the true mean,\n$\\hat{Q}_t(a)$ as the sample mean,\nAnd $u$ as the upper confidence bound, $u = U_t(a)$\nThen we have,\n$$\n\\mathbb{P} [ Q(a) > \\hat{Q}_t(a) + U_t(a)] \\leq e^{-2t{U_t(a)}^2}\n$$\nWe want to pick a bound so that with high chances the true mean is blow the sample mean + the upper confidence bound. Thus $e^{-2t U_t(a)^2}$ should be a small probability. Let’s say we are ok with a tiny threshold p:\n$$\ne^{-2t U_t(a)^2} = p \\text{  Thus, } U_t(a) = \\sqrt{\\frac{-\\log p}{2 N_t(a)}}\n$$\nUCB1\n#\nOne heuristic is to reduce the threshold p in time, as we want to make more confident bound estimation with more rewards observed. Set $p=t^{-4}$ we get\nUCB1\nalgorithm:\n$$\nU_t(a) = \\sqrt{\\frac{2 \\log t}{N_t(a)}} \\text{  and  }\na^{UCB1}_t = \\arg\\max_{a \\in \\mathcal{A}} Q(a) + \\sqrt{\\frac{2 \\log t}{N_t(a)}}\n$$\nBayesian UCB\n#\nIn UCB or UCB1 algorithm, we do not assume any prior on the reward distribution and therefore we have to rely on the Hoeffding’s Inequality for a very generalize estimation. If we are able to know the distribution upfront, we would be able to make better bound estimation.\nFor example, if we expect the mean reward of every slot machine to be Gaussian as in Fig 2, we can set the upper bound as 95% confidence interval by setting $\\hat{U}_t(a)$ to be twice the standard deviation.\nWhen the expected reward has a Gaussian distribution. $\\sigma(a\\_i)$ is the standard deviation and $c\\sigma(a\\_i)$ is the upper confidence bound. The constant $c$ is a adjustable hyperparameter. (Image source:\nUCL RL course lecture 9's slides\n)\nCheck my toy implementation of\nUCB1\nand\nBayesian UCB\nwith Beta prior on θ.\nThompson Sampling\n#\nThompson sampling has a simple idea but it works great for solving the multi-armed bandit problem.\nOops, I guess not this Thompson? (Credit goes to\nBen Taborsky\n; he has a full theorem of how Thompson invented while pondering over who to pass the ball. Yes I stole his joke.)\nAt each time step, we want to select action a according to the probability that a is\noptimal\n:\n$$\n\\begin{aligned}\n\\pi(a \\; \\vert \\; h_t) \n&= \\mathbb{P} [ Q(a) > Q(a'), \\forall a' \\neq a \\; \\vert \\; h_t] \\\\\n&= \\mathbb{E}_{\\mathcal{R} \\vert h_t} [ \\mathbb{1}(a = \\arg\\max_{a \\in \\mathcal{A}} Q(a)) ]\n\\end{aligned}\n$$\nwhere $\\pi(a ; \\vert ; h_t)$ is the probability of taking action a given the history $h_t$.\nFor the Bernoulli bandit, it is natural to assume that $Q(a)$ follows a\nBeta\ndistribution, as $Q(a)$ is essentially the success probability θ in\nBernoulli\ndistribution.  The value of $\\text{Beta}(\\alpha, \\beta)$ is within the interval [0, 1]; α and β correspond to the counts when we\nsucceeded\nor\nfailed\nto get a reward respectively.\nFirst, let us initialize the Beta parameters α and β based on some prior knowledge or belief for every action. For example,\nα = 1 and β = 1; we expect the reward probability to be 50% but we are not very confident.\nα = 1000 and β = 9000; we strongly believe that the reward probability is 10%.\nAt each time t, we sample an expected reward, $\\tilde{Q}(a)$, from the prior distribution $\\text{Beta}(\\alpha_i, \\beta_i)$ for every action. The best action is selected among samples: $a^{TS}_t = \\arg\\max_{a \\in \\mathcal{A}} \\tilde{Q}(a)$. After the true reward is observed, we can update the Beta distribution accordingly, which is essentially doing Bayesian inference to compute the posterior with the known prior and the likelihood of getting the sampled data.\n$$\n\\begin{aligned}\n\\alpha_i & \\leftarrow \\alpha_i + r_t \\mathbb{1}[a^{TS}_t = a_i] \\\\ \n\\beta_i & \\leftarrow \\beta_i + (1-r_t) \\mathbb{1}[a^{TS}_t = a_i]\n\\end{aligned}\n$$\nThompson sampling implements the idea of\nprobability matching\n. Because its reward estimations $\\tilde{Q}$ are sampled from posterior distributions, each of these probabilities is equivalent to the probability that the corresponding action is optimal, conditioned on observed history.\nHowever, for many practical and complex problems, it can be computationally intractable to estimate the posterior distributions with observed true rewards using Bayesian inference. Thompson sampling still can work out if we are able to approximate the posterior distributions using methods like Gibbs sampling, Laplace approximate, and the bootstraps. This\ntutorial\npresents a comprehensive review; strongly recommend it if you want to learn more about Thompson sampling.\nCase Study\n#\nI implemented the above algorithms in\nlilianweng/multi-armed-bandit\n. A\nBernoulliBandit\nobject can be constructed with a list of random or predefined reward probabilities. The bandit algorithms are implemented as subclasses of\nSolver\n, taking a Bandit object as the target problem. The cumulative regrets are tracked in time.\nThe result of a small experiment on solving a Bernoulli bandit with K = 10 slot machines with reward probabilities, {0.0, 0.1, 0.2, ..., 0.9}. Each solver runs 10000 steps.\n(Left) The plot of time step vs the cumulative regrets. \n(Middle) The plot of true reward probability vs estimated probability. \n(Right) The fraction of each action is picked during the 10000-step run.*\nSummary\n#\nWe need exploration because information is valuable. In terms of the exploration strategies, we can do no exploration at all, focusing on the short-term returns. Or we occasionally explore at random. Or even further, we explore and we are picky about which options to explore — actions with higher uncertainty are favored because they can provide higher information gain.\nCited as:\n@article{weng2018bandit,\n  title   = \"The Multi-Armed Bandit Problem and Its Solutions\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/\"\n}\nReferences\n#\n[1] CS229 Supplemental Lecture notes:\nHoeffding’s inequality\n.\n[2] RL Course by David Silver - Lecture 9:\nExploration and Exploitation\n[3] Olivier Chapelle and Lihong Li.\n“An empirical evaluation of thompson sampling.”\nNIPS. 2011.\n[4] Russo, Daniel, et al.\n“A Tutorial on Thompson Sampling.”\narXiv:1707.02038 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:18Z",
            "title": "The Multi-Armed Bandit Problem and Its Solutions | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/8a21c0acfb00/code/body-000.txt",
                "chars": 255,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "bytes": 87277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7f286fae95f9b1c990be.pdf"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "retried_at": "2026-10-20T17:52:05Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.02038.pdf",
                "bytes": 3259310,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/11b5feb4dc8735d58193.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "bytes": 239361,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6b691aa46c22c662cdf.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 13130,
            "expected_body_images": 6,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/8a21c0acfb00/pages/source.html",
            "local_html": "attachments/8a21c0acfb00/pages/article.html",
            "body_base_path": "attachments/8a21c0acfb00/pages/",
            "body_markdown_path": "attachments/8a21c0acfb00/pages/article.md",
            "links": [
              {
                "href": "http://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/lecture_slides.html",
                "label": "slide",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/slides/Lecture%2011%20--%20Reinforcement%20Learning%20II/SP14%20CS188%20Lecture%2011%20--%20Reinforcement%20Learning%20II.pptx",
                "label": "lecture 11",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Multi-armed_bandit",
                "label": "multi-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "law of large numbers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_decision_process",
                "label": "Markov decision process",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Regret_(decision_theory)",
                "label": "regret",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/solvers.py",
                "label": "here",
                "type": "a"
              },
              {
                "href": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "label": "“Hoeffding’s Inequality”",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "label": "UCL RL course lecture 9's slides",
                "type": "a"
              },
              {
                "href": "https://www.linkedin.com/in/benjamin-taborsky",
                "label": "Ben Taborsky",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beta_distribution",
                "label": "Beta",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bernoulli_distribution",
                "label": "Bernoulli",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_matching",
                "label": "probability matching",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.02038.pdf",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/bandits.py",
                "label": "BernoulliBandit",
                "type": "a"
              },
              {
                "href": "https://youtu.be/sGuiWX07sKw",
                "label": "Exploration and Exploitation",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "label": "“An empirical evaluation of thompson sampling.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
          "status": "http_404"
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
          "status": "partial",
          "article_id": "18b05e29ab9d",
          "local_path": "series-follow/1602/repair/788a1d1b274cec73d601.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
              "bytes": 252865,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/afdfe639fc8e1e1fffd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
              "bytes": 398921,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/16ceaeb88e6dddc6da50.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
              "bytes": 101901,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e1a448b3ff933291fe36.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
              "bytes": 381220,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0cbda3f821a3c389eac8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
              "bytes": 346442,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7e88364dbbb1f375b821.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
              "bytes": 228570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/df4787f5cc26e6a6c19f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
              "bytes": 338618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5e41793b605df1e81d30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
              "bytes": 288179,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3f6e0179b739c72f6462.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
              "bytes": 922761,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f1d133cc3f81469a78d0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
              "bytes": 287370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f0267a45ebe0513db62f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
              "bytes": 261905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3bf6bcdbee4e7c90f493.png"
            }
          ],
          "article": {
            "id": "18b05e29ab9d",
            "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "bytes": 252865,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-afdfe639fc8e1e1fffd2.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "bytes": 398921,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-16ceaeb88e6dddc6da50.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "bytes": 101901,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-e1a448b3ff933291fe36.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "bytes": 381220,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-0cbda3f821a3c389eac8.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "bytes": 346442,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-7e88364dbbb1f375b821.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "bytes": 228570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-df4787f5cc26e6a6c19f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "bytes": 338618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-5e41793b605df1e81d30.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "bytes": 288179,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3f6e0179b739c72f6462.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "bytes": 922761,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f1d133cc3f81469a78d0.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "bytes": 287370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f0267a45ebe0513db62f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "bytes": 261905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3bf6bcdbee4e7c90f493.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "[Updated on 2020-02-03: mentioning\nPCG\nin the “Task-Specific Curriculum” section.\n[Updated on 2020-02-04: Add a new\n“curriculum through distillation”\nsection.\nIt sounds like an impossible task if we want to teach integral or derivative to a 3-year-old who does not even know basic arithmetics. That’s why education is important, as it provides a systematic way to break down complex knowledge and a nice curriculum for teaching concepts from simple to hard. A curriculum makes learning difficult things easier and approachable for us humans. But, how about machine learning models? Can we train our models more efficiently with a curriculum? Can we design a curriculum to speed up learning?\nBack in 1993, Jeffrey Elman has proposed the idea of training neural networks with a curriculum. His early work on learning simple language grammar demonstrated the importance of such a strategy: starting with a restricted set of simple data and gradually increasing the complexity of training samples; otherwise the model was not able to learn at all.\nCompared to training without a curriculum, we would expect the adoption of the curriculum to expedite the speed of convergence and may or may not improve the final model performance. To design an efficient and effective curriculum is not easy. Keep in mind that, a bad curriculum may even hamper learning.\nNext, we will look into several categories of curriculum learning, as illustrated in Most cases are applied to Reinforcement Learning, with a few exceptions on Supervised Learning.\nFive types of curriculum for reinforcement learning.\nIn “The importance of starting small” paper (\nElman 1993\n), I especially like the starting sentences and find them both inspiring and affecting:\n“Humans differ from other species along many dimensions, but two are particularly noteworthy. Humans display an exceptional capacity to learn; and humans are remarkable for the unusually long time it takes to reach maturity. The adaptive advantage of learning is clear, and it may be argued that, through culture, learning has created the basis for a non-genetically based transmission of behaviors which may accelerate the evolution of our species.”\nIndeed, learning is probably the best superpower we humans have.\nTask-Specific Curriculum\n#\nBengio, et al. (2009)\nprovided a good overview of curriculum learning in the old days. The paper presented two ideas with toy experiments using a manually designed task-specific curriculum:\nCleaner Examples may yield better generalization faster.\nIntroducing gradually more difficult examples speeds up online training.\nIt is plausible that some curriculum strategies could be useless or even harmful. A good question to answer in the field is:\nWhat could be the general principles that make some curriculum strategies work better than others?\nThe Bengio 2009 paper hypothesized it would be beneficial to make learning focus on “interesting” examples that are neither too hard or too easy.\nIf our naive curriculum is to train the model on samples with a gradually increasing level of complexity, we need a way to quantify the difficulty of a task first. One idea is to use its minimal loss with respect to another model while this model is pretrained on other tasks (\nWeinshall, et al. 2018\n). In this way, the knowledge of the pretrained model can be transferred to the new model by suggesting a rank of training samples. Fig. 2 shows the effectiveness of the\ncurriculum\ngroup (green), compared to\ncontrol\n(random order; yellow) and\nanti\n(reverse the order; red) groups.\nImage classification accuracy on test image set (5 member classes of \"small mammals\" in CIFAR100). There are 4 experimental groups, (a) `curriculum`: sort the labels by the confidence of another trained classifier (e.g. the margin of an SVM); (b) `control-curriculum`: sort the labels randomly; (c) `anti-curriculum`: sort the labels reversely; (d) `None`: no curriculum. (Image source:\nWeinshall, et al. 2018\n)\nZaremba & Sutskever (2014)\ndid an interesting experiment on training LSTM to predict the output of a short Python program for mathematical ops without actually executing the code. They found curriculum is necessary for learning. The program’s complexity is controlled by two parameters,\nlength\n∈ [1, a] and\nnesting\n∈ [1, b]. Three strategies are considered:\nNaive curriculum: increase\nlength\nfirst until reaching\na\n; then increase\nnesting\nand reset\nlength\nto 1; repeat this process until both reach maximum.\nMix curriculum: sample\nlength\n~ [1, a] and\nnesting\n~ [1, b]\nCombined: naive + mix.\nThey noticed that combined strategy always outperformed the naive curriculum and would generally (but not always) outperform the mix strategy — indicating that it is quite important to mix in easy tasks during training to\navoid forgetting\n.\nProcedural content generation (\nPCG\n) is a popular approach for creating video games of various levels of difficulty. PCG involves algorithmic randomness and a heavy dose of human expertise in designing game elements and dependencies among them. Procedurally generated levels have been introduced into several benchmark environments for evaluating whether an RL agent can generalize to a new level that it is not trained on (\nmeta-RL\n!), such as\nGVGAI\n, OpenAI\nCoinRun\nand\nProcgen benchmark\n. Using GVGAI,\nJustesen, et al. (2018)\ndemonstrated that an RL policy can easily overfit to a specific game but training over a simple curriculum that grows the task difficulty together with the model performance helps its generalization to new human-designed levels. Similar results are also found in CoinRun (\nCobbe, et al. 2018\n). POET (\nWang et al, 2019\n) is another example for leveraging evolutionary algorithm and procedural generated game levels to improve RL generalization, which I’ve described in details in my\nmeta-RL post\n.\nTo follow the curriculum learning approaches described above, generally we need to figure out two problems in the training procedure:\nDesign a metric to quantify how hard a task is so that we can sort tasks accordingly.\nProvide a sequence of tasks with an increasing level of difficulty to the model during training.\nHowever, the order of tasks does not have to be sequential. In our Rubik’s cube paper (\nOpenAI et al, 2019\n), we depended on\nAutomatic domain randomization\n(\nADR\n) to generate a curriculum by growing a distribution of environments with increasing complexity. The difficulty of each task (i.e. solving a Rubik’s cube in a set of environments) depends on the randomization ranges of various environmental parameters. Even with a simplified assumption that all the environmental parameters are uncorrelated, we were able to create a decent curriculum for our robot hand to learn the task.\nTeacher-Guided Curriculum\n#\nThe idea of\nAutomatic Curriculum Learning\nwas proposed by\nGraves, et al. 2017\nslightly earlier. It considers a $N$-task curriculum as an\n$N$-armed bandit\nproblem and an adaptive policy which learns to optimize the returns from this bandit.\nTwo categories of learning signals have been considered in the paper:\nLoss-driven progress: the loss function change before and after one gradient update. This type of reward signals tracks the speed of the learning process, because the greatest task loss decrease is equivalent to the fastest learning.\nComplex-driven progress: the KL divergence between posterior and prior distribution over network weights. This type of learning signals are inspired by the\nMDL\nprinciple, “increasing the model complexity by a certain amount is only worthwhile if it compresses the data by a greater amount”. The model complexity is therefore expected to increase most in response to the model nicely generalizing to training examples.\nThis framework of proposing curriculum automatically through another RL agent was formalized as\nTeacher-Student Curriculum Learning\n(\nTSCL\n;\nMatiisen, et al. 2017\n). In TSCL, a\nstudent\nis an RL agent working on actual tasks while a\nteacher\nagent is a policy for selecting tasks. The student aims to master a complex task that might be hard to learn directly. To make this task easier to learn, we set up the teacher agent to guide the student’s training process by picking proper sub-tasks.\nThe setup of teacher-student curriculum learning. (Image source:\nMatiisen, et al. 2017\n+ my annotation in red.)\nIn the process, the student should learn tasks which:\ncan help the student make fastest learning progress, or\nare at risk of being forgotten.\nNote: The setup of framing the teacher model as an RL problem feels quite similar to Neural Architecture Search (NAS), but differently the RL model in TSCL operates on the task space and NAS operates on the main model architecture space.\nTraining the teacher model is to solve a\nPOMDP\nproblem:\nThe unobserved $s_t$ is the full state of the student model.\nThe observed $o = (x_t^{(1)}, \\dots, x_t^{(N)})$ are a list of scores for $N$ tasks.\nThe action $a$ is to pick on subtask.\nThe reward per step is the score delta.$r_t = \\sum_{i=1}^N x_t^{(i)} - x_{t-1}^{(i)}$ (i.e., equivalent to maximizing the score of all tasks at the end of the episode).\nThe method of estimating learning progress from noisy task scores while balancing exploration vs exploitation can be borrowed from the non-stationary multi-armed bandit problem — use\nε-greedy\n, or\nThompson sampling\n.\nThe core idea, in summary, is to use one policy to propose tasks for another policy to learn better. Interestingly, both works above (in the discrete task space) found that uniformly sampling from all tasks is a surprisingly strong benchmark.\nWhat if the task space is continuous?\nPortelas, et al. (2019)\nstudied a continuous teacher-student framework, where the teacher has to sample parameters from continuous task space to generate a learning curriculum. Given a newly sampled parameter $p$, the absolute learning progress (short for ALP) is measured as $\\text{ALP}_p = \\vert r - r_\\text{old} \\vert$, where $r$ is the episodic reward associated with $p$ and $r_\\text{old}$ is the reward associated with $p_\\text{old}$. Here, $p_\\text{old}$ is a previous sampled parameter closest to $p$ in the task space, which can be retrieved by nearest neighbor. Note that how this ALP score is different from learning signals in\nTSCL\nor\nGrave, et al. 2017\nabove: ALP score measures the reward difference between two tasks rather than performance at two time steps of the same task.\nOn top of the task parameter space, a Gaussian mixture model is trained to fit the distribution of $\\text{ALP}_p$ over $p$. ε-greedy is used when sampling the tasks: with some probability, sampling a random task; otherwise sampling proportionally to ALP score from the GMM model.\nThe algorithm of ALP-GMM (absolute learning progress Gaussian mixture model). (Image source:\nPortelas, et al., 2019\n)\nCurriculum through Self-Play\n#\nDifferent from the teacher-student framework, two agents are doing very different things. The teacher learns to pick a task for the student without any knowledge of the actual task content. What if we want to make both train on the main task directly? How about even make them compete with each other?\nSukhbaatar, et al. (2017)\nproposed a framework for automatic curriculum learning through\nasymmetric self-play\n. Two agents, Alice and Bob, play the same task with different goals: Alice challenges Bob to achieve the same state and Bob attempts to complete it as fast as he can.\nIllustration of the self-play setup when training two agents. The example task is\nMazeBase\n: An agent is asked to reach a goal flag in a maze with a light switch, a key and a wall with a door. Toggling the key switch can open or close the door and Turning off the light makes only the glowing light switch available to the agent. (Image source:\nSukhbaatar, et al. 2017\n)\nLet us consider Alice and Bob as two separate copies for one RL agent trained in the same environment but with different brains. Each of them has independent parameters and loss objective. The self-play-driven training consists of two types of episodes:\nIn the\nself-play episode\n, Alice alters the state from $s_0$ to $s_t$ and then Bob is asked to return the environment to its original state $s_0$ to get an internal reward.\nIn the\ntarget task episode\n, Bob receives an external reward if he visits the target flag.\nNote that since B has to repeat the actions between the same pair of $(s_0, s_t)$ of A, this framework only works in reversible or resettable environments.\nAlice should learn to push Bob out of his comfort zone, but not give him impossible tasks. Bob’s reward is set as $R_B = -\\gamma t_B$ and Alice’s reward is $R_A = \\gamma \\max(0, t_B - t_A)$, where $t_B$ is the total time for B to complete the task, $t_A$ is the time until Alice performs the STOP action and $\\gamma$ is a scalar constant to rescale the reward to be comparable with the external task reward. If B fails a task, $t_B = t_\\max - t_A$.\nBoth policies are goal-conditioned. The losses imply:\nB wants to finish a task asap.\nA prefers tasks that take more time of B.\nA does not want to take too many steps when B is failing.\nIn this way, the interaction between Alice and Bob automatically builds a curriculum of increasingly challenging tasks. Meanwhile, as A has done the task herself before proposing the task to B, the task is guaranteed to be solvable.\nThe paradigm of A suggesting tasks and then B solving them does sound similar to the Teacher-Student framework. However, in asymmetric self-play, Alice, who plays a teacher role, also works on the same task to find challenging cases for Bob, rather than optimizes B’s learning process explicitly.\nAutomatic Goal Generation\n#\nOften RL policy needs to be able to perform over a set of tasks. The goal should be carefully chosen so that at every training stage, it would not be too hard or too easy for the current policy. A goal $g \\in \\mathcal{G}$ can be defined as a set of states $S^g$ and a goal is considered as achieved whenever an agent arrives at any of those states.\nThe approach of Generative Goal Learning (\nFlorensa, et al. 2018\n) relies on a\nGoal GAN\nto generate desired goals automatically. In their experiment, the reward is very sparse, just a binary flag for whether a goal is achieved or not and the policy is conditioned on goal,\n$$\n\\begin{aligned}\n\\pi^{*}(a_t\\vert s_t, g) &= \\arg\\max_\\pi \\mathbb{E}_{g\\sim p_g(.)} R^g(\\pi) \\\\\n\\text{where }R^g(\\pi) &= \\mathbb{E}_\\pi(.\\mid s_t, g) \\mathbf{1}[\\exists t \\in [1,\\dots, T]: s_t \\in S^g]\n\\end{aligned}\n$$\nHere $R^g(\\pi)$ is the expected return, also equivalent to the success probability. Given sampled trajectories from the current policy, as long as any state belongs to the goal set, the return will be positive.\nTheir approach iterates through 3 steps until the policy converges:\nLabel a set of goals based on whether they are at the appropriate level of difficulty for the current policy.\nThe set of goals at the appropriate level of difficulty are named\nGOID\n(short for “Goals of Intermediate Difficulty”).\n$\\text{GOID}_i := \\{g : R_\\text{min} \\leq R^g(\\pi_i) \\leq R_\\text{max} \\} \\subseteq G$\nHere $R_\\text{min}$ and $R_\\text{max}$ can be interpreted as a minimum and maximum probability of reaching a goal over T time-steps.\nTrain a Goal GAN model using labelled goals from step 1 to produce new goals\nUse these new goals to train the policy, improving its coverage objective.\nThe Goal GAN generates a curriculum automatically:\nGenerator $G(z)$: produces a new goal. => expected to be a goal uniformly sampled from $GOID$ set.\nDiscriminator $D(g)$: evaluates whether a goal can be achieved. => expected to tell whether a goal is from $GOID$ set.\nThe Goal GAN is constructed similar to LSGAN (Least-Squared GAN;\nMao et al., (2017)\n), which has better stability of learning compared to vanilla GAN. According to LSGAN, we should minimize the following losses for $D$ and $G$ respectively:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{LSGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{LSGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nwhere $a$ is the label for fake data, $b$ for real data, and $c$ is the value that $G$ wants $D$ to believe for fake data. In LSGAN paper’s experiments, they used $a=-1, b=1, c=0$.\nThe Goal GAN introduces an extra binary flag $y_b$ indicating whether a goal $g$ is real ($y_g = 1$) or fake ($y_g = 0$) so that the model can use negative samples for training:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{GoalGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2 + (1-y_g) (D(g) - a)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{GoalGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nThe algorithm of Generative Goal Learning. (Image source: (\nFlorensa, et al. 2018\n)\nFollowing the same idea,\nRacaniere & Lampinen, et al. (2019)\ndesigns a method to make the objectives of goal generator more sophisticated. Their method contains three components, same as generative goal learning above:\nSolver\n/Policy $\\pi$: In each episode, the solver gets a goal $g$ at the beginning and get a single binary reward $R^g$ at the end.\nJudge\n/Discriminator $D(.)$: A classifier to predict the binary reward (whether goal can be achieved or not); precisely it outputs the logit of a probability of achieving the given goal, $\\sigma(D(g)) = p(R^g=1\\vert g)$, where $\\sigma$ is the sigmoid function.\nSetter\n/Generator $G(.)$: The goal setter takes as input a desired feasibility score $f \\in \\text{Unif}(0, 1)$ and generates $g = G(z, f)$, where the latent variable $z$ is sampled by $z \\sim \\mathcal{N}(0, I)$. The goal generator is designed to reversible, so $G^{-1}$ can map backwards from a goal $g$ to a latent $z = G^{-1}(g, f)$\nThe generator is optimized with three objectives:\nGoal\nvalidity\n: The proposed goal should be achievable by an expert policy. The corresponding generative loss is designed to increase the likelihood of generating goals that the solver policy has achieved before (like in\nHER\n).\n$\\mathcal{L}_\\text{val}$ is the negative log-likelihood of generated goals that have been solved by the solver in the past.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{val} = \\mathbb{E}_{\\substack{\n  g \\sim \\text{ achieved by solver}, \\\\\n  \\xi \\in \\text{Uniform}(0, \\delta), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ -\\log p(G^{-1}(g + \\xi, f)) \\big]\n\\end{align*}\n$$\nGoal\nfeasibility\n: The proposed goal should be achievable by the current policy; that is, the level of difficulty should be appropriate.\n$\\mathcal{L}_\\text{feas}$ is the output probability by the judge model $D$ on the generated goal $G(z, f)$ should match the desired $f$.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{feas} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ D(G(z, f)) - \\sigma^{-1}(f)^2 \\big]\n\\end{align*}\n$$\nGoal\ncoverage\n: We should maximize the entropy of generated goals to encourage diverse goal and to improve the coverage over the goal space.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{cov} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ \\log p(G(z, f)) \\big]\n\\end{align*}\n$$\nTheir experiments showed complex environments require all three losses above. When the environment is changing between episodes, both the goal generator and the discriminator need to be conditioned on environmental observation to produce better results. If there is a desired goal distribution, an additional loss can be added to match a desired goal distribution using Wasserstein distance. Using this loss, the generator can push the solver toward mastering the desired tasks more efficiently.\nTraining schematic for the (a) solver/policy, (b) judge/discriminator, and (c) setter/goal generator models. (Image source:\nRacaniere & Lampinen, et al., 2019\n)\nSkill-Based Curriculum\n#\nAnother view is to decompose what an agent is able to complete into a variety of skills and each skill set could be mapped into a task. Let’s imagine when an agent interacts with the environment in an unsupervised manner, is there a way to discover useful skills from such interaction and further build into the solutions for more complicated tasks through a curriculum?\nJabri, et al. (2019)\ndeveloped an automatic curriculum,\nCARML\n(short for “Curricula for Unsupervised Meta-Reinforcement Learning”), by modeling unsupervised trajectories into a latent skill space, with a focus on training\nmeta-RL\npolicies (i.e. can transfer to unseen tasks). The setting of training environments in CARML is similar to\nDIAYN\n. Differently, CARML is trained on pixel-level observations but DIAYN operates on the true state space. An RL algorithm $\\pi_\\theta$, parameterized by $\\theta$, is trained via unsupervised interaction formulated as a CMP combined with a learned reward function $r$. This setting naturally works for the meta-learning purpose, since a customized reward function can be given only at the test time.\nAn illustration of CARML, containing two steps: (1) organizing experiential data into the latent skill space; (2) meta-training the policy with the reward function constructed from the learned skills. (Image source:\nJabri, et al 2019\n)\nCARML is framed as a\nvariational Expectation-Maximization (EM)\n.\n(1)\nE-Step\n: This is the stage for organizing experiential data. Collected trajectories are modeled with a mixture of latent components forming the\nbasis\nof\nskills\n.\nLet $z$ be a latent task variable and $q_\\phi$ be a variational distribution of $z$, which could be a mixture model with discrete $z$ or a VAE with continuous $z$. A variational posterior $q_\\phi(z \\vert s)$ works like a classifier, predicting a skill given a state, and we would like to maximize $q_\\phi(z \\vert s)$ to discriminate between data produced by different skills as much as possible. In E-step, $q_\\phi$ is fitted to a set of trajectories produced by $\\pi_\\theta$.\nPrecisely, given a trajectory $\\tau = (s_1,\\dots,s_T)$, we would like to find $\\phi$ such that\n$$\n\\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\log q_\\phi(\\tau \\vert z) \\big]\n= \\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\sum_{s_i \\in \\tau} \\log q_\\phi(s_i \\vert z) \\big]\n$$\nA simplifying assumption is made here to ignore the order of states in one trajectory.\n(2)\nM-Step\n: This is the stage for doing meta-RL training with $\\pi_\\theta$. The learned skill space is considered as a training task distribution. CARML is agnostic to the type of meta-RL algorithm for policy parameter updates.\nGiven a trajectory $\\tau$, it makes sense for the policy to maximize the mutual information between $\\tau$ and $z$, $I(\\tau;z) = H(\\tau) - H(\\tau \\vert z)$, because:\nmaximizing $H(\\tau)$ => diversity in the policy data space; expected to be large.\nminimizing $H(\\tau \\vert z)$ => given a certain skill, the behavior should be restricted; expected to be small.\nThen we have,\n$$\n\\begin{aligned}\nI(\\tau; z) \n&= \\mathcal{H}(z) - \\mathcal{H}(z \\vert s_1,\\dots, s_T) \\\\\n&\\geq \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(z) - \\mathcal{H}(z\\vert s)] & \\scriptstyle{\\text{; discard the order of states.}} \\\\\n&= \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(s_t) - \\mathcal{H}(s\\vert z)] & \\scriptstyle{\\text{; by definition of MI.}} \\\\\n&= \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\log q_\\phi(s|z) - \\log \\pi_\\theta(s)] \\\\\n&\\approx \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\color{green}{\\log q_\\phi(s|z) - \\log q_\\phi(s)}] & \\scriptstyle{\\text{; assume learned marginal distr. matches policy.}}\n\\end{aligned}\n$$\nWe can set the reward as $\\log q_\\phi(s \\vert z) - \\log q_\\phi(s)$, as shown in the\nred\npart in the equation above. In order to balance between task-specific exploration (as in\nred\nbelow) and latent skill matching (as in\nblue\nbelow) , a parameter $\\lambda \\in [0, 1]$ is added. Each realization of $z \\sim q_\\phi(z)$ induces a reward function $r_z(s)$ (remember that reward + CMP => MDP) as follows:\n$$\n\\begin{aligned}\nr_z(s)\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s) \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log \\frac{q_\\phi(s|z) q_\\phi(z)}{q_\\phi(z|s)} \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s|z) - \\log q_\\phi(z) + \\log q_\\phi(z|s) \\\\\n&= (\\lambda - 1) \\log \\color{red}{q_\\phi(s|z)} + \\color{blue}{\\log q_\\phi(z|s)} + C\n\\end{aligned}\n$$\nThe algorithm of CARML. (Image source:\nJabri, et al 2019\n)\nLearning a latent skill space can be done in different ways, such as in\nHausman, et al. 2018\n. The goal of their approach is to learn a task-conditioned policy, $\\pi(a \\vert s, t^{(i)})$, where $t^{(i)}$ is from a discrete list of $N$ tasks, $\\mathcal{T} = [t^{(1)}, \\dots, t^{(N)}]$. However, rather than learning $N$ separate solutions, one per task, it would be nice to learn a latent skill space so that each task could be represented in a distribution over skills and thus skills are\nreused between tasks\n. The policy is defined as $\\pi_\\theta(a \\vert s,t) = \\int \\pi_\\theta(a \\vert z,s,t) p_\\phi(z \\vert t)\\mathrm{d}z$, where $\\pi_\\theta$ and $p_\\phi$ are policy and embedding networks to learn, respectively. If $z$ is discrete, i.e. drawn from a set of $K$ skills, then the policy becomes a mixture of $K$ sub-policies. The policy training uses\nSAC\nand the dependency on $z$ is introduced in the entropy term.\nCurriculum through Distillation\n#\n[I was thinking of the name of this section for a while, deciding between cloning, inheritance, and distillation. Eventually, I picked distillation because it sounds the coolest B-)]\nThe motivation for the\nprogressive neural network\n(\nRusu et al. 2016\n) architecture is to efficiently transfer learned skills between different tasks and in the meantime avoid catastrophic forgetting. The curriculum is realized through a set of progressively stacked neural network towers (or “columns”, as in the paper).\nA progressive network has the following structure:\nIt starts with a single column containing $L$ layers of neurons, in which the corresponding activation layers are labelled as $h^{(1)}_i, i=1, \\dots, L$. We first train this single-column network for one task to convergence, achieving parameter config $\\theta^{(1)}$.\nOnce switch to the next task, we need to add a new column to adapt to the new context while freezing $\\theta^{(1)}$ to lock down the learned skills from the previous task. The new column has activation layers labelled as $h^{(2)}_i, i=1, \\dots, L$, and parameters $\\theta^{(2)}$.\nStep 2 can be repeated with every new task. The $i$-th layer activation in the $k$-th column depends on the previous activation layers in all the existing columns:\n$$\n h^{(k)}_i = f(W^{(k)}_i h^{(k)}_{i-1} + \\sum_{j < k} U_i^{(k:j)} h^{(j)}_{i-1})\n $$\nwhere $W^{(k)}_i$ is the weight matrix of the layer $i$ in the column $k$; $U_i^{(k:j)}, j < k$ are the weight matrices for projecting the layer $i-1$ of the column $j$ to the layer $i$ of column $k$ ($ j < k $). The above weights matrices should be learned. $f(.)$ is a non-linear activation function by choice.\nThe progressive neural network architecture. (Image source:\nRusu, et al. 2017\n)\nThe paper experimented with Atari games by training a progressive network on multiple games to check whether features learned in one game can transfer to another. That is indeed the case. Though interestingly, learning a high dependency on features in the previous columns does not always indicate good transfer performance on the new task. One hypothesis is that features learned from the old task might introduce biases into the new task, leading to policy getting trapped in a sub-optimal solution. Overall, the progressive network works better than only fine-tuning the top layer and can achieve similar transfer performance as fine-tuning the entire network.\nOne use case for the progressive network is to do sim2real transfer (\nRusu, et al. 2017\n), in which the first column is trained in simulator with a lot of samples and then the additional columns (could be for different real-world tasks) are added and trained with a few real data samples.\nCzarnecki, et al. (2018)\nproposed another RL training framework,\nMix & Match\n(short for\nM&M\n) to provide curriculum through coping knowledge between agents. Given a sequence of agents from simple to complex, $\\pi_1, \\dots, \\pi_K$, each parameterized with some shared weights (e.g. by shared some lower common layers). M&M trains a mixture of agents, but only the final performance of the most complex one $\\pi_K$ matters.\nIn the meantime, M&M learns a categorical distribution $c \\sim \\text{Categorical}(1, \\dots, K \\vert \\alpha)$ with\npmf\n$p(c=i) = \\alpha_i$ probability to pick which policy to use at a given time. The mixed M&M policy is a simple weighted sum: $\\pi_\\text{mm}(a \\vert s) = \\sum_{i=1}^K \\alpha_i \\pi_i(a \\vert s)$. Curriculum learning is realized by dynamically adjusting $\\alpha_i$, from $\\alpha_K=0$ to $\\alpha_K=1$. The tuning of $\\alpha$ can be manual or through\npopulation-based training\n.\nTo encourage cooperation rather than competition among policies, besides the RL loss $\\mathcal{L}_\\text{RL}$, another\ndistillation\n-like loss $\\mathcal{L}_\\text{mm}(\\theta)$ is added. The knowledge transfer loss $\\mathcal{L}_\\text{mm}(\\theta)$ measures the KL divergence between two policies, $\\propto D_\\text{KL}(\\pi_{i}(. \\vert s) | \\pi_j(. \\vert s))$ for $i < j$. It encourages complex agents to match the simpler ones early on. The final loss is $\\mathcal{L} = \\mathcal{L}_\\text{RL}(\\theta \\vert \\pi_\\text{mm}) + \\lambda \\mathcal{L}_\\text{mm}(\\theta)$.\nThe Mix & Match architecture for training a mixture of policies.  (Image source:\nCzarnecki, et al., 2018\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2020). Curriculum for reinforcement learning. Lil’Log. https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/.\nOr\n@article{weng2020curriculum,\n  title   = \"Curriculum for Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/\"\n}\nReferences\n#\n[1] Jeffrey L. Elman.\n“Learning and development in neural networks: The importance of starting small.”\nCognition 48.1 (1993): 71-99.\n[2] Yoshua Bengio, et al.\n“Curriculum learning.”\nICML 2009.\n[3] Daphna Weinshall, Gad Cohen, and Dan Amir.\n“Curriculum learning by transfer learning: Theory and experiments with deep networks.”\nICML 2018.\n[4] Wojciech Zaremba and Ilya Sutskever.\n“Learning to execute.”\narXiv preprint arXiv:1410.4615 (2014).\n[5] Tambet Matiisen, et al.\n“Teacher-student curriculum learning.”\nIEEE Trans. on neural networks and learning systems (2017).\n[6] Alex Graves, et al.\n“Automated curriculum learning for neural networks.”\nICML 2017.\n[7]  Remy Portelas, et al.\nTeacher algorithms for curriculum learning of Deep RL in continuously parameterized environments\n. CoRL 2019.\n[8] Sainbayar Sukhbaatar, et al.\n“Intrinsic Motivation and Automatic Curricula via Asymmetric Self-Play.”\nICLR 2018.\n[9] Carlos Florensa, et al.\n“Automatic Goal Generation for Reinforcement Learning Agents”\nICML 2019.\n[10] Sebastien Racaniere & Andrew K. Lampinen, et al.\n“Automated Curriculum through Setter-Solver Interactions”\nICLR 2020.\n[11] Allan Jabri, et al.\n“Unsupervised Curricula for Visual Meta-Reinforcement Learning”\nNeuriPS 2019.\n[12] Karol Hausman, et al.\n“Learning an Embedding Space for Transferable Robot Skills “\nICLR 2018.\n[13] Josh Merel, et al.\n“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”\narXiv preprint arXiv:1911.06636 (2019).\n[14] OpenAI, et al.\n“Solving Rubik’s Cube with a Robot Hand.”\narXiv preprint arXiv:1910.07113 (2019).\n[15] Niels Justesen, et al.\n“Illuminating Generalization in Deep Reinforcement Learning through Procedural Level Generation”\nNeurIPS 2018 Deep RL Workshop.\n[16] Karl Cobbe, et al.\n“Quantifying Generalization in Reinforcement Learning”\narXiv preprint arXiv:1812.02341 (2018).\n[17] Andrei A. Rusu et al.\n“Progressive Neural Networks”\narXiv preprint arXiv:1606.04671 (2016).\n[18] Andrei A. Rusu et al.\n“Sim-to-Real Robot Learning from Pixels with Progressive Nets.”\nCoRL 2017.\n[19] Wojciech Marian Czarnecki, et al.\n“Mix & Match – Agent Curricula for Reinforcement Learning.”\nICML 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:47Z",
            "title": "Curriculum for Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/18b05e29ab9d/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_403",
                "url": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03796",
                "bytes": 585421,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6faa67cb3f93d77c9d67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.4615",
                "bytes": 559518,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a33b0ab1229e8af644d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.10729",
                "bytes": 999159,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/09fa801246d0c67848b3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.02341",
                "bytes": 7003398,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/9e7f2dbe5f93a5d5e4a2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/1910.07113.",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03003",
                "bytes": 3091441,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b98bef9914392e12f875.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.00183",
                "bytes": 1347985,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/79adfbe28098dc1e1722.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07224",
                "bytes": 2628539,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f72a60e37e01560d1e27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.05407",
                "bytes": 2032765,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f4e7d6c2102fc058dc62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.06366",
                "bytes": 6654321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3bc7353a8badf27f9df4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04076",
                "bytes": 3719760,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7af911a9191b6055b1a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.12892",
                "bytes": 2506625,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a8a071c792508aea939d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.01495",
                "bytes": 2464277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/81859ed20fbb79d50eec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.04226",
                "bytes": 3425807,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b8a67f584549b501f6b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04671",
                "bytes": 4278357,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3304a794e8bdd5c42143.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.04286",
                "bytes": 1087389,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b715f19efae8d26a11d0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.01780",
                "bytes": 4106903,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5c9572e1111a7e6fdcb1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06295",
                "bytes": 727329,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/270be775129eb54c13ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.06636",
                "bytes": 5806364,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e62ae132fefd8cc55d44.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07113",
                "bytes": 5194320,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2ef619bdd5bd429418f2.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 32251,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_403；http_404",
            "raw_html": "attachments/18b05e29ab9d/pages/source.html",
            "local_html": "attachments/18b05e29ab9d/pages/article.html",
            "body_base_path": "attachments/18b05e29ab9d/pages/",
            "body_markdown_path": "attachments/18b05e29ab9d/pages/article.md",
            "links": [
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.128.4487&rep=rep1&type=pdf",
                "label": "Elman 1993",
                "type": "a"
              },
              {
                "href": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "label": "Bengio, et al. (2009)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03796",
                "label": "Weinshall, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.4615",
                "label": "Zaremba & Sutskever (2014)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Procedural_generation",
                "label": "PCG",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "meta-RL",
                "type": "a"
              },
              {
                "href": "http://www.gvgai.net/",
                "label": "GVGAI",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/quantifying-generalization-in-reinforcement-learning/",
                "label": "CoinRun",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/procgen-benchmark/",
                "label": "Procgen benchmark",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.10729",
                "label": "Justesen, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.02341",
                "label": "Cobbe, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113.",
                "label": "OpenAI et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03003",
                "label": "Graves, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$N$-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimum_description_length",
                "label": "MDL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.00183",
                "label": "Matiisen, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Partially_observable_Markov_decision_process",
                "label": "POMDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07224",
                "label": "Portelas, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.05407",
                "label": "Sukhbaatar, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://github.com/facebook/MazeBase",
                "label": "MazeBase",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.06366",
                "label": "Florensa, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04076",
                "label": "Mao et al., (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.12892",
                "label": "Racaniere & Lampinen, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.01495",
                "label": "HER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.04226",
                "label": "Jabri, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://chrischoy.github.io/research/Expectation-Maximization-and-Variational-Inference/",
                "label": "variational Expectation-Maximization (EM)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Basis_(linear_algebra)",
                "label": "basis",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=rk07ZXZRb",
                "label": "Hausman, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://127.0.0.1:4000/lil-log/2018/04/07/policy-gradient-algorithms.html",
                "label": "SAC",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04671",
                "label": "Rusu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.04286",
                "label": "Rusu, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.01780",
                "label": "Czarnecki, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_mass_function",
                "label": "pmf",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "population-based training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06295",
                "label": "distillation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.06636",
                "label": "“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113",
                "label": "“Solving Rubik’s Cube with a Robot Hand.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
          "status": "ok",
          "article_id": "3cea57e75b80",
          "local_path": "series-follow/1602/repair/af2ac25733510357c46b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
              "bytes": 313515,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/41ecf126bf1745efcc5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
              "bytes": 146194,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3ea228d0e87dde9e7cf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
              "bytes": 354759,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6bd3a5f62a05f8cd2ac7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
              "bytes": 416371,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b634c681f16b15e45c48.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
              "bytes": 57364,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/db6d0799d37711ac02cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
              "bytes": 599299,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e2359292b85ebbae6075.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
              "bytes": 423806,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a6b205a1fce5f8c10434.png"
            }
          ],
          "article": {
            "id": "3cea57e75b80",
            "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "bytes": 313515,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-41ecf126bf1745efcc5a.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "bytes": 146194,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-3ea228d0e87dde9e7cf1.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "bytes": 354759,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-6bd3a5f62a05f8cd2ac7.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "bytes": 416371,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-b634c681f16b15e45c48.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "bytes": 57364,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-db6d0799d37711ac02cd.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "bytes": 599299,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-e2359292b85ebbae6075.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "bytes": 423806,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-a6b205a1fce5f8c10434.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=bLqJHjXihK8",
                "src": "https://youtu.be/bLqJHjXihK8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-bLqJHjXihK8.mp4",
                "bytes": 393293403,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "3474.261000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=P1A1yNsxMjc",
                "src": "https://youtu.be/P1A1yNsxMjc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-P1A1yNsxMjc.mp4",
                "bytes": 7744527,
                "valid": true,
                "height": 1080,
                "width": 1440,
                "duration": "100.041000",
                "reused": false
              }
            ],
            "body_markdown": "Professor Naftali Tishby passed away in 2021. Hope the post can introduce his cool idea of information bottleneck to more people.\nRecently I watched the talk\n“Information Theory in Deep Learning”\nby Prof Naftali Tishby and found it very interesting. He presented how to apply the information theory to study the growth and transformation of deep neural networks during training. Using the\nInformation Bottleneck (IB)\nmethod, he proposed a new learning bound for deep neural networks (DNN), as the traditional learning theory fails due to the exponentially large number of parameters. Another keen observation is that DNN training involves two distinct phases: First, the network is trained to fully represent the input data and minimize the generalization error; then, it learns to forget the irrelevant details by compressing the representation of the input.\nMost of the materials in this post are from Prof Tishby’s talk and\nrelated papers\n.\nBasic Concepts\n#\nMarkov Chain\nA Markov process is a\n“memoryless”\n(also called “Markov Property”) stochastic process. A Markov chain is a type of Markov process containing multiple discrete states. That is being said, the conditional probability of future states of the process is only determined by the current state and does not depend on the past states.\nKullback–Leibler (KL) Divergence\nKL divergence measures how one probability distribution $p$ diverges from a second expected probability distribution $q$. It is asymmetric.\n$$\n\\begin{aligned}\nD_{KL}(p \\| q) &= \\sum_x p(x) \\log \\frac{p(x)}{q(x)} \\\\\n &= - \\sum_x p(x)\\log q(x) + \\sum_x p(x)\\log p(x) \\\\\n &= H(P, Q) - H(P)\n\\end{aligned}\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nMutual Information\nMutual information measures the mutual dependence between two variables. It quantifies the “amount of information” obtained about one random variable through the other random variable. Mutual information is symmetric.\n$$\n\\begin{aligned}\nI(X;Y) &= D_{KL}[p(x,y) \\| p(x)p(y)] \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x, y)}{p(x)p(y)}) \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x|y)}{p(x)}) \\\\ \n &= H(X) - H(X|Y) \\\\\n\\end{aligned}\n$$\nData Processing Inequality (DPI)\nFor any markov chain: $X \\to Y \\to Z$, we would have $I(X; Y) \\geq I(X; Z)$.\nA deep neural network can be viewed as a Markov chain, and thus when we are moving down the layers of a DNN, the mutual information between the layer and the input can only decrease.\nReparametrization invariance\nFor two invertible functions $\\phi$, $\\psi$, the mutual information still holds: $I(X; Y) = I(\\phi(X); \\psi(Y))$.\nFor example, if we shuffle the weights in one layer of DNN, it would not affect the mutual information between this layer and another.\nDeep Neural Networks as Markov Chains\n#\nThe training data contains sampled observations from the joint distribution of $X$ and $Y$. The input variable $X$ and weights of hidden layers are all high-dimensional random variable. The ground truth target $Y$ and the predicted value $\\hat{Y}$ are random variables of smaller dimensions in the classification settings.\nThe structure of a deep neural network, which consists of the target label $Y$, input layer $X$, hidden layers $h\\_1, \\dots, h\\_m$ and the final prediction $\\hat{Y}$. (Image source:\nTishby and Zaslavsky, 2015\n)\nIf we label the hidden layers of a DNN as $h_1, h_2, \\dots, h_m$ as in Fig. 1, we can view each layer as one state of a Markov Chain: $ h_i \\to h_{i+1}$. According to DPI, we would have:\n$$\n\\begin{aligned}\nH(X) \\geq I(X; h_1) \\geq I(X; h_2) \\geq \\dots \\geq I(X; h_m) \\geq I(X; \\hat{Y}) \\\\\nI(X; Y) \\geq I(h_1; Y) \\geq I(h_2; Y) \\geq \\dots \\geq I(h_m; Y) \\geq I(\\hat{Y}; Y)\n\\end{aligned}\n$$\nA DNN is designed to learn how to describe $X$ to predict $Y$ and eventually, to compress $X$ to only hold the information related to $Y$. Tishby describes this processing as\n“successive refinement of relevant information”\n.\nInformation Plane Theorem\n#\nA DNN has successive internal representations of $X$, a set of hidden layers $\\{T_i\\}$. The\ninformation plane\ntheorem characterizes each layer by its encoder and decoder information. The encoder is a representation of the input data $X$, while the decoder translates the information in the current layer to the target ouput $Y$.\nPrecisely, in an information plane plot:\nX-axis\n: The sample complexity of $T_i$ is determined by the encoder mutual information $I(X; T_i)$. Sample complexity refers to how many samples you need to achieve certain accuracy and generalization.\nY-axis\n: The accuracy (generalization error) is determined by the decoder mutual information $I(T_i; Y)$.\nThe encoder vs decoder mutual information of DNN hidden layers of 50 experiments. Different layers are color-coders, with green being the layer right next to the input and the orange being the furthest. There are three snapshots, at the initial epoch, 400 epochs and 9000 epochs respectively. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nEach dot in marks the encoder/ decoder mutual information of one hidden layer of one network simulation (no regularization is applied; no weights decay, no dropout, etc.). They move up as expected because the knowledge about the true labels is increasing (accuracy increases). At the early stage, the hidden layers learn a lot about the input $X$, but later they start to compress to forget some information about the input. Tishby believes that\n“the most important part of learning is actually forgetting”\n. Check out this\nnice video\nthat demonstrates how the mutual information measures of layers are changing in epoch time.\nHere is an aggregated view of Fig 2. The compression happens after the generalization error becomes very small. (Image source:\nTishby’ talk 15:15\n)\nTwo Optimization Phases\n#\nTracking the normalized mean and standard deviation of each layer’s weights in time also reveals two optimization phases of the training process.\nThe norm of mean and standard deviation of each layer's weight gradients for each layer as a function of training epochs. Different layers are color-coded. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nAmong early epochs, the mean values are three magnitudes larger than the standard deviations. After a sufficient number of epochs, the error saturates and the standard deviations become much noisier afterward. The further a layer is away from the output, the noisier it gets, because the noises can get amplified and accumulated through the back-prop process (not due to the width of the layer).\nLearning Theory\n#\n“Old” Generalization Bounds\n#\nThe generalization bounds defined by the classic learning theory is:\n$$\n\\epsilon^2 < \\frac{\\log|H_\\epsilon| + \\log{1/\\delta}}{2m}\n$$\n$\\epsilon$: The difference between the training error and the generalization error. The generalization error measures how accurate the prediction of an algorithm is for previously unseen data.\n$H_\\epsilon$: $\\epsilon$-cover of the hypothesis class. Typically we assume the size $\\vert H_\\epsilon \\vert \\sim (1/\\epsilon)^d$.\n$\\delta$: Confidence.\n$m$: The number of training samples.\n$d$: The VC dimension of the hypothesis.\nThis definition states that the difference between the training error and the generalization error is bounded by a function of the hypothesis space size and the dataset size. The bigger the hypothesis space gets, the bigger the generalization error becomes. I recommend this tutorial on ML theory,\npart1\nand\npart2\n, if you are interested in reading more on generalization bounds.\nHowever, it does not work for deep learning. The larger a network is, the more parameters it needs to learn. With this generalization bounds, larger networks (larger $d$) would have worse bounds. This is contrary to the intuition that larger networks are able to achieve better performance with higher expressivity.\n“New” Input compression bound\n#\nTo solve this counterintuitive observation, Tishby et al. proposed a new input compression bound for DNN.\nFirst let us have $T_\\epsilon$ as an $\\epsilon$-partition of the input variable $X$. This partition compresses the input with respect to the homogeneity to the labels into small cells. The cells in total can cover the whole input space. If the prediction outputs binary values, we can replace the cardinality of the hypothesis, $\\vert H_\\epsilon \\vert$, with $2^{\\vert T_\\epsilon \\vert}$.\n$$\n|H_\\epsilon| \\sim 2^{|X|} \\to 2^{|T_\\epsilon|}\n$$\nWhen $X$ is large, the size of $X$ is approximately $2^{H(X)}$. Each cell in the $\\epsilon$-partition is of size $2^{H(X \\vert T_\\epsilon)}$. Therefore we have $\\vert T_\\epsilon \\vert \\sim \\frac{2^{H(X)}}{2^{H(X \\vert T_\\epsilon)}} = 2^{I(T_\\epsilon; X)}$. Then the input compression bound becomes:\n$$\n\\epsilon^2 < \\frac{2^{I(T_\\epsilon; X)} + \\log{1/\\delta}}{2m}\n$$\nThe black line is the optimal achievable information bottleneck (IB) limit. The red line corresponds to the upper bound on the out-of-sample IB distortion, when trained on a finite sample set. $\\Delta C$ is the complexity gap and $\\Delta G$ is the generalization gap. (Recreated based on\nTishby’ talk 24:50\n)\nNetwork Size and Training Data Size\n#\nThe Benefit of More Hidden Layers\n#\nHaving more layers give us computational benefits and speed up the training process for good generalization.\nThe optimization time is much shorter (fewer epochs) with more hidden layers. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCompression through stochastic relaxation\n: According to the\ndiffusion equation\n, the relaxation time of layer $k$ is proportional to the exponential of this layer’s compression amount $\\Delta S_k$: $\\Delta t_k \\sim \\exp(\\Delta S_k)$. We can compute the layer compression as $\\Delta S_k = I(X; T_k) - I(X; T_{k-1})$.  Because $\\exp(\\sum_k \\Delta S_k) \\geq \\sum_k \\exp(\\Delta S_k)$, we would expect an exponential decrease in training epochs with more hidden layers (larger $k$).\nThe Benefit of More Training Samples\n#\nFitting more training data requires more information captured by the hidden layers. With increased training data size, the decoder mutual information (recall that this is directly related to the generalization error), $I(T; Y)$, is pushed up and gets closer to the theoretical information bottleneck bound. Tishby emphasized that It is the mutual information, not the layer size or the VC dimension, that determines generalization, different from standard theories.\nThe training data of different sizes is color-coded. The information plane of multiple converged networks are plotted. More training data leads to better generalization. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCited as:\n@article{weng2017infotheory,\n  title   = \"Anatomize Deep Learning with Information Theory\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/\"\n}\nReferences\n#\n[1] Naftali Tishby.\nInformation Theory of Deep Learning\n[2]\nMachine Learning Theory - Part 1: Introduction\n[3]\nMachine Learning Theory - Part 2: Generalization Bounds\n[4]\nNew Theory Cracks Open the Black Box of Deep Learning\nby Quanta Magazine.\n[5] Naftali Tishby and Noga Zaslavsky.\n“Deep learning and the information bottleneck principle.”\nIEEE Information Theory Workshop (ITW), 2015.\n[6] Ravid Shwartz-Ziv and Naftali Tishby.\n“Opening the Black Box of Deep Neural Networks via Information.”\narXiv preprint arXiv:1703.00810, 2017.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:54Z",
            "title": "Anatomize Deep Learning with Information Theory | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/3cea57e75b80/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/physics/0004057.pdf",
                "bytes": 136267,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2bcb5c185f6c851f4943.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.02406.pdf",
                "bytes": 370205,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e3468aeea8ac86e9dd9c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00810.pdf",
                "bytes": 3921623,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d2cb5165e032151c7470.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 11409,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/3cea57e75b80/pages/source.html",
            "local_html": "attachments/3cea57e75b80/pages/article.html",
            "body_base_path": "attachments/3cea57e75b80/pages/",
            "body_markdown_path": "attachments/3cea57e75b80/pages/article.md",
            "links": [
              {
                "href": "https://youtu.be/bLqJHjXihK8",
                "label": "“Information Theory in Deep Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/physics/0004057.pdf",
                "label": "Information Bottleneck (IB)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "related papers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_chain",
                "label": "Markov Chain",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/Memoryless.html",
                "label": "“memoryless”",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback–Leibler (KL) Divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Mutual_information",
                "label": "Mutual Information",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Data_processing_inequality",
                "label": "Data Processing Inequality (DPI)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parametrization",
                "label": "Reparametrization invariance",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.02406.pdf",
                "label": "Tishby and Zaslavsky, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.00810.pdf",
                "label": "Shwartz-Ziv and Tishby, 2017",
                "type": "a"
              },
              {
                "href": "https://youtu.be/P1A1yNsxMjc",
                "label": "nice video",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=15m15s",
                "label": "Tishby’ talk 15:15",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt1/",
                "label": "part1",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt2/",
                "label": "part2",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=24m56s",
                "label": "Tishby’ talk 24:50",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Fokker%E2%80%93Planck_equation",
                "label": "diffusion equation",
                "type": "a"
              },
              {
                "href": "https://www.quantamagazine.org/new-theory-cracks-open-the-black-box-of-deep-learning-20170921/",
                "label": "New Theory Cracks Open the Black Box of Deep Learning",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
          "status": "partial",
          "article_id": "878201399682",
          "local_path": "series-follow/1602/repair/9bc8cee33939058ef446.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
              "bytes": 141343,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bb6875cd3e5549abbcd1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
              "bytes": 200906,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f63f468d5b6f609fb860.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
              "bytes": 320117,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b9e6a98b0df645854fba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
              "bytes": 393303,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d993cb03136583a0420d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
              "bytes": 299867,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/fc09fee591b88b9de59b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
              "bytes": 234229,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/87d8182dba34df99768a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
              "bytes": 153051,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/39271025b647a9d7c525.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
              "bytes": 969820,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/aaa694c2f42a8a7392e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
              "bytes": 281128,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/09d9fe883beab7d0f798.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
              "bytes": 263467,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/61258136fa6d92c338e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
              "bytes": 343247,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c5d63d539267ebf9a663.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
              "bytes": 131443,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4b9f5c7d78f642b4b125.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
              "bytes": 255209,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1feaf95f38447214362b.png"
            }
          ],
          "article": {
            "id": "878201399682",
            "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "bytes": 141343,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-bb6875cd3e5549abbcd1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "bytes": 200906,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-f63f468d5b6f609fb860.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "bytes": 320117,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-b9e6a98b0df645854fba.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "bytes": 393303,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-d993cb03136583a0420d.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "bytes": 299867,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-fc09fee591b88b9de59b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "bytes": 234229,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-87d8182dba34df99768a.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "bytes": 153051,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-39271025b647a9d7c525.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "bytes": 969820,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-aaa694c2f42a8a7392e9.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "bytes": 281128,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-09d9fe883beab7d0f798.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "bytes": 263467,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-61258136fa6d92c338e1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "bytes": 343247,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-c5d63d539267ebf9a663.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "bytes": 131443,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-4b9f5c7d78f642b4b125.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "bytes": 255209,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-1feaf95f38447214362b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Stochastic gradient descent is a universal choice for optimizing deep learning models. However, it is not the only option. With black-box optimization algorithms, you can evaluate a target function $f(x): \\mathbb{R}^n \\to \\mathbb{R}$, even when you don’t know the precise analytic form of $f(x)$ and thus cannot compute gradients or the Hessian matrix. Examples of black-box optimization methods include\nSimulated Annealing\n,\nHill Climbing\nand\nNelder-Mead method\n.\nEvolution Strategies (ES)\nis one type of black-box optimization algorithms, born in the family of\nEvolutionary Algorithms (EA)\n. In this post, I would dive into a couple of classic ES methods and introduce a few applications of how ES can play a role in deep reinforcement learning.\nWhat are Evolution Strategies?\n#\nEvolution strategies (ES) belong to the big family of evolutionary algorithms. The optimization targets of ES are vectors of real numbers, $x \\in \\mathbb{R}^n$.\nEvolutionary algorithms refer to a division of population-based optimization algorithms inspired by\nnatural selection\n. Natural selection believes that individuals with traits beneficial to their survival can live through generations and pass down the good characteristics to the next generation. Evolution happens by the selection process gradually and the population grows better adapted to the environment.\nHow natural selection works. (Image source: Khan Academy:\nDarwin, evolution, & natural selection\n)\nEvolutionary algorithms can be summarized in the following\nformat\nas a general optimization solution:\nLet’s say we want to optimize a function $f(x)$ and we are not able to compute gradients directly. But we still can evaluate $f(x)$ given any $x$ and the result is deterministic. Our belief in the probability distribution over $x$ as a good solution to $f(x)$ optimization is $p_\\theta(x)$, parameterized by $\\theta$. The goal is to find an optimal configuration of $\\theta$.\nHere given a fixed format of distribution (i.e. Gaussian), the parameter $\\theta$ carries  the knowledge about the best solutions and is being iteratively updated across generations.\nStarting with an initial value of $\\theta$, we can continuously update $\\theta$ by looping three steps as follows:\nGenerate a population of samples $D = \\{(x_i, f(x_i)\\}$ where $x_i \\sim p_\\theta(x)$.\nEvaluate the “fitness” of samples in $D$.\nSelect the best subset of individuals and use them to update $\\theta$, generally based on fitness or rank.\nIn\nGenetic Algorithms (GA)\n, another popular subcategory of EA, $x$ is a sequence of binary codes, $x \\in \\{0, 1\\}^n$. While in ES, $x$ is just a vector of real numbers, $x \\in \\mathbb{R}^n$.\nSimple Gaussian Evolution Strategies\n#\nThis\nis the most basic and canonical version of evolution strategies. It models $p_\\theta(x)$ as a $n$-dimensional isotropic Gaussian distribution, in which $\\theta$ only tracks the mean $\\mu$ and standard deviation $\\sigma$.\n$$\n\\theta = (\\mu, \\sigma),\\;p_\\theta(x) \\sim \\mathcal{N}(\\mathbf{\\mu}, \\sigma^2 I) = \\mu + \\sigma \\mathcal{N}(0, I)\n$$\nThe process of Simple-Gaussian-ES, given $x \\in \\mathcal{R}^n$:\nInitialize $\\theta = \\theta^{(0)}$ and the generation counter $t=0$\nGenerate the offspring population of size $\\Lambda$ by sampling from the Gaussian distribution:\n$D^{(t+1)}=\\{ x^{(t+1)}_i \\mid x^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{ where } y^{(t+1)}_i \\sim \\mathcal{N}(x \\vert 0, \\mathbf{I}),;i = 1, \\dots, \\Lambda\\}$\n.\nSelect a top subset of $\\lambda$ samples with optimal $f(x_i)$ and this subset is called\nelite\nset. Without loss of generality, we may consider the first $k$ samples in $D^{(t+1)}$ to belong to the elite group — Let’s label them as\n$$\n  D^{(t+1)}\\_\\text{elite} = \\\\{x^{(t+1)}\\_i \\mid x^{(t+1)}\\_i \\in D^{(t+1)}, i=1,\\dots, \\lambda, \\lambda\\leq \\Lambda\\\\}\n  $$\nThen we estimate the new mean and std for the next generation using the elite set:\n$$\n  \\begin{aligned}\n  \\mu^{(t+1)} &= \\text{avg}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda x_i^{(t+1)} \\\\\n  {\\sigma^{(t+1)}}^2 &= \\text{var}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} -\\mu^{(t)})^2\n  \\end{aligned}\n  $$\nRepeat steps (2)-(4) until the result is good enough ✌️\nCovariance Matrix Adaptation Evolution Strategies (CMA-ES)\n#\nThe standard deviation $\\sigma$ accounts for the level of exploration: the larger $\\sigma$ the bigger search space we can sample our offspring population. In\nvanilla ES\n, $\\sigma^{(t+1)}$ is highly correlated with $\\sigma^{(t)}$, so the algorithm is not able to rapidly adjust the exploration space when needed (i.e. when the confidence level changes).\nCMA-ES\n, short for\n“Covariance Matrix Adaptation Evolution Strategy”\n, fixes the problem by tracking pairwise dependencies between the samples in the distribution with a covariance matrix $C$. The new distribution parameter becomes:\n$$\n\\theta = (\\mu, \\sigma, C),\\; p_\\theta(x) \\sim \\mathcal{N}(\\mu, \\sigma^2 C) \\sim \\mu + \\sigma \\mathcal{N}(0, C)\n$$\nwhere $\\sigma$ controls for the overall scale of the distribution,  often known as\nstep size\n.\nBefore we dig into how the parameters are updated in CMA-ES, it is better to review how the covariance matrix works in the multivariate Gaussian distribution first. As a real symmetric matrix, the covariance matrix $C$ has the following nice features (See\nproof\n&\nproof\n):\nIt is always diagonalizable.\nAlways positive semi-definite.\nAll of its eigenvalues are real non-negative numbers.\nAll of its eigenvectors are orthogonal.\nThere is an orthonormal basis of $\\mathbb{R}^n$ consisting of its eigenvectors.\nLet the matrix $C$ have an\northonormal\nbasis of eigenvectors $B = [b_1, \\dots, b_n]$, with corresponding eigenvalues $\\lambda_1^2, \\dots, \\lambda_n^2$. Let $D=\\text{diag}(\\lambda_1, \\dots, \\lambda_n)$.\n$$\nC = B^\\top D^2 B\n= \\begin{bmatrix} \n\\mid & \\mid &  & \\mid \\\\\nb_1 & b_2 & \\dots & b_n\\\\\n\\mid & \\mid &  & \\mid \\\\\n\\end{bmatrix}\n\\begin{bmatrix}\n\\lambda_1^2 & 0 & \\dots & 0 \\\\\n0 & \\lambda_2^2 & \\dots & 0 \\\\\n\\vdots & \\dots & \\ddots & \\vdots \\\\\n0 & \\dots & 0 & \\lambda_n^2\n\\end{bmatrix}\n\\begin{bmatrix} \n- & b_1 & - \\\\\n- & b_2 & - \\\\\n  & \\dots & \\\\\n- & b_n & - \\\\\n\\end{bmatrix}\n$$\nThe square root of $C$ is:\n$$\nC^{\\frac{1}{2}} = B^\\top D B\n$$\nSymbol\nMeaning\n$x_i^{(t)} \\in \\mathbb{R}^n$\nthe $i$-th samples at the generation (t)\n$y_i^{(t)} \\in \\mathbb{R}^n$\n$x_i^{(t)} = \\mu^{(t-1)} + \\sigma^{(t-1)} y_i^{(t)} $\n$\\mu^{(t)}$\nmean of the generation (t)\n$\\sigma^{(t)}$\nstep size\n$C^{(t)}$\ncovariance matrix\n$B^{(t)}$\na matrix of $C$’s eigenvectors as row vectors\n$D^{(t)}$\na diagonal matrix with $C$’s eigenvalues on the diagnose.\n$p_\\sigma^{(t)}$\nevaluation path for $\\sigma$ at the generation (t)\n$p_c^{(t)}$\nevaluation path for $C$ at the generation (t)\n$\\alpha_\\mu$\nlearning rate for $\\mu$’s update\n$\\alpha_\\sigma$\nlearning rate for $p_\\sigma$\n$d_\\sigma$\ndamping factor for $\\sigma$’s update\n$\\alpha_{cp}$\nlearning rate for $p_c$\n$\\alpha_{c\\lambda}$\nlearning rate for $C$’s rank-min(λ, n) update\n$\\alpha_{c1}$\nlearning rate for $C$’s rank-1 update\nUpdating the Mean\n#\n$$\n\\mu^{(t+1)} = \\mu^{(t)} + \\alpha_\\mu \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})\n$$\nCMA-ES has a learning rate $\\alpha_\\mu \\leq 1$ to control how fast the mean $\\mu$ should be updated.  Usually it is set to 1 and thus the equation becomes the same as in vanilla ES, $\\mu^{(t+1)} = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)}$.\nControlling the Step Size\n#\nThe sampling process can be decoupled from the mean and standard deviation:\n$$\nx^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{, where } y^{(t+1)}_i = \\frac{x_i^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)\n$$\nThe parameter $\\sigma$ controls the overall scale of the distribution. It is separated from the covariance matrix so that we can change steps faster than the full covariance. A larger step size leads to faster parameter update. In order to evaluate whether the current step size is proper, CMA-ES constructs an\nevolution path\n$p_\\sigma$ by summing up a consecutive sequence of moving steps, $\\frac{1}{\\lambda}\\sum_{i}^\\lambda y_i^{(j)}, j=1, \\dots, t$. By comparing this path length with its expected length under random selection (meaning single steps are uncorrelated), we are able to adjust $\\sigma$ accordingly (See Fig. 2).\nThree scenarios of how single steps are correlated in different ways and their impacts on step size update. (Image source: additional annotations on Fig 5 in\nCMA-ES tutorial\npaper)\nEach time the evolution path is updated with the average of moving step $y_i$ in the same generation.\n$$\n\\begin{aligned}\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n= \\frac{1}{\\lambda} \\frac{\\sum_{i=1}^\\lambda x_i^{(t+1)} - \\lambda \\mu^{(t)}}{\\sigma^{(t)}}\n= \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n\\sim \\frac{1}{\\lambda}\\mathcal{N}(0, \\lambda C^{(t)}) \n\\sim \\frac{1}{\\sqrt{\\lambda}}{C^{(t)}}^{\\frac{1}{2}}\\mathcal{N}(0, I) \\\\\n&\\text{Thus } \\sqrt{\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nBy multiplying with $C^{-\\frac{1}{2}}$, the evolution path is transformed to be independent of its direction. The term ${C^{(t)}}^{-\\frac{1}{2}} = {B^{(t)}}^\\top {D^{(t)}}^{-\\frac{1}{2}} {B^{(t)}}$ transformation works as follows:\n${B^{(t)}}$ contains row vectors of $C$’s eigenvectors. It projects the original space onto the perpendicular principal axes.\nThen ${D^{(t)}}^{-\\frac{1}{2}} = \\text{diag}(\\frac{1}{\\lambda_1}, \\dots, \\frac{1}{\\lambda_n})$ scales the length of principal axes to be equal.\n${B^{(t)}}^\\top$ transforms the space back to the original coordinate system.\nIn order to assign higher weights to recent generations, we use polyak averaging to update the evolution path with learning rate $\\alpha_\\sigma$. Meanwhile, the weights are balanced so that $p_\\sigma$ is\nconjugate\n, $\\sim \\mathcal{N}(0, I)$ both before and after one update.\n$$\n\\begin{aligned}\np_\\sigma^{(t+1)} \n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{1 - (1 - \\alpha_\\sigma)^2}\\;\\sqrt{\\lambda}\\; {C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{c_\\sigma (2 - \\alpha_\\sigma)\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThe expected length of $p_\\sigma$ under random selection is $\\mathbb{E}|\\mathcal{N}(0,I)|$, that is the expectation of the L2-norm of a $\\mathcal{N}(0,I)$ random variable. Following the idea in Fig. 2, we adjust the step size according to the ratio of $|p_\\sigma^{(t+1)}| / \\mathbb{E}|\\mathcal{N}(0,I)|$:\n$$\n\\begin{aligned}\n\\ln\\sigma^{(t+1)} &= \\ln\\sigma^{(t)} + \\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big) \\\\\n\\sigma^{(t+1)} &= \\sigma^{(t)} \\exp\\Big(\\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big)\\Big)\n\\end{aligned}\n$$\nwhere $d_\\sigma \\approx 1$ is a damping parameter, scaling how fast $\\ln\\sigma$ should be changed.\nAdapting the Covariance Matrix\n#\nFor the covariance matrix, it can be estimated from scratch using $y_i$ of elite samples (recall that $y_i \\sim \\mathcal{N}(0, C)$):\n$$\nC_\\lambda^{(t+1)} \n= \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n= \\frac{1}{\\lambda {\\sigma^{(t)}}^2} \\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})(x_i^{(t+1)} - \\mu^{(t)})^\\top\n$$\nThe above estimation is only reliable when the selected population is large enough. However, we do want to run\nfast\niteration with a\nsmall\npopulation of samples in each generation. That’s why CMA-ES invented a more reliable but also more complicated way to update $C$. It involves two independent routes,\nRank-min(λ, n) update\n: uses the history of $\\{C_\\lambda\\}$, each estimated from scratch in one generation.\nRank-one update\n: estimates the moving steps $y_i$ and the sign information from the history.\nThe first route considers the estimation of $C$ from the entire history of $\\{C_\\lambda\\}$. For example, if we have experienced a large number of generations, $C^{(t+1)} \\approx \\text{avg}(C_\\lambda^{(i)}; i=1,\\dots,t)$ would be a good estimator. Similar to $p_\\sigma$, we also use polyak averaging with a learning rate to incorporate the history:\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} C_\\lambda^{(t+1)}\n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n$$\nA common choice for the learning rate is $\\alpha_{c\\lambda} \\approx \\min(1, \\lambda/n^2)$.\nThe second route tries to solve the issue that $y_i{y_i}^\\top = (-y_i)(-y_i)^\\top$ loses the sign information. Similar to how we adjust the step size $\\sigma$, an evolution path $p_c$ is used to track the sign information and it is constructed in a way that $p_c$ is conjugate, $\\sim \\mathcal{N}(0, C)$ both before and after a new generation.\nWe may consider $p_c$ as another way to compute $\\text{avg}_i(y_i)$ (notice that both $\\sim \\mathcal{N}(0, C)$) while the entire history is used and the sign information is maintained. Note that we’ve known $\\sqrt{k}\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)$ in the\nlast section\n,\n$$\n\\begin{aligned}\np_c^{(t+1)} \n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{1 - (1-\\alpha_{cp})^2}\\;\\sqrt{\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{\\alpha_{cp}(2 - \\alpha_{cp})\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThen the covariance matrix is updated according to $p_c$:\n$$\nC^{(t+1)} = (1-\\alpha_{c1}) C^{(t)} + \\alpha_{c1}\\;p_c^{(t+1)} {p_c^{(t+1)}}^\\top\n$$\nThe\nrank-one update\napproach is claimed to generate a significant improvement over the\nrank-min(λ, n)-update\nwhen $k$ is small, because the signs of moving steps and correlations between consecutive steps are all utilized and passed down through generations.\nEventually we combine two approaches together,\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda} - \\alpha_{c1}) C^{(t)}\n+ \\alpha_{c1}\\;\\underbrace{p_c^{(t+1)} {p_c^{(t+1)}}^\\top}_\\textrm{rank-one update}\n+ \\alpha_{c\\lambda} \\underbrace{\\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top}_\\textrm{rank-min(lambda, n) update}\n$$\nIn all my examples above, each elite sample is considered to contribute an equal amount of weights, $1/\\lambda$. The process can be easily extended to the case where selected samples are assigned with different weights, $w_1, \\dots, w_\\lambda$, according to their performances. See more detail in\ntutorial\n.\nIllustration of how CMA-ES works on a 2D optimization problem (the lighter color the better). Black dots are samples in one generation. The samples are more spread out initially but when the model has higher confidence in finding a good solution in the late stage, the samples become very concentrated over the global optimum. (Image source:\nWikipedia CMA-ES\n)\nNatural Evolution Strategies\n#\nNatural Evolution Strategies (\nNES\n;\nWierstra, et al, 2008\n) optimizes in a search distribution of parameters and moves the distribution in the direction of high fitness indicated by the\nnatural gradient\n.\nNatural Gradients\n#\nGiven an objective function $\\mathcal{J}(\\theta)$ parameterized by $\\theta$, let’s say our goal is to find the optimal $\\theta$ to maximize the objective function value. A\nplain gradient\nfinds the steepest direction within a small Euclidean distance from the current $\\theta$; the distance restriction is applied on the parameter space. In other words, we compute the plain gradient with respect to a small change of the absolute value of $\\theta$. The optimal step is:\n$$\nd^{*} = \\operatorname*{argmax}_{\\|d\\| = \\epsilon} \\mathcal{J}(\\theta + d)\\text{, where }\\epsilon \\to 0\n$$\nDifferently,\nnatural gradient\nworks with a probability\ndistribution\nspace\nparameterized by $\\theta$, $p_\\theta(x)$ (referred to as “search distribution” in NES\npaper\n). It looks for the steepest direction within a small step in the distribution space where the distance is measured by KL divergence. With this constraint we ensure that each update is moving along the distributional manifold with constant speed, without being slowed down by its curvature.\n$$\nd^{*}_\\text{N} = \\operatorname*{argmax}_{\\text{KL}[p_\\theta \\| p_{\\theta+d}] = \\epsilon} \\mathcal{J}(\\theta + d)\n$$\nEstimation using Fisher Information Matrix\n#\nBut, how to compute $\\text{KL}[p_\\theta | p_{\\theta+\\Delta\\theta}]$ precisely? By running Taylor expansion of $\\log p_{\\theta + d}$ at $\\theta$, we get:\n$$\n\\begin{aligned}\n& \\text{KL}[p_\\theta \\| p_{\\theta+d}] \\\\\n&= \\mathbb{E}_{x \\sim p_\\theta} [\\log p_\\theta(x) - \\log p_{\\theta+d}(x)] & \\\\\n&\\approx \\mathbb{E}_{x \\sim p_\\theta} [ \\log p_\\theta(x) -( \\log p_{\\theta}(x) + \\nabla_\\theta \\log p_{\\theta}(x) d + \\frac{1}{2}d^\\top \\nabla^2_\\theta \\log p_{\\theta}(x) d)] & \\scriptstyle{\\text{; Taylor expand }\\log p_{\\theta+d}} \\\\\n&\\approx - \\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}(x)] d - \\frac{1}{2}d^\\top \\mathbb{E}_x [\\nabla^2_\\theta \\log p_{\\theta}(x)] d & \n\\end{aligned}\n$$\nwhere\n$$\n\\begin{aligned}\n\\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}] d \n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) & \\\\\n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\frac{1}{p_\\theta(x)} \\nabla_\\theta p_\\theta(x) & \\\\\n&= \\nabla_\\theta \\Big( \\int_{x} p_\\theta(x) \\Big) & \\scriptstyle{\\textrm{; note that }p_\\theta(x)\\textrm{ is probability distribution.}} \\\\\n&= \\nabla_\\theta (1) = 0\n\\end{aligned}\n$$\nFinally we have,\n$$\n\\text{KL}[p_\\theta \\| p_{\\theta+d}] = - \\frac{1}{2}d^\\top \\mathbf{F}_\\theta d \n\\text{, where }\\mathbf{F}_\\theta = \\mathbb{E}_x [(\\nabla_\\theta \\log p_{\\theta}) (\\nabla_\\theta \\log p_{\\theta})^\\top]\n$$\nwhere $\\mathbf{F}_\\theta$ is called the\nFisher Information Matrix\nand\nit is\nthe covariance matrix of $\\nabla_\\theta \\log p_\\theta$ since $\\mathbb{E}[\\nabla_\\theta \\log p_\\theta] = 0$.\nThe solution to the following optimization problem:\n$$\n\\max \\mathcal{J}(\\theta + d) \\approx \\max \\big( \\mathcal{J}(\\theta) + {\\nabla_\\theta\\mathcal{J}(\\theta)}^\\top d \\big)\\;\\text{ s.t. }\\text{KL}[p_\\theta \\| p_{\\theta+d}] - \\epsilon = 0\n$$\ncan be found using a Lagrangian multiplier,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta, d, \\beta) &= \\mathcal{J}(\\theta) + \\nabla_\\theta\\mathcal{J}(\\theta)^\\top d - \\beta (\\frac{1}{2}d^\\top \\mathbf{F}_\\theta d + \\epsilon) = 0 \\text{ s.t. } \\beta > 0 \\\\\n\\nabla_d \\mathcal{L}(\\theta, d, \\beta) &= \\nabla_\\theta\\mathcal{J}(\\theta) - \\beta\\mathbf{F}_\\theta d = 0 \\\\\n\\text{Thus } d_\\text{N}^* &= \\nabla_\\theta^\\text{N} \\mathcal{J}(\\theta) = \\mathbf{F}_\\theta^{-1} \\nabla_\\theta\\mathcal{J}(\\theta) \n\\end{aligned}\n$$\nwhere $d_\\text{N}^*$ only extracts the direction of the optimal moving step on $\\theta$, ignoring the scalar $\\beta^{-1}$.\nThe natural gradient samples (black solid arrows) in the right are the plain gradient samples (black solid arrows)  in the left multiplied by the inverse of their covariance. In this way, a gradient direction with high uncertainty (indicated by high covariance with other samples) are penalized with a small weight. The aggregated natural gradient (red dash arrow) is therefore more trustworthy than the natural gradient (green solid arrow). (Image source: additional annotations on Fig 2 in\nNES\npaper)\nNES Algorithm\n#\nThe fitness associated with one sample is labeled as $f(x)$ and the search distribution over $x$ is parameterized by $\\theta$. NES is expected to optimize the parameter $\\theta$ to achieve maximum expected fitness:\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{x\\sim p_\\theta(x)} [f(x)] = \\int_x f(x) p_\\theta(x) dx\n$$\nUsing the same log-likelihood\ntrick\nin\nREINFORCE\n:\n$$\n\\begin{aligned}\n\\nabla_\\theta\\mathcal{J}(\\theta) \n&= \\nabla_\\theta \\int_x f(x) p_\\theta(x) dx \\\\\n&= \\int_x f(x) \\frac{p_\\theta(x)}{p_\\theta(x)}\\nabla_\\theta p_\\theta(x) dx \\\\\n& = \\int_x f(x) p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) dx \\\\\n& = \\mathbb{E}_{x \\sim p_\\theta} [f(x) \\nabla_\\theta \\log p_\\theta(x)]\n\\end{aligned}\n$$\nBesides natural gradients, NES adopts a couple of important heuristics to make the algorithm performance more robust.\nNES applies\nrank-based fitness shaping\n, that is to use the\nrank\nunder monotonically increasing fitness values instead of using $f(x)$ directly. Or it can be a function of the rank (“utility function”), which is considered as a free parameter of NES.\nNES adopts\nadaptation sampling\nto adjust hyperparameters at run time. When changing $\\theta \\to \\theta’$, samples drawn from $p_\\theta$ are compared with samples from $p_{\\theta’}$ using [Mann-Whitney U-test(https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test)]; if there shows a positive or negative sign, the target hyperparameter decreases or increases by a multiplication constant. Note the score of a sample $x’_i \\sim p_{\\theta’}(x)$ has importance sampling weights applied $w_i’ = p_\\theta(x) / p_{\\theta’}(x)$.\nApplications: ES in Deep Reinforcement Learning\n#\nOpenAI ES for RL\n#\nThe concept of using evolutionary algorithms in reinforcement learning can be traced back\nlong ago\n, but only constrained to tabular RL due to computational limitations.\nInspired by\nNES\n, researchers at OpenAI (\nSalimans, et al. 2017\n) proposed to use NES as a gradient-free black-box optimizer to find optimal policy parameters $\\theta$ that maximizes the return function $F(\\theta)$. The key is to add Gaussian noise $\\epsilon$ on the model parameter $\\theta$ and then use the log-likelihood trick to write it as the gradient of the Gaussian pdf. Eventually only the noise term is left as a weighting scalar for measured performance.\nLet’s say the current parameter value is $\\hat{\\theta}$ (the added hat is to distinguish the value from the random variable $\\theta$). The search distribution of $\\theta$ is designed to be an isotropic multivariate Gaussian with a mean $\\hat{\\theta}$ and a fixed covariance matrix $\\sigma^2 I$,\n$$\n\\theta \\sim \\mathcal{N}(\\hat{\\theta}, \\sigma^2 I) \\text{ equivalent to } \\theta = \\hat{\\theta} + \\sigma\\epsilon, \\epsilon \\sim \\mathcal{N}(0, I)\n$$\nThe gradient for $\\theta$ update is:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} F(\\theta) \\\\\n&= \\nabla_\\theta \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} F(\\hat{\\theta} + \\sigma\\epsilon) \\\\\n&= \\nabla_\\theta \\int_{\\epsilon} p(\\epsilon) F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; Gaussian }p(\\epsilon)=(2\\pi)^{-\\frac{n}{2}} \\exp(-\\frac{1}{2}\\epsilon^\\top\\epsilon)} \\\\\n&= \\int_{\\epsilon} p(\\epsilon) \\nabla_\\epsilon \\log p(\\epsilon) \\nabla_\\theta \\epsilon\\;F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; log-likelihood trick}}\\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\nabla_\\epsilon \\big(-\\frac{1}{2}\\epsilon^\\top\\epsilon\\big) \\nabla_\\theta \\big(\\frac{\\theta - \\hat{\\theta}}{\\sigma}\\big) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ (-\\epsilon) (\\frac{1}{\\sigma}) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\scriptstyle{\\text{; negative sign can be absorbed.}}\n\\end{aligned}\n$$\nIn one generation, we can sample many $epsilon_i, i=1,\\dots,n$ and evaluate the fitness\nin parallel\n. One beautiful design is that no large model parameter needs to be shared. By only communicating the random seeds between workers, it is enough for the master node to do parameter update. This approach is later extended to adaptively learn a loss function; see my previous post on\nEvolved Policy Gradient\n.\nThe algorithm for training a RL policy using evolution strategies. (Image source:\nES-for-RL\npaper)\nTo make the performance more robust, OpenAI ES adopts virtual batch normalization (BN with mini-batch used for calculating statistics fixed), mirror sampling (sampling a pair of $(-\\epsilon, \\epsilon)$ for evaluation), and\nfitness shaping\n.\nExploration with ES\n#\nExploration (\nvs exploitation\n) is an important topic in RL. The optimization direction in the ES algorithm\nabove\nis only extracted from the cumulative return $F(\\theta)$. Without explicit exploration, the agent might get trapped in a local optimum.\nNovelty-Search ES (\nNS-ES\n;\nConti et al, 2018\n) encourages exploration by updating the parameter in the direction to maximize the\nnovelty\nscore. The novelty score depends on a domain-specific behavior characterization function $b(\\pi_\\theta)$. The choice of $b(\\pi_\\theta)$ is specific to the task and seems to be a bit arbitrary; for example, in the Humanoid locomotion task in the paper, $b(\\pi_\\theta)$ is the final $(x,y)$ location of the agent.\nEvery policy’s $b(\\pi_\\theta)$ is pushed to an archive set $\\mathcal{A}$.\nNovelty of a policy $\\pi_\\theta$ is measured as the k-nearest neighbor score between $b(\\pi_\\theta)$ and all other entries in $\\mathcal{A}$.\n(The use case of the archive set sounds quite similar to\nepisodic memory\n.)\n$$\nN(\\theta, \\mathcal{A}) = \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda \\| b(\\pi_\\theta), b^\\text{knn}_i \\|_2\n\\text{, where }b^\\text{knn}_i \\in \\text{kNN}(b(\\pi_\\theta), \\mathcal{A})\n$$\nThe ES optimization step relies on the novelty score instead of fitness:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} N(\\theta, \\mathcal{A})\n= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon N(\\hat{\\theta} + \\sigma\\epsilon, \\mathcal{A}) ]\n$$\nNS-ES maintains a group of $M$ independently trained agents (“meta-population”), $\\mathcal{M} = \\{\\theta_1, \\dots, \\theta_M \\}$ and picks one to advance proportional to the novelty score. Eventually we select the best policy. This process is equivalent to ensembling; also see the same idea in\nSVPG\n.\n$$\n\\begin{aligned}\nm &\\leftarrow \\text{pick } i=1,\\dots,M\\text{ according to probability}\\frac{N(\\theta_i, \\mathcal{A})}{\\sum_{j=1}^M N(\\theta_j, \\mathcal{A})} \\\\\n\\theta_m^{(t+1)} &\\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) \\text{ where }\\epsilon_i \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nwhere $N$ is the number of Gaussian perturbation noise vectors and $\\alpha$ is the learning rate.\nNS-ES completely discards the reward function and only optimizes for novelty to avoid deceptive local optima. To incorporate the fitness back into the formula, another two variations are proposed.\nNSR-ES\n:\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\frac{N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + F(\\theta^{(t)}_m + \\epsilon_i)}{2}\n$$\nNSRAdapt-ES (NSRA-ES)\n: the adaptive weighting parameter $w = 1.0$ initially. We start decreasing $w$ if performance stays flat for a number of generations. Then when the performance starts to increase, we stop decreasing $w$ but increase it instead. In this way, fitness is preferred when the performance stops growing but novelty is preferred otherwise.\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\big((1-w) N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + w F(\\theta^{(t)}_m + \\epsilon_i)\\big)\n$$\n(Left) The environment is Humanoid locomotion with a three-sided wall which plays a role as a deceptive trap to create local optimum. (Right) Experiments compare ES baseline and other variations that encourage exploration. (Image source:\nNS-ES\npaper)\nCEM-RL\n#\nArchitectures of the (a) CEM-RL and (b)\nERL\nalgorithms (Image source:\nCEM-RL\npaper)\nThe CEM-RL method (\nPourchot & Sigaud, 2019\n) combines Cross Entropy Method (CEM) with either\nDDPG\nor\nTD3\n. CEM here works pretty much the same as the simple Gaussian ES described\nabove\nand therefore the same function can be replaced using CMA-ES. CEM-RL is built on the framework of\nEvolutionary Reinforcement Learning\n(\nERL\n;\nKhadka & Tumer, 2018\n) in which the standard EA algorithm selects and evolves a population of actors and the rollout experience generated in the process is then added into reply buffer for training both RL-actor and RL-critic networks.\nWorkflow:\nThe mean actor of the CEM population is $\\pi_\\mu$ is initialized with a random actor network.\nThe critic network $Q$ is initialized too, which will be updated by DDPG/TD3.\nRepeat until happy:\na. Sample a population of actors $\\sim \\mathcal{N}(\\pi_\\mu, \\Sigma)$.\nb. Half of the population is evaluated. Their fitness scores are used as the cumulative reward $R$ and added into replay buffer.\nc. The other half are updated together with the critic.\nd. The new $\\pi_mu$ and $\\Sigma$ is computed using top performing elite samples.\nCMA-ES\ncan be used for parameter update too.\nExtension: EA in Deep Learning\n#\n(This section is not on evolution strategies, but still an interesting and relevant reading.)\nThe\nEvolutionary Algorithms\nhave been applied on many deep learning problems. POET (\nWang et al, 2019\n) is a framework based on EA and attempts to generate a variety of different tasks while the problems themselves are being solved. POET has been introduced in my\nlast post\non meta-RL. Evolutionary Reinforcement Learning (ERL) is another example; See Fig. 7 (b).\nBelow I would like to introduce two applications in more detail,\nPopulation-Based Training (PBT)\nand\nWeight-Agnostic Neural Networks (WANN)\n.\nHyperparameter Tuning: PBT\n#\nParadigms of comparing different ways of hyperparameter tuning. (Image source:\nPBT\npaper)\nPopulation-Based Training (\nJaderberg, et al, 2017\n), short for\nPBT\napplies EA on the problem of hyperparameter tuning. It jointly trains a population of models and corresponding hyperparameters for optimal performance.\nPBT starts with a set of random candidates, each containing a pair of model weights initialization and hyperparameters, $\\{(\\theta_i, h_i)\\mid i=1, \\dots, N\\}$. Every sample is trained in parallel and asynchronously evaluates its own performance periodically. Whenever a member deems ready (i.e. after taking enough gradient update steps, or when the performance is good enough), it has a chance to be updated by comparing with the whole population:\nexploit()\n: When this model is under-performing, the weights could be replaced with a better performing model.\nexplore()\n: If the model weights are overwritten,\nexplore\nstep perturbs the hyperparameters with random noise.\nIn this process, only promising model and hyperparameter pairs can survive and keep on evolving, achieving better utilization of computational resources.\nThe algorithm of population-based training. (Image source:\nPBT\npaper)\nNetwork Topology Optimization: WANN\n#\nWeight Agnostic Neural\nNetworks (short for\nWANN\n;\nGaier & Ha 2019\n) experiments with searching for the smallest network topologies that can achieve the optimal performance without training the network weights. By not considering the best configuration of network weights, WANN puts much more emphasis on the architecture itself, making the focus different from\nNAS\n. WANN is heavily inspired by a classic genetic algorithm to evolve network topologies, called\nNEAT\n(“Neuroevolution of Augmenting Topologies”;\nStanley & Miikkulainen 2002\n).\nThe workflow of WANN looks pretty much the same as standard GA:\nInitialize: Create a population of minimal networks.\nEvaluation: Test with a range of\nshared\nweight values.\nRank and Selection: Rank by performance and complexity.\nMutation: Create new population by varying best networks.\nmutation operations for searching for new network topologies in WANN (Image source:\nWANN\npaper)\nAt the “evaluation” stage, all the network weights are set to be the same. In this way, WANN is actually searching for network that can be described with a minimal description length. In the “selection” stage, both the network connection and the model performance are considered.\nPerformance of WANN found network topologies on different RL tasks are compared with baseline FF networks commonly used in the literature. \"Tuned Shared Weight\" only requires adjusting one weight value. (Image source:\nWANN\npaper)\nAs shown in Fig. 11, WANN results are evaluated with both random weights and shared weights (single weight). It is interesting that even when enforcing weight-sharing on all weights and tuning this single parameter, WANN can discover topologies that achieve non-trivial good performance.\nCited as:\n@article{weng2019ES,\n  title   = \"Evolution Strategies\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/\"\n}\nReferences\n#\n[1] Nikolaus Hansen.\n“The CMA Evolution Strategy: A Tutorial”\narXiv preprint arXiv:1604.00772 (2016).\n[2] Marc Toussaint.\nSlides: “Introduction to Optimization”\n[3] David Ha.\n“A Visual Guide to Evolution Strategies”\nblog.otoro.net. Oct 2017.\n[4] Daan Wierstra, et al.\n“Natural evolution strategies.”\nIEEE World Congress on Computational Intelligence, 2008.\n[5] Agustinus Kristiadi.\n“Natural Gradient Descent”\nMar 2018.\n[6] Razvan Pascanu & Yoshua Bengio.\n“Revisiting Natural Gradient for Deep Networks.”\narXiv preprint arXiv:1301.3584 (2013).\n[7] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[8] Edoardo Conti, et al.\n“Improving exploration in evolution strategies for deep reinforcement learning via a population of novelty-seeking agents.”\nNIPS. 2018.\n[9] Aloïs Pourchot & Olivier Sigaud.\n“CEM-RL: Combining evolutionary and gradient-based methods for policy search.”\nICLR 2019.\n[10] Shauharda Khadka & Kagan Tumer.\n“Evolution-guided policy gradient in reinforcement learning.”\nNIPS 2018.\n[11] Max Jaderberg, et al.\n“Population based training of neural networks.”\narXiv preprint arXiv:1711.09846 (2017).\n[12] Adam Gaier & David Ha.\n“Weight Agnostic Neural Networks.”\narXiv preprint arXiv:1906.04358 (2019).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:55Z",
            "title": "Evolution Strategies | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/878201399682/code/body-000.txt",
                "chars": 225,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "retried_at": "2026-10-20T17:50:44Z"
              },
              {
                "status": "ok",
                "url": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "bytes": 88049,
                "reused": true,
                "local_path": "papers/repair/917cd856fd35314537c1.pdf"
              },
              {
                "status": "download_error",
                "url": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='control.ucsd.edu', port=80): Max retries exceeded with url: /mauricio/courses/mae280a/lecture11.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='co",
                "retried_at": "2026-10-20T22:24:26Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.00772",
                "bytes": 857878,
                "reused": true,
                "local_path": "papers/repair/71af15dab8222eb475d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.4487",
                "bytes": 1171979,
                "reused": true,
                "local_path": "papers/repair/37f18f0d7acadb4282f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3584v7",
                "bytes": 685629,
                "reused": true,
                "local_path": "papers/repair/bdf05dc4032d4acb3572.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.0221",
                "bytes": 331057,
                "reused": true,
                "local_path": "papers/repair/4e0bbca4680770f0c883.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.06560",
                "bytes": 4261567,
                "reused": true,
                "local_path": "papers/repair/129e1e6853a3d4d7a64a.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "bytes": 921414,
                "reused": true,
                "local_path": "papers/repair/c7818bfa100e7982cf3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.01222",
                "bytes": 2570801,
                "reused": true,
                "local_path": "papers/repair/17fc5b1b00f236706451.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.04358",
                "bytes": 2337427,
                "reused": true,
                "local_path": "papers/repair/8b93d140fe096a835c1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "bytes": 6284388,
                "reused": true,
                "local_path": "papers/repair/338cf06e2122caa8db06.pdf"
              },
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "bytes": 334309,
                "reused": true,
                "local_path": "papers/repair/4b425dc99075992bc98a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33765,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/878201399682/pages/source.html",
            "local_html": "attachments/878201399682/pages/article.html",
            "body_base_path": "attachments/878201399682/pages/",
            "body_markdown_path": "attachments/878201399682/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Simulated_annealing",
                "label": "Simulated Annealing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hill_climbing",
                "label": "Hill Climbing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method",
                "label": "Nelder-Mead method",
                "type": "a"
              },
              {
                "href": "https://www.khanacademy.org/science/biology/her/evolution-and-natural-selection/a/darwin-evolution-natural-selection",
                "label": "Darwin, evolution, & natural selection",
                "type": "a"
              },
              {
                "href": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "label": "format",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "This",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.00772",
                "label": "CMA-ES tutorial",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Conjugate_prior",
                "label": "conjugate",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.4487",
                "label": "Wierstra, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1301.3584v7",
                "label": "distribution",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/14/natural-gradient/",
                "label": "space",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/FisherInformationMatrix.html",
                "label": "Fisher Information Matrix",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/11/fisher-information/",
                "label": "it is",
                "type": "a"
              },
              {
                "href": "http://blog.shakirm.com/2015/11/machine-learning-trick-of-the-day-5-log-derivative-trick/",
                "label": "trick",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.0221",
                "label": "long ago",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "Evolved Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "vs exploitation",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/TBA",
                "label": "above",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.06560",
                "label": "Conti et al, 2018",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "label": "ERL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.01222",
                "label": "CEM-RL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "PBT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.04358",
                "label": "Gaier & Ha 2019",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "label": "Stanley & Miikkulainen 2002",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
          "status": "partial",
          "article_id": "b003e8b2488e",
          "local_path": "series-follow/1602/repair/e770cc6a0f63aaa24286.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
              "bytes": 231787,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b57d68f7092bb1833c8c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
              "bytes": 277510,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c910fbb94e9497077e67.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
              "bytes": 70545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/28c7d5f3966b58d0995d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
              "bytes": 146618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3d90f7e1924950ee061d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
              "bytes": 737321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/3c5ddbb346561ac954f4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
              "bytes": 291684,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d4e8da7e08714c6e544e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
              "bytes": 109328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c514078611120f181162.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
              "bytes": 334060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ce2407eb4ff860e95cdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
              "bytes": 291512,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/772893bb018752b899d9.png"
            }
          ],
          "article": {
            "id": "b003e8b2488e",
            "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "bytes": 231787,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-b57d68f7092bb1833c8c.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "bytes": 277510,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c910fbb94e9497077e67.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "bytes": 70545,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-28c7d5f3966b58d0995d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "bytes": 146618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3d90f7e1924950ee061d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "bytes": 737321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3c5ddbb346561ac954f4.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "bytes": 291684,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-d4e8da7e08714c6e544e.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "bytes": 109328,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c514078611120f181162.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "bytes": 334060,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-ce2407eb4ff860e95cdd.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "bytes": 291512,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-772893bb018752b899d9.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In my earlier post on\nmeta-learning\n, the problem is mainly defined in the context of few-shot classification. Here I would like to explore more into cases when we try to “meta-learn”\nReinforcement Learning (RL)\ntasks by developing an agent that can solve unseen tasks fast and efficiently.\nTo recap, a good meta-learning model is expected to generalize to new tasks or new environments that have never been encountered during training. The adaptation process, essentially a\nmini learning session\n, happens at test with limited exposure to the new configurations. Even without any explicit fine-tuning (no gradient backpropagation on trainable variables), the meta-learning model autonomously adjusts internal hidden states to learn.\nTraining RL algorithms can be notoriously difficult sometimes. If the meta-learning agent could become so smart that the distribution of solvable unseen tasks grows extremely broad, we are on track towards\ngeneral purpose methods\n— essentially building a “brain” which would solve all kinds of RL problems without much human interference or manual feature engineering. Sounds amazing, right? 💖\nOn the Origin of Meta-RL\n#\nBack in 2001\n#\nI encountered a paper  written in 2001 by\nHochreiter et al.\nwhen reading\nWang et al., 2016\n. Although the idea was proposed for supervised learning, there are so many resemblances to the current approach to meta-RL.\nThe meta-learning system consists of the supervisory and the subordinate systems. The subordinate system is a recurrent neural network that takes as input both the observation at the current time step, $x\\_t$ and the label at the last time step, $y\\_{t-1}$. (Image source:\nHochreiter et al., 2001\n)\nHochreiter’s meta-learning model is a recurrent network with LSTM cell. LSTM is a good choice because it can internalize a history of inputs and tune its own weights effectively through\nBPTT\n. The training data contains $K$ sequences and each sequence is consist of $N$ samples generated by a target function $f_k(.), k=1, \\dots, K$,\n$$\n\\{\\text{input: }(\\mathbf{x}^k_i, \\mathbf{y}^k_{i-1}) \\to \\text{label: }\\mathbf{y}^k_i\\}_{i=1}^N\n\\text{ where }\\mathbf{y}^k_i = f_k(\\mathbf{x}^k_i)\n$$\nNoted that\nthe last label\n$\\mathbf{y}^k_{i-1}$ is also provided as an auxiliary input so that the function can learn the presented mapping.\nIn the experiment of decoding two-dimensional quadratic functions, $a x_1^2 + b x_2^2 + c x_1 x_2 + d x_1 + e x_2 + f$, with coefficients $a$-$f$ are randomly sampled from [-1, 1], this meta-learning system was able to approximate the function after seeing only ~35 examples.\nProposal in 2016\n#\nIn the modern days of DL,\nWang et al.\n(2016) and\nDuan et al.\n(2017) simultaneously proposed the very similar idea of\nMeta-RL\n(it is called\nRL^2\nin the second paper). A meta-RL model is trained over a distribution of MDPs, and at test time, it is able to learn to solve a new task quickly. The goal of meta-RL is ambitious, taking one step further towards general algorithms.\nDefine Meta-RL\n#\nMeta Reinforcement Learning\n, in short, is to do\nmeta-learning\nin the field of\nreinforcement learning\n. Usually the train and test tasks are different but drawn from the same family of problems; i.e., experiments in the papers included multi-armed bandit with different reward probabilities, mazes with different layouts, same robots but with different physical parameters in simulator, and many others.\nFormulation\n#\nLet’s say we have a distribution of tasks, each formularized as an\nMDP\n(Markov Decision Process), $M_i \\in \\mathcal{M}$. An MDP is determined by a 4-tuple, $M_i= \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle$:\nSymbol\nMeaning\n$\\mathcal{S}$\nA set of states.\n$\\mathcal{A}$\nA set of actions.\n$P_i: \\mathcal{S} \\times \\mathcal{A} \\times \\mathcal{S} \\to \\mathbb{R}_{+}$\nTransition probability function.\n$R_i: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}$\nReward function.\n(RL^2 paper adds an extra parameter, horizon $T$, into the MDP tuple to emphasize that each MDP should have a finite horizon.)\nNote that common state $\\mathcal{S}$ and action space $\\mathcal{A}$ are used above, so that a (stochastic) policy: $\\pi_\\theta: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}_{+}$ would get inputs compatible across different tasks. The test tasks are sampled from the same distribution $\\mathcal{M}$ or slightly modified version.\nIllustration of meta-RL, containing two optimization loops. The outer loop samples a new environment in every iteration and adjusts parameters that determine the agent's behavior. In the inner loop, the agent interacts with the environment and optimizes for the maximal reward. (Image source:\nBotvinick, et al. 2019\n)\nMain Differences from RL\n#\nThe overall configure of meta-RL is very similar to an ordinary RL algorithm, except that\nthe last reward\n$r_{t-1}$ and\nthe last action\n$a_{t-1}$ are also incorporated into the policy observation in addition to the current state $s_t$.\nIn RL: $\\pi_\\theta(s_t) \\to$  a distribution over $\\mathcal{A}$\nIn meta-RL: $\\pi_\\theta(a_{t-1}, r_{t-1}, s_t) \\to$  a distribution over $\\mathcal{A}$\nThe intention of this design is to feed a history into the model so that the policy can internalize the dynamics between states, rewards, and actions in the current MDP and adjust its strategy accordingly. This is well aligned with the setup in\nHochreiter’s system\n. Both meta-RL and RL^2 implemented an LSTM policy and the LSTM’s hidden states serve as a\nmemory\nfor tracking characteristics of the trajectories. Because the policy is recurrent, there is no need to feed the last state as inputs explicitly.\nThe training procedure works as follows:\nSample a new MDP, $M_i \\sim \\mathcal{M}$;\nReset the hidden state\nof the model;\nCollect multiple trajectories and update the model weights;\nRepeat from step 1.\nIn the meta-RL paper, different actor-critic architectures all use a recurrent model. Last reward and last action are additional inputs. The observation is fed into the LSTM either as a one-hot vector or as an embedding vector after passed through an encoder model. (Image source:\nWang et al., 2016\n)\nAs described in the RL^2 paper, illustration of the procedure of the model interacting with a series of MDPs in training time . (Image source:\nDuan et al., 2017\n)\nKey Components\n#\nThere are three key components in Meta-RL:\n⭐\nA Model with Memory\nA recurrent neural network maintains a hidden state. Thus, it could acquire and memorize the knowledge about the current task by updating the hidden state during rollouts. Without memory, meta-RL would not work.\n⭐\nMeta-learning Algorithm\nA meta-learning algorithm refers to how we can update the model weights to optimize for the purpose of solving an unseen task fast at test time. In both Meta-RL and RL^2 papers, the meta-learning algorithm is the ordinary gradient descent update of LSTM with hidden state reset between a switch of MDPs.\n⭐\nA Distribution of MDPs\nWhile the agent is exposed to a variety of environments and tasks during training, it has to learn how to adapt to different MDPs.\nAccording to\nBotvinick et al.\n(2019), one source of slowness in RL training is\nweak\ninductive bias\n( = “a set of assumptions that the learner uses to predict outputs given inputs that it has not encountered”). As a general ML rule, a learning algorithm with weak inductive bias will be able to master a wider range of variance, but usually, will be less sample-efficient. Therefore, to narrow down the hypotheses with stronger inductive biases help improve the learning speed.\nIn meta-RL, we impose certain types of inductive biases from the\ntask distribution\nand store them in\nmemory\n. Which inductive bias to adopt at test time depends on the\nalgorithm\n. Together, these three key components depict a compelling view of meta-RL: Adjusting the weights of a recurrent network is slow but it allows the model to work out a new task fast with its own RL algorithm implemented in its internal activity dynamics.\nMeta-RL interestingly and not very surprisingly matches the ideas in the\nAI-GAs\n(“AI-Generating Algorithms”) paper by Jeff Clune (2019). He proposed that one efficient way towards building general AI is to make learning as automatic as possible. The AI-GAs approach involves three pillars: (1) meta-learning architectures, (2) meta-learning algorithms, and (3) automatically generated environments for effective learning.\nThe topic of designing good recurrent network architectures is a bit too broad to be discussed here, so I will skip it. Next, let’s look further into another two components: meta-learning algorithms in the context of meta-RL and how to acquire a variety of training MDPs.\nMeta-Learning Algorithms for Meta-RL\n#\nMy previous\npost\non meta-learning has covered several classic meta-learning algorithms. Here I’m gonna include more related to RL.\nOptimizing Model Weights for Meta-learning\n#\nBoth MAML (\nFinn, et al. 2017\n) and Reptile (\nNichol et al., 2018\n) are methods on updating model parameters in order to achieve good generalization performance on new tasks. See an earlier post\nsection\non MAML and Reptile.\nMeta-learning Hyperparameters\n#\nThe\nreturn\nfunction in an RL problem, $G_t^{(n)}$ or $G_t^\\lambda$, involves a few hyperparameters that are often set heuristically, like the discount factor\n$\\gamma$\nand the bootstrapping parameter\n$\\lambda$\n.\nMeta-gradient RL (\nXu et al., 2018\n) considers them as\nmeta-parameters\n, $\\eta=\\{\\gamma, \\lambda \\}$, that can be tuned and learned\nonline\nwhile an agent is interacting with the environment. Therefore, the return becomes a function of $\\eta$ and dynamically adapts itself to a specific task over time.\n$$\n\\begin{aligned}\nG_\\eta^{(n)}(\\tau_t) &= R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1}R_{t+n} + \\gamma^n v_\\theta(s_{t+n}) & \\scriptstyle{\\text{; n-step return}} \\\\\nG_\\eta^{\\lambda}(\\tau_t) &= (1-\\lambda) \\sum_{n=1}^\\infty \\lambda^{n-1} G_\\eta^{(n)} & \\scriptstyle{\\text{; λ-return, mixture of n-step returns}}\n\\end{aligned}\n$$\nDuring training, we would like to update the policy parameters with gradients as a function of all the information in hand, $\\theta’ = \\theta + f(\\tau, \\theta, \\eta)$, where $\\theta$ are the current model weights, $\\tau$ is a sequence of trajectories, and $\\eta$ are the meta-parameters.\nMeanwhile, let’s say we have a meta-objective function $J(\\tau, \\theta, \\eta)$ as a performance measure. The training process follows the principle of online cross-validation, using a sequence of consecutive experiences:\nStarting with parameter $\\theta$, the policy $\\pi_\\theta$ is updated on the first batch of samples $\\tau$, resulting in $\\theta’$.\nThen we continue running the policy $\\pi_{\\theta’}$ to collect a new set of experiences $\\tau’$, just following $\\tau$ consecutively in time. The performance is measured as $J(\\tau’, \\theta’, \\bar{\\eta})$ with a fixed meta-parameter $\\bar{\\eta}$.\nThe gradient of meta-objective $J(\\tau’, \\theta’, \\bar{\\eta})$ w.r.t. $\\eta$ is used to update $\\eta$:\n$$\n\\begin{aligned}\n\\Delta \\eta\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\eta} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{d\\theta'}{d\\eta} & \\scriptstyle{\\text{ ; single variable chain rule.}} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial (\\theta + f(\\tau, \\theta, \\eta))}{\\partial\\eta}  \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big(\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\frac{d\\eta}{d\\eta} \\Big) & \\scriptstyle{\\text{; multivariable chain rule.}}\\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big( \\color{red}{\\big(\\mathbf{I} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\big)}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\Big) & \\scriptstyle{\\text{; secondary gradient term in red.}}\n\\end{aligned}\n$$\nwhere $\\beta$ is the learning rate for $\\eta$.\nThe meta-gradient RL algorithm simplifies the computation by setting the secondary gradient term to zero, $\\mathbf{I} + \\partial g(\\tau, \\theta, \\eta)/\\partial\\theta = 0$ — this choice prefers the immediate effect of the meta-parameters $\\eta$ on the parameters $\\theta$. Eventually we get:\n$$\n\\Delta \\eta = -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\n$$\nExperiments in the paper adopted the meta-objective function same as $TD(\\lambda)$ algorithm, minimizing the error between the approximated value function $v_\\theta(s)$ and the $\\lambda$-return:\n$$\n\\begin{aligned}\nJ(\\tau, \\theta, \\eta) &= (G^\\lambda_\\eta(\\tau) - v_\\theta(s))^2 \\\\\nJ(\\tau', \\theta', \\bar{\\eta}) &= (G^\\lambda_{\\bar{\\eta}}(\\tau') - v_{\\theta'}(s'))^2\n\\end{aligned}\n$$\nMeta-learning the Loss Function\n#\nIn policy gradient algorithms, the expected total reward is maximized by updating the policy parameters $\\theta$ in the direction of estimated gradient (\nSchulman et al., 2016\n),\n$$\ng = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\nabla_\\theta \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nwhere the candidates for $\\Psi_t$ include the trajectory return $G_t$, the Q value $Q(s_t, a_t)$, or the advantage value $A(s_t, a_t)$. The corresponding surrogate loss function for the policy gradient can be reverse-engineered:\n$$\nL_\\text{pg} = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nThis loss function is a measure over a history of trajectories, $(s_0, a_0, r_0, \\dots, s_t, a_t, r_t, \\dots)$.\nEvolved Policy Gradient\n(\nEPG\n;\nHouthooft, et al, 2018\n) takes a step further by defining the policy gradient loss function as a temporal convolution (1-D convolution) over the agent’s past experience, $L_\\phi$. The parameters $\\phi$ of the loss function network are evolved in a way that an agent can achieve higher returns.\nSimilar to many meta-learning algorithms, EPG has two optimization loops:\nIn the internal loop, an agent learns to improve its policy $\\pi_\\theta$.\nIn the outer loop, the model updates the parameters $\\phi$ of the loss function $L_\\phi$. Because there is no explicit way to write down a differentiable equation between the return and the loss, EPG turned to\nEvolutionary Strategies\n(ES).\nA general idea is to train a population of $N$ agents, each of them is trained with the loss function $L_{\\phi + \\sigma \\epsilon_i}$ parameterized with $\\phi$ added with a small Gaussian noise $\\epsilon_i \\sim \\mathcal{N}(0, \\mathbf{I})$ of standard deviation $\\sigma$. During the inner loop’s training, EPG tracks a history of experience and updates the policy parameters according to the loss function $L_{\\phi + \\sigma\\epsilon_i}$ for each agent:\n$$\n\\theta_i \\leftarrow \\theta - \\alpha_\\text{in} \\nabla_\\theta L_{\\phi + \\sigma \\epsilon_i} (\\pi_\\theta, \\tau_{t-K, \\dots, t})\n$$\nwhere $\\alpha_\\text{in}$ is the learning rate of the inner loop and $\\tau_{t-K, \\dots, t}$ is a sequence of $M$ transitions up to the current time step $t$.\nOnce the inner loop policy is mature enough, the policy is evaluated by the mean return $\\bar{G}_{\\phi+\\sigma\\epsilon_i}$ over multiple randomly sampled trajectories. Eventually, we are able to estimate the gradient of $\\phi$ according to\nNES\nnumerically (\nSalimans et al, 2017\n). While repeating this process, both the policy parameters $\\theta$ and the loss function weights $\\phi$ are being updated simultaneously to achieve higher returns.\n$$\n\\phi \\leftarrow \\phi + \\alpha_\\text{out} \\frac{1}{\\sigma N} \\sum_{i=1}^N \\epsilon_i G_{\\phi+\\sigma\\epsilon_i}\n$$\nwhere $\\alpha_\\text{out}$ is the learning rate of the outer loop.\nIn practice, the loss $L_\\phi$ is bootstrapped with an ordinary policy gradient (such as REINFORCE or PPO) surrogate loss $L_\\text{pg}$, $\\hat{L} = (1-\\alpha) L_\\phi + \\alpha L_\\text{pg}$. The weight $\\alpha$ is annealing from 1 to 0 gradually during training. At test time, the loss function parameter $\\phi$ stays fixed and the loss value is computed over a history of experience to update the policy parameters $\\theta$.\nMeta-learning the Exploration Strategies\n#\nThe\nexploitation vs exploration\ndilemma is a critical problem in RL. Common ways to do exploration include $\\epsilon$-greedy, random noise on actions, or stochastic policy with built-in randomness on the action space.\nMAESN\n(\nGupta et al, 2018\n) is an algorithm to learn structured action noise from prior experience for better and more effective exploration. Simply adding random noise on actions cannot capture task-dependent or time-correlated exploration strategies. MAESN changes the policy to condition on a per-task random variable $z_i \\sim \\mathcal{N}(\\mu_i, \\sigma_i)$, for $i$-th task $M_i$, so we would have a policy $a \\sim \\pi_\\theta(a\\mid s, z_i)$.\nThe latent variable $z_i$ is sampled once and fixed during one episode. Intuitively, the latent variable determines one type of behavior (or skills) that should be explored more at the beginning of a rollout and the agent would adjust its actions accordingly. Both the policy parameters and latent space are optimized to maximize the total task rewards. In the meantime, the policy learns to make use of the latent variables for exploration.\nIn addition,  the loss function includes a KL divergence between the learned latent variable and a unit Gaussian prior, $D_\\text{KL}(\\mathcal{N}(\\mu_i, \\sigma_i)|\\mathcal{N}(0, \\mathbf{I}))$. On one hand, it restricts the learned latent space not too far from a common prior. On the other hand, it creates the variational evidence lower bound (\nELBO\n) for the reward function. Interestingly the paper found that $(\\mu_i, \\sigma_i)$ for each task are usually close to the prior at convergence.\nThe policy is conditioned on a latent variable variable $z\\_i \\sim \\mathcal{N}(\\mu, \\sigma)$ that is sampled once every episode. Each task has different hyperparameters for the latent variable distribution, $(\\mu\\_i, \\sigma\\_i)$ and they are optimized in the outer loop. (Image source:\nGupta et al, 2018\n)\nEpisodic Control\n#\nA major criticism of RL is on its sample inefficiency. A large number of samples and small learning steps are required for incremental parameter adjustment in RL in order to maximize generalization and avoid catastrophic forgetting of earlier learning (\nBotvinick et al., 2019\n).\nEpisodic control\n(\nLengyel & Dayan, 2008\n) is proposed as a solution to avoid forgetting and improve generalization while training at a faster speed. It is partially inspired by hypotheses on instance-based\nhippocampal\nlearning.\nAn\nepisodic memory\nkeeps explicit records of past events and uses these records directly as point of reference for making new decisions (i.e. just like\nmetric-based\nmeta-learning). In\nMFEC\n(Model-Free Episodic Control;\nBlundell et al., 2016\n), the memory is modeled as a big table, storing the state-action pair $(s, a)$ as key and the corresponding Q-value $Q_\\text{EC}(s, a)$ as value. When receiving a new observation $s$, the Q value is estimated in an non-parametric way as the average Q-value of top $k$ most similar samples:\n$$\n\\hat{Q}_\\text{EC}(s, a) = \n\\begin{cases}\nQ_\\text{EC}(s, a)                      & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\n\\frac{1}{k} \\sum_{i=1}^k Q(s^{(i)}, a) & \\text{otherwise}\n\\end{cases}\n$$\nwhere $s^{(i)}, i=1, \\dots, k$ are top $k$ states with smallest distances to the state $s$. Then the action that yields the highest estimated Q value is selected. Then the memory table is updated according to the return received at $s_t$:\n$$\nQ_\\text{EC}(s, a) \\leftarrow\n\\begin{cases}\n\\max\\{Q_\\text{EC}(s_t, a_t), G_t\\}  & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\nG_t                                 & \\text{otherwise}\n\\end{cases}\n$$\nAs a tabular RL method, MFEC suffers from large memory consumption and a lack of ways to generalize among similar states. The first one can be fixed with an LRU cache. Inspired by\nmetric-based\nmeta-learning, especially Matching Networks (\nVinyals et al., 2016\n), the generalization problem is improved in a follow-up algorithm,\nNEC\n(Neural Episodic Control;\nPritzel et al., 2016\n).\nThe episodic memory in NEC is a Differentiable Neural Dictionary (\nDND\n), where the key is a convolutional embedding vector of input image pixels and the value stores estimated Q value. Given an inquiry key, the output is a weighted sum of values of top similar keys, where the weight is a normalized kernel measure between the query key and the selected key in the dictionary. This sounds like a hard\nattention\nmachanism.\nFig. 6 Illustrations of episodic memory module in NEC and two operations on a differentiable neural dictionary. (Image source:\nPritzel et al., 2016\n)\nFurther,\nEpisodic LSTM\n(\nRitter et al., 2018\n) enhances the basic LSTM architecture with a DND episodic memory, which stores task context embeddings as keys and the LSTM cell states as values. The stored hidden states are retrieved and added directly to the current cell state through the same gating mechanism within LSTM:\nIllustration of the episodic LSTM architecture. The additional structure of episodic memory is in bold. (Image source:\nRitter et al., 2018\n)\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\mathbf{i}_t \\circ \\mathbf{c}_\\text{in} + \\mathbf{f}_t \\circ \\mathbf{c}_{t-1} + \\color{green}{\\mathbf{r}_t \\circ \\mathbf{c}_\\text{ep}} &\\\\\n\\mathbf{i}_t &= \\sigma(\\mathbf{W}_{i} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_i) & \\scriptstyle{\\text{; input gate}} \\\\\n\\mathbf{f}_t &= \\sigma(\\mathbf{W}_{f} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_f) & \\scriptstyle{\\text{; forget gate}} \\\\\n\\color{green}{\\mathbf{r}_t} & \\color{green}{=} \\color{green}{\\sigma(\\mathbf{W}_{r} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_r)} & \\scriptstyle{\\text{; reinstatement gate}}\n\\end{aligned}\n$$\nwhere $\\mathbf{c}_t$ and $\\mathbf{h}_t$ are hidden and cell state at time $t$; $\\mathbf{i}_t$, $\\mathbf{f}_t$ and $\\mathbf{r}_t$ are input, forget and reinstatement gates, respectively; $\\mathbf{c}_\\text{ep}$ is the retrieved cell state from episodic memory. The newly added episodic memory components are marked in green.\nThis architecture provides a shortcut to the prior experience through context-based retrieval. Meanwhile, explicitly saving the task-dependent experience in an external memory avoids forgetting. In the paper, all the experiments have manually designed context vectors. How to construct an effective and efficient format of task context embeddings for more free-formed tasks would be an interesting topic.\nOverall the capacity of episodic control is limited by the complexity of the environment. It is very rare for an agent to repeatedly visit exactly the same states in a real-world task, so properly encoding the states is critical. The learned embedding space compresses the observation data into a lower dimension space and, in the meantime, two states being close in this space are expected to demand similar strategies.\nTraining Task Acquisition\n#\nAmong three key components, how to design a proper distribution of tasks is the less studied and probably the most specific one to meta-RL itself. As described\nabove\n, each task is a MDP: $M_i = \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle \\in \\mathcal{M}$. We can build a distribution of MDPs by modifying:\nThe\nreward configuration\n: Among different tasks, same behavior might get rewarded differently according to $R_i$.\nOr, the\nenvironment\n: The transition function $P_i$ can be reshaped by initializing the environment with varying shifts between states.\nTask Generation by Domain Randomization\n#\nRandomizing parameters in a simulator is an easy way to obtain tasks with modified transition functions. If interested in learning further, check my last\npost\non\ndomain randomization\n.\nEvolutionary Algorithm on Environment Generation\n#\nEvolutionary algorithm\nis a gradient-free heuristic-based optimization method, inspired by natural selection. A population of solutions follows a loop of evaluation, selection, reproduction, and mutation. Eventually, good solutions survive and thus get selected.\nPOET\n(\nWang et al, 2019\n), a framework based on the evolutionary algorithm, attempts to generate tasks while the problems themselves are being solved. The implementation of POET is only specifically designed for a simple 2D\nbipedal walker\nenvironment but points out an interesting direction. It is noteworthy that the evolutionary algorithm has had some compelling applications in Deep Learning like\nEPG\nand PBT (Population-Based Training;\nJaderberg et al, 2017\n).\nAn example bipedal walking environment (top) and an overview of POET (bottom). (Image source:\nPOET blog post\n)\nThe 2D bipedal walking environment is evolving: from a simple flat surface to a much more difficult trail with potential gaps, stumps, and rough terrains. POET pairs the generation of environmental challenges and the optimization of agents together so as to (a) select agents that can resolve current challenges and (b) evolve environments to be solvable. The algorithm maintains a list of\nenvironment-agent pairs\nand repeats the following:\nMutation\n: Generate new environments from currently active environments. Note that here types of mutation operations are created just for bipedal walker and a new environment would demand a new set of configurations.\nOptimization\n: Train paired agents within their respective environments.\nSelection\n: Periodically attempt to transfer current agents from one environment to another. Copy and update the best performing agent for every environment. The intuition is that skills learned in one environment might be helpful for a different environment.\nThe procedure above is quite similar to\nPBT\n, but PBT mutates and evolves hyperparameters instead. To some extent, POET is doing\ndomain randomization\n, as all the gaps, stumps and terrain roughness are controlled by some randomization probability parameters. Different from DR, the agents are not exposed to a fully randomized difficult environment all at once, but instead they are learning gradually with a curriculum configured by the evolutionary algorithm.\nLearning with Random Rewards\n#\nAn MDP without a reward function $R$ is known as a\nControlled Markov process\n(CMP). Given a predefined CMP, $\\langle \\mathcal{S}, \\mathcal{A}, P\\rangle$, we can acquire a variety of tasks by generating a collection of reward functions $\\mathcal{R}$ that encourage the training of an effective meta-learning policy.\nGupta et al. (2018)\nproposed two unsupervised approaches  for growing the task distribution in the context of CMP. Assuming there is an underlying latent variable $z \\sim p(z)$ associated with every task, it parameterizes/determines a reward function: $r_z(s) = \\log D(z|s)$, where a “discriminator” function $D(.)$ is used to extract the latent variable from the state. The paper described two ways to construct a discriminator function:\nSample random weights $\\phi_\\text{rand}$ of the discriminator, $D_{\\phi_\\text{rand}}(z \\mid s)$.\nLearn a discriminator function to encourage diversity-driven exploration. This method is introduced in more details in another sister paper “DIAYN” (\nEysenbach et al., 2018\n).\nDIAYN, short for “Diversity is all you need”, is a framework to encourage a policy to learn useful skills without a reward function. It explicitly models the latent variable $z$ as a\nskill\nembedding and makes the policy conditioned on $z$ in addition to state $s$, $\\pi_\\theta(a \\mid s, z)$. (Ok, this part is same as\nMAESN\nunsurprisingly, as the papers are from the same group.) The design of DIAYN is motivated by a few hypotheses:\nSkills should be diverse and lead to visitations of different states. → maximize the mutual information between states and skills, $I(S; Z)$\nSkills should be distinguishable by states, not actions. → minimize the mutual information between actions and skills, conditioned on states $I(A; Z \\mid S)$\nThe objective function to maximize is as follows, where the policy entropy is also added to encourage diversity:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta) \n&= I(S; Z) + H[A \\mid S] - I(A; Z \\mid S) &  \\\\\n&= (H(Z) - H(Z \\mid S)) + H[A \\mid S] - (H[A\\mid S] - H[A\\mid S, Z]) & \\\\\n&= H[A\\mid S, Z] \\color{green}{- H(Z \\mid S) + H(Z)} & \\\\\n&= H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\log p(z \\mid s)] - \\mathbb{E}_{z\\sim p(z)}[\\log p(z)] & \\scriptstyle{\\text{; can infer skills from states & p(z) is diverse.}} \\\\\n&\\ge H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\color{red}{\\log D_\\phi(z \\mid s) - \\log p(z)}] & \\scriptstyle{\\text{; according to Jensen's inequality; \"pseudo-reward\" in red.}}\n\\end{aligned}\n$$\nwhere $I(.)$ is mutual information and $H[.]$ is entropy measure. We cannot integrate all states to compute $p(z \\mid s)$, so approximate it with $D_\\phi(z \\mid s)$ — that is the diversity-driven discriminator function.\nDIAYN Algorithm. (Image source:\nEysenbach et al., 2019\n)\nOnce the discriminator function is learned, sampling a new MDP for training is strainght-forward: First, sample a latent variable, $z \\sim p(z)$ and construct a reward function $r_z(s) = \\log(D(z \\vert s))$. Pairing the reward function with a predefined CMP creates a new MDP.\nCited as:\n@article{weng2019metaRL,\n  title   = \"Meta Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-06-23-meta-rl/\"\n}\nReferences\n#\n[1] Richard S. Sutton.\n“The Bitter Lesson.”\nMarch 13, 2019.\n[2] Sepp Hochreiter, A. Steven Younger, and Peter R. Conwell.\n“Learning to learn using gradient descent.”\nIntl. Conf. on Artificial Neural Networks. 2001.\n[3] Jane X Wang, et al.\n“Learning to reinforcement learn.”\narXiv preprint arXiv:1611.05763 (2016).\n[4] Yan Duan, et al.\n“RL $^ 2$: Fast Reinforcement Learning via Slow Reinforcement Learning.”\nICLR 2017.\n[5] Matthew Botvinick, et al.\n“Reinforcement Learning, Fast and Slow”\nCell Review, Volume 23, Issue 5, P408-422, May 01, 2019.\n[6] Jeff Clune.\n“AI-GAs: AI-generating algorithms, an alternate paradigm for producing general artificial intelligence”\narXiv preprint arXiv:1905.10985 (2019).\n[7] Zhongwen Xu, et al.\n“Meta-Gradient Reinforcement Learning”\nNIPS 2018.\n[8] Rein Houthooft, et al.\n“Evolved Policy Gradients.”\nNIPS 2018.\n[9] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[10] Abhishek Gupta, et al.\n“Meta-Reinforcement Learning of Structured Exploration Strategies.”\nNIPS 2018.\n[11] Alexander Pritzel, et al.\n“Neural episodic control.”\nProc. Intl. Conf. on Machine Learning, Volume 70, 2017.\n[12] Charles Blundell, et al.\n“Model-free episodic control.”\narXiv preprint arXiv:1606.04460 (2016).\n[13] Samuel Ritter, et al.\n“Been there, done that: Meta-learning with episodic recall.”\nICML, 2018.\n[14] Rui Wang et al.\n“Paired Open-Ended Trailblazer (POET): Endlessly Generating Increasingly Complex and Diverse Learning Environments and Their Solutions”\narXiv preprint arXiv:1901.01753 (2019).\n[15] Uber Engineering Blog:\n“POET: Endlessly Generating Increasingly Complex and Diverse Learning Environments and their Solutions through the Paired Open-Ended Trailblazer.”\nJan 8, 2019.\n[16] Abhishek Gupta, et al.\n“Unsupervised meta-learning for Reinforcement Learning”\narXiv preprint arXiv:1806.04640 (2018).\n[17] Eysenbach, Benjamin, et al.\n“Diversity is all you need: Learning skills without a reward function.”\nICLR 2019.\n[18] Max Jaderberg, et al.\n“Population Based Training of Neural Networks.”\narXiv preprint arXiv:1711.09846 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:27Z",
            "title": "Meta Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/b003e8b2488e/code/body-000.txt",
                "chars": 223,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763.pdf",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d07e19c65fe402fbcd87.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ef36a4fe103ce19e63ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02779",
                "bytes": 1730325,
                "reused": true,
                "local_path": "papers/repair/29d9036eedf2ce0e8bad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.10985",
                "bytes": 421434,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0e39e620cbcdc3c0e38c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": true,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "bytes": 1111580,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bb993313e45a20ad529a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "bytes": 1779803,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/85a9a7621c9e0663fa1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "bytes": 2498781,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ddef5bb7adf90b31a4e2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "bytes": 227616,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1c0ac870da375a0164dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04460",
                "bytes": 915060,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6d8db7782bea674b000.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": true,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01988",
                "bytes": 2536595,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e1d79161cd219f80796c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09692",
                "bytes": 1441925,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b25973c32f2180b33c22.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.04640",
                "bytes": 2305556,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/022e9be73e69c1bb6162.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.06070",
                "bytes": 10804715,
                "reused": true,
                "local_path": "papers/repair/682027046f87efa4a50a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31542,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b003e8b2488e/pages/source.html",
            "local_html": "attachments/b003e8b2488e/pages/article.html",
            "body_base_path": "attachments/b003e8b2488e/pages/",
            "body_markdown_path": "attachments/b003e8b2488e/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning (RL)",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/IncIdeas/BitterLesson.html",
                "label": "general purpose methods",
                "type": "a"
              },
              {
                "href": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "label": "Hochreiter et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.05763.pdf",
                "label": "Wang et al., 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Backpropagation_through_time",
                "label": "BPTT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.05763",
                "label": "Wang et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02779",
                "label": "Duan et al.",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/action/showPdf?pii=S1364-6613%2819%2930061-0",
                "label": "Botvinick, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Inductive_bias",
                "label": "inductive bias",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.10985",
                "label": "AI-GAs",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol et al., 2018",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "label": "Xu et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "label": "Houthooft, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolutionary Strategies",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "NES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans et al, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "exploitation vs exploration",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "label": "Gupta et al, 2018",
                "type": "a"
              },
              {
                "href": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "label": "ELBO",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/trends/cognitive-sciences/fulltext/S1364-6613(19)30061-0",
                "label": "Botvinick et al., 2019",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "label": "Lengyel & Dayan, 2008",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hippocampus",
                "label": "hippocampal",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04460",
                "label": "Blundell et al., 2016",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01988",
                "label": "Pritzel et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09692",
                "label": "Ritter et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolutionary_algorithm",
                "label": "Evolutionary algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://gym.openai.com/envs/BipedalWalkerHardcore-v2/",
                "label": "bipedal walker",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://eng.uber.com/poet-open-ended-deep-learning/",
                "label": "POET blog post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.04640",
                "label": "Gupta et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.06070",
                "label": "Eysenbach et al., 2018",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
          "status": "partial",
          "article_id": "54a9d3380f68",
          "local_path": "series-follow/1602/repair/fd35ae042f354cb3c47d.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
              "bytes": 21634,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/0af902d15df97a679d1d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
              "bytes": 54826,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1602/repair/assets/b14e80a69c065fcf923f.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
              "bytes": 89960,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1602/repair/assets/2ff11bc219d2fddbb103.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
              "bytes": 1470472,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/299fa3d9ecac66743b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
              "bytes": 497605,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/35effb374a6c3725fe88.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
              "bytes": 788370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c0e1f225ec0f222e8138.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
              "bytes": 645042,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c3675d62fb7c6784228f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
              "bytes": 31968,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/069c442cc0ce9957e75d.png"
            }
          ],
          "article": {
            "id": "54a9d3380f68",
            "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "bytes": 21634,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-0af902d15df97a679d1d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "bytes": 54826,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-b14e80a69c065fcf923f.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "bytes": 89960,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-2ff11bc219d2fddbb103.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "bytes": 1470472,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-299fa3d9ecac66743b06.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "bytes": 497605,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-35effb374a6c3725fe88.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "bytes": 788370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c0e1f225ec0f222e8138.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "bytes": 645042,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c3675d62fb7c6784228f.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "bytes": 31968,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-069c442cc0ce9957e75d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Part 1\nof the “Object Detection for Dummies” series introduced: (1) the concept of image gradient vector and how HOG algorithm summarizes the information across all the gradient vectors in one image; (2) how the image segmentation algorithm works to detect regions that potentially contain objects; (3) how the Selective Search algorithm refines the outcomes of image segmentation for better region proposal.\nIn Part 2, we are about to find out more on the classic convolution neural network architectures for image classification. They lay the\nfoundation\nfor further progress on the deep learning models for object detection. Go check\nPart 3\nif you want to learn more on R-CNN and related models.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nCNN for Image Classification\n#\nCNN, short for “\nConvolutional Neural Network\n”, is the go-to solution for computer vision problems in the deep learning world. It was, to some extent,\ninspired\nby how human visual cortex system works.\nConvolution Operation\n#\nI strongly recommend this\nguide\nto convolution arithmetic, which provides a clean and solid explanation with tons of visualizations and examples. Here let’s focus on two-dimensional convolution as we are working with images in this post.\nIn short, convolution operation slides a predefined\nkernel\n(also called “filter”) on top of the input feature map (matrix of image pixels), multiplying and adding the values of the kernel and partial input features to generate the output. The values form an output matrix, as usually, the kernel is much smaller than the input image.\nAn illustration of applying a kernel on the input feature map to generate the output. (Image source:\nRiver Trail documentation\n)\nFigure 2 showcases two real examples of how to convolve a 3x3 kernel over a 5x5 2D matrix of numeric values to generate a 3x3 matrix. By controlling the padding size and the stride length, we can generate an output matrix of a certain size.\nTwo examples of 2D convolution operation: (top) no padding and 1x1 strides; (bottom) 1x1 border zeros padding and 2x2 strides. (Image source:\ndeeplearning.net\n)\nAlexNet (Krizhevsky et al, 2012)\n#\n5 convolution [+ optional max pooling] layers + 2 MLP layers + 1 LR layer\nUse data augmentation techniques to expand the training dataset, such as image translations, horizontal reflections, and patch extractions.\nThe architecture of AlexNet. (Image source:\nlink\n)\nVGG (Simonyan and Zisserman, 2014)\n#\nThe network is considered as “very deep” at its time; 19 layers\nThe architecture is extremely simplified with only 3x3 convolutional layers and 2x2 pooling layers. The stacking of small filters simulates a larger filter with fewer parameters.\nResNet (He et al., 2015)\n#\nThe network is indeed very deep; 152 layers of simple architecture.\nResidual Block\n: Some input of a certain layer can be passed to the component two layers later. Residual blocks are essential for keeping a deep network trainable and eventually work. Without residual blocks, the training loss of a plain network does not monotonically decrease as the number of layers increases due to\nvanishing and exploding gradients\n.\nAn illustration of the residual block of ResNet. In some way, we can say the design of residual blocks is inspired by V4 getting input directly from V1 in the human visual cortex system. (left image source:\nWang et al., 2017\n)\nEvaluation Metrics: mAP\n#\nA common evaluation metric used in many object recognition and detection tasks is “\nmAP\n”, short for “\nmean average precision\n”. It is a number from 0 to 100; higher value is better.\nCombine all detections from all test images to draw a precision-recall curve (PR curve) for each class; The “average precision” (AP) is the area under the PR curve.\nGiven that target objects are in different classes, we first compute AP separately for each class, and then average over classes.\nA detection is a true positive if it has\n“intersection over union” (IoU)\nwith a ground-truth box greater than some threshold (usually 0.5; if so, the metric is “\nmAP@0.5\n”)\nDeformable Parts Model\n#\nThe Deformable Parts Model (DPM) (\nFelzenszwalb et al., 2010\n) recognizes objects with a mixture graphical model (Markov random fields) of deformable parts. The model consists of three major components:\nA coarse\nroot filter\ndefines a detection window that approximately covers an entire object. A filter specifies weights for a region feature vector.\nMultiple\npart filters\nthat cover smaller parts of the object. Parts filters are learned at twice resolution of the root filter.\nA\nspatial model\nfor scoring the locations of part filters relative to the root.\nThe DPM model contains (a) a root filter, (b) multiple part filters at twice the resolution, and (c) a model for scoring the location and deformation of parts.\nThe quality of detecting an object is measured by the score of filters minus the deformation costs. The matching score $f$, in laymen’s terms, is:\n$$\nf(\\text{model}, x) = f(\\beta_\\text{root}, x) + \\sum_{\\beta_\\text{part} \\in \\text{part filters}} \\max_y [f(\\beta_\\text{part}, y) - \\text{cost}(\\beta_\\text{part}, x, y)]\n$$\nin which,\n$x$ is an image with a specified position and scale;\n$y$ is a sub region of $x$.\n$\\beta_\\text{root}$ is the root filter.\n$\\beta_\\text{part}$ is one part filter.\ncost() measures the penalty of the part deviating from its ideal location relative to the root.\nThe basic score model is the dot product between the filter $\\beta$ and the region feature vector $\\Phi(x)$: $f(\\beta, x) = \\beta \\cdot \\Phi(x)$. The feature set $\\Phi(x)$ can be defined by HOG or other similar algorithms.\nA root location with high score detects a region with high chances to contain an object, while the locations of the parts with high scores confirm a recognized object hypothesis. The paper adopted latent SVM to model the classifier.\nThe matching process by DPM. (Image source:\nFelzenszwalb et al., 2010\n)\nThe author later claimed that DPM and CNN models are not two distinct approaches to object recognition. Instead, a DPM model can be formulated as a CNN by unrolling the DPM inference algorithm and mapping each step to an equivalent CNN layer. (Check the details in\nGirshick et al., 2015\n!)\nOverfeat\n#\nOverfeat [\npaper\n][\ncode\n] is a pioneer model of integrating the object detection, localization and classification tasks all into one convolutional neural network. The main idea is to (i) do image classification at different locations on regions of multiple scales of the image in a sliding window fashion, and (ii) predict the bounding box locations with a regressor trained on top of the same convolution layers.\nThe Overfeat model architecture is very similar to\nAlexNet\n. It is trained as follows:\nThe training stages of the Overfeat model. (Image source:\nlink\n)\nTrain a CNN model (similar to AlexNet) on the image classification task.\nThen, we replace the top classifier layers by a regression network and train it to predict object bounding boxes at each spatial location and scale. The regressor is class-specific, each generated for one image class.\nInput: Images with classification and bounding box.\nOutput: $(x_\\text{left}, x_\\text{right}, y_\\text{top}, y_\\text{bottom})$, 4 values in total, representing the coordinates of the bounding box edges.\nLoss: The regressor is trained to minimize $l2$ norm between generated bounding box and the ground truth for each training example.\nAt the detection time,\nPerform classification at each location using the pretrained CNN model.\nPredict object bounding boxes on all classified regions generated by the classifier.\nMerge bounding boxes with sufficient overlap from localization and sufficient confidence of being the same object from the classifier.\nCited as:\n@article{weng2017detection2,\n  title   = \"Object Detection for Dummies Part 2: CNN, DPM and Overfeat\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/\"\n}\nReference\n#\n[1] Vincent Dumoulin and Francesco Visin.\n“A guide to convolution arithmetic for deep learning.”\narXiv preprint arXiv:1603.07285 (2016).\n[2] Haohan Wang, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800 (2017).\n[3] Pedro F. Felzenszwalb, Ross B. Girshick, David McAllester, and Deva Ramanan.\n“Object detection with discriminatively trained part-based models.”\nIEEE transactions on pattern analysis and machine intelligence 32, no. 9 (2010): 1627-1645.\n[4] Ross B. Girshick, Forrest Iandola, Trevor Darrell, and Jitendra Malik.\n“Deformable part models are convolutional neural networks.”\nIn Proc. IEEE Conf. on Computer Vision and Pattern Recognition (CVPR), pp. 437-446. 2015.\n[5] Sermanet, Pierre, David Eigen, Xiang Zhang, Michaël Mathieu, Rob Fergus, and Yann LeCun.\n“OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks”\narXiv preprint arXiv:1312.6229 (2013).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:42Z",
            "title": "Object Detection for Dummies Part 2: CNN, DPM and Overfeat | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/54a9d3380f68/code/body-000.txt",
                "chars": 276,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.07285.pdf",
                "bytes": 913752,
                "reused": true,
                "local_path": "papers/repair/b61fe9cb2654d748de68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6229.pdf",
                "bytes": 937841,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/540d3c26a6305febc0e1.pdf"
              },
              {
                "status": "http_403",
                "url": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "retried_at": "2026-10-20T17:45:41Z"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "bytes": 832728,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1743cfdd1a25ffae4bbb.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "retried_at": "2026-10-20T17:45:42Z"
              },
              {
                "status": "ok",
                "url": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "bytes": 6298687,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/417cc548662a22985f80.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 8988,
            "expected_body_images": 8,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_403",
            "raw_html": "attachments/54a9d3380f68/pages/source.html",
            "local_html": "attachments/54a9d3380f68/pages/article.html",
            "body_base_path": "attachments/54a9d3380f68/pages/",
            "body_markdown_path": "attachments/54a9d3380f68/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/",
                "label": "inspired",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1603.07285.pdf",
                "label": "guide",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "kernel",
                "type": "a"
              },
              {
                "href": "http://intellabs.github.io/RiverTrail/tutorial/",
                "label": "River Trail documentation",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html",
                "label": "deeplearning.net",
                "type": "a"
              },
              {
                "href": "http://vision03.csail.mit.edu/cnn_art/index.html",
                "label": "link",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2015/10/recurrent-neural-networks-tutorial-part-3-backpropagation-through-time-and-vanishing-gradients/",
                "label": "vanishing and exploding gradients",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1312.6229.pdf",
                "label": "Wang et al., 2017",
                "type": "a"
              },
              {
                "href": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "label": "Felzenszwalb et al., 2010",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "label": "Girshick et al., 2015",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sermanet/OverFeat",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
          "status": "partial",
          "article_id": "bd2a1c61491f",
          "local_path": "series-follow/1602/repair/99f4c939175460a007b6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cfd86d1d041d4e587dd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/57e8505d379090b6a5c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/eb72333120a9bf61db22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
              "bytes": 517373,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/94806f3485ee4c7d4137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
              "bytes": 420355,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/10c3f7a4432b939f41e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
              "bytes": 110695,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9af813630ff27b91e9f8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
              "bytes": 104844,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2d52fb35835b8ffb9f5c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
              "bytes": 441748,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b512db56c30433d4c252.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
              "bytes": 81702,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/701853184c4d260333df.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
              "bytes": 75150,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/440b77c01199a8fa47a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
              "bytes": 308982,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/321a0b363e9a6d1aa98b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/65f1b4ee283f16066c80.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
              "bytes": 118602,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f6d1acbfbe9a2ebc5720.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
              "bytes": 128314,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6801941ec960782dbcdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
              "bytes": 49638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/aa7a4901bbb57ffba3a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
              "bytes": 144593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/61300c84161edec245ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
              "bytes": 92635,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e33cbf677e130ee48f58.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
              "bytes": 244624,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f5d3b8b9ebc8beb78c77.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
              "bytes": 135708,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/30a7b1c7f2d502623782.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/528e7d446bed9aeb5917.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
              "bytes": 306995,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/08fa8454100a632db05c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
              "bytes": 296726,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5fade868b98da3fc740e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
              "bytes": 150541,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1864a0421abec41db939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
              "bytes": 300912,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9bbffc5733b6530c7240.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/8ed5854240a34aa93f46.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family Version 2.0",
            "keywords": "Transformer,注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "publish_date": "2023-01",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer架构家族全景综述（2.0版）",
            "id": "bd2a1c61491f",
            "collected_at": "2026-10-02T14:12:43",
            "title": "The Transformer Family Version 2.0 | Lil'Log",
            "body_markdown": "Many new Transformer architecture improvements have been proposed since my last post on\n“The Transformer Family”\nabout three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$N$\nThe total number of attention layers in the model; not considering MoE.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\nRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nTransformer Basics\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})}{ \\sum_{r \\in \\mathcal{S}_i} \\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_r}^\\top}{\\sqrt{d_k}}) }\n$$\nwhere $\\mathcal{S}_i$ is a collection of key positions for the $i$-th query to attend to.\nSee my old\npost for other types of attention\nif interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttn}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nEncoder-Decoder Architecture\n#\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\n#\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\nSinusoidal Positional Encoding\n#\nSinusoidal positional encoding is defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\nLearned Positional Encoding\n#\nLearned positional encoding assigns each element with a\nlearned\ncolumn vector which encodes its absolute position (\nGehring, et al. 2017\n) and furthermroe this encoding can be learned differently per layer (\nAl-Rfou et al. 2018\n).\nRelative Position Encoding\n#\nShaw et al. (2018)\n) incorporated relative positional information into $\\mathbf{W}^k$ and $\\mathbf{W}^v$. Maximum relative position is clipped to a maximum absolute value of $k$ and this clipping operation enables the model to generalize to unseen sequence lengths. Therefore, $2k + 1$ unique edge labels are considered and let us denote $\\mathbf{P}^k, \\mathbf{P}^v \\in \\mathbb{R}^{2k+1}$ as learnable relative position representations.\n$$\nA_{ij}^k = P^k_{\\text{clip}(j - i, k)} \\quad\nA_{ij}^v = P^v_{\\text{clip}(j - i, k)} \\quad\n\\text{where }\\text{clip}(x, k) = \\text{clip}(x, -k, k)\n$$\nTransformer-XL\n(\nDai et al., 2019\n) proposed a type of relative positional encoding based on reparametrization of dot-product of keys and queries. To keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nRotary Position Embedding\n#\nRotary position embedding (\nRoPE\n;\nSu et al. 2021\n) encodes the absolution position with a\nrotation matrix\nand multiplies key and value matrices of every attention layer with it to inject relative positional information at every layer.\nWhen encoding relative positional information into the inner product of the $i$-th key and the $j$-th query, we would like to formulate the function in a way that the inner product is only about the relative position $i-j$. Rotary Position Embedding (RoPE) makes use of the rotation operation in Euclidean space and frames the relative position embedding as simply rotating feature matrix by an angle proportional to its position index.\nGiven a vector $\\mathbf{z}$, if we want to rotate it counterclockwise by $\\theta$, we can multiply it by a rotation matrix to get $R\\mathbf{z}$ where the rotation matrix $R$ is defined as:\n$$\nR = \\begin{bmatrix}\n\\cos\\theta & -\\sin\\theta \\\\\n\\sin\\theta & \\cos\\theta\n\\end{bmatrix}\n$$\nWhen generalizing to higher dimensional space, RoPE divide the $d$-dimensional space into $d/2$ subspaces and constructs a rotation matrix $R$ of size $d \\times d$ for token at position $i$:\n$$\nR^d_{\\Theta, i} = \\begin{bmatrix}\n\\cos i\\theta_1 & -\\sin i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n\\sin i\\theta_1 & \\cos i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n0 & 0 & \\cos i\\theta_2 & -\\sin i\\theta_2 & \\dots & 0 & 0 \\\\\n0 & 0 & \\sin i\\theta_2 & \\cos i\\theta_2 & \\dots & 0 & 0 \\\\\n\\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n0 & 0 & 0 & 0 & \\dots & \\cos i\\theta_{d/2} & -\\sin i\\theta_{d/2} \\\\\n0 & 0 & 0 & 0 & \\dots & \\sin i\\theta_{d/2} & \\cos i\\theta_{d/2} \\\\\n\\end{bmatrix}\n$$\nwhere in the paper we have $\\Theta = {\\theta_i = 10000^{-2(i−1)/d}, i \\in [1, 2, …, d/2]}$. Note that this is essentially equivalent to sinusoidal positional encoding but formulated as a rotation matrix.\nThen both key and query matrices incorporates the positional information by multiplying with this rotation matrix:\n$$\n\\begin{aligned}\n& \\mathbf{q}_i^\\top \\mathbf{k}_j = (R^d_{\\Theta, i} \\mathbf{W}^q\\mathbf{x}_i)^\\top (R^d_{\\Theta, j} \\mathbf{W}^k\\mathbf{x}_j) = \\mathbf{x}_i^\\top\\mathbf{W}^q R^d_{\\Theta, j-i}\\mathbf{W}^k\\mathbf{x}_j \\\\\n& \\text{ where } R^d_{\\Theta, j-i} = (R^d_{\\Theta, i})^\\top R^d_{\\Theta, j}\n\\end{aligned}\n$$\nVisual illustration of how rotary position embedding is implemented.(Image source:\nSu et al., 2021\n) Note: I used $i$ instead of $m$ to represent the position index compared to the original figure in the paper.\nLonger Context\n#\nThe length of an input sequence for transformer models at inference time is upper-bounded by the context length used for training. Naively increasing context length leads to high consumption in both time ($\\mathcal{O}(L^2d)$) and memory ($\\mathcal{O}(L^2)$) and may not be supported due to hardware constraints.\nThis section introduces several improvements in transformer architecture to better support long context at inference; E.g. using additional memory, design for better context extrapolation, or recurrency mechanism.\nContext Memory\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments. This\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) modifies the architecture to reuse hidden states between segments with an additional memory. The recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both keys and values rely on extended hidden states, while queries only consume hidden states at the current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension. And Transformer-XL needs to use\nrelative positional encoding\nbecause previous and current segments would be assigned with the same encoding if we encode absolute positions, which is undesired.\nCompressive Transformer\n(\nRae et al. 2019\n) extends Transformer-XL by compressing past memories to support longer sequences. It explicitly adds\nmemory\nslots of size $m_m$ per layer for storing past activations of this layer to preserve long context. When some past activations become old enough, they are compressed and saved in an additional\ncompressed memory\nof size $m_{cm}$ per layer.\nCompressive transformer maintains two types of memory slots, memory and compressed memory, to support long context. (Image source:\nRae et al. 2019\n).\nBoth memory and compressed memory are FIFO queues. Given the model context length $L$, the compression function of compression rate $c$ is defined as $f_c: \\mathbb{R}^{L \\times d} \\to \\mathbb{R}^{[\\frac{L}{c}] \\times d}$, mapping $L$ oldest activations to $[\\frac{L}{c}]$ compressed memory elements. There are several choices of compression functions:\nMax/mean pooling of kernel and stride size $c$;\n1D convolution with kernel and stride size $c$ (need to learn additional parameters);\nDilated convolution (need to learn additional parameters). In their experiments, convolution compression works out the best on\nEnWik8\ndataset;\nMost used memories.\nCompressive transformer has two additional training losses:\nAuto-encoding loss\n(lossless compression objective) measures how well we can reconstruct the original memories from compressed memories\n$$\n \\mathcal{L}_{ac} = \\| \\textbf{old_mem}^{(i)} - g(\\textbf{new_cm}^{(i)}) \\|_2\n $$\nwhere $g: \\mathbb{R}^{[\\frac{L}{c}] \\times d} \\to \\mathbb{R}^{L \\times d}$ reverses the compression function $f$.\nAttention-reconstruction loss\n(lossy objective) reconstructs content-based attention over memory vs compressed memory and minimize the difference:\n$$\n \\mathcal{L}_{ar} = \\|\\text{attn}(\\mathbf{h}^{(i)}, \\textbf{old_mem}^{(i)}) − \\text{attn}(\\mathbf{h}^{(i)}, \\textbf{new_cm}^{(i)})\\|_2\n $$\nTransformer-XL with a memory of size $m$ has a maximum temporal range of $m \\times N$, where $N$ is the number of layers in the model, and attention cost $\\mathcal{O}(L^2 + Lm)$. In comparison, compressed transformer has a temporal range of $(m_m + c \\cdot m_{cm}) \\times N$ and attention cost $\\mathcal{O}(L^2 + L(m_m + m_{cm}))$. A larger compression rate $c$ gives better tradeoff between temporal range length and attention cost.\nAttention weights, from oldest to newest, are stored in three locations: compressed memory → memory → causally masked sequence. In the experiments, they observed an increase in attention weights from oldest activations stored in the regular memory, to activations stored in the compressed memory, implying that the network is learning to preserve salient information.\nAttention weights with one standard deviation as error bars versus memory positions, from oldest (left) to newest (right). (Image source:\nRae et al. 2019\n).\nNon-Differentiable External Memory\n#\n$k$NN-LM\n(\nKhandelwal et al. 2020\n) enhances a pretrained LM with a separate $k$NN model by linearly interpolating the next token probabilities predicted by both models. The $k$NN model is built upon an external key-value store  which can store any large pre-training dataset or OOD new dataset. This datastore is preprocessed to save a\nlarge\nnumber of pairs, (LM embedding representation of context, next token) and the nearest neighbor retrieval happens in the LM embedding space. Because the datastore can be gigantic, we need to rely on libraries for fast dense vector search such as\nFAISS\nor\nScaNN\n. The indexing process only happens once and parallelism is easy to implement at inference time.\nAt inference time, the next token probability is a weighted sum of two predictions:\n$$\n\\begin{aligned}\np(y \\vert \\mathbf{x}) &= \\lambda \\; p_\\text{kNN}(y \\vert \\mathbf{x}) + (1- \\lambda) \\; p_\\text{LM}(y \\vert \\mathbf{x}) \\\\\np_\\text{kNN}(y \\vert \\mathbf{x}) &\\propto \\sum_{(k_i, w_i) \\in \\mathcal{N}} \\mathbb{1}[y = w_i] \\exp(-d(k_i, f(\\mathbf{x})))\n\\end{aligned}\n$$\nwhere $\\mathcal{N}$ contains a set of nearest neighbor data points retrieved by $k$NN; $d(., .)$ is a distance function such as L2 distance.\nAccording to the experiments, larger datastore size or larger $k$ is correlated with better perplexity. The weighting scalar $\\lambda$ should be tuned, but in general it is expected to be larger for out-of-domain data compared to in-domain data and larger datastore can afford a larger $\\lambda$.\nSPALM\n(\nAdaptive semiparametric language models\n;\nYogatama et al. 2021\n) incorporates both (1) Transformer-XL style memory for hidden states from external context as short-term memory and (2) $k$NN-LM style key-value store as long memory.\nIllustration of how SPALM combines context memory of past hidden states (short term memory) with an external key-value datastore (long term memory) to support longer context. (Image source:\nYogatama et al. 2021\n).\nSPALM runs $k$NN search to fetch $k$ tokens with most relevant context. For each token we can get the same embedding representation provided by a pretrained LM, denoted as $\\{\\mathbf{y}_i\\}_{i=1}^k$. The gating mechanism first aggregates the retrieved token embeddings with a simple attention layer using $\\mathbf{h}^R_t$ (the hidden state for token $x_t$ at layer $R$) as a query and then learns a gating parameter $\\mathbf{g}_t$ to balance between local information $\\mathbf{h}^R_t$ and long-term information $\\mathbf{m}_t$.\n$$\n\\begin{aligned}\n\\mathbf{m}_t &= \\sum_{i=1}^k \\frac{\\exp(\\mathbf{y}_i^\\top \\mathbf{h}^R_t)}{\\sum_{j=1}^k \\exp(\\mathbf{y}_j^\\top \\mathbf{h}^R_t)} \\cdot \\mathbf{y}_i \\\\\n\\mathbf{g}_t &= \\sigma(\\mathbf{w}_g^\\top \\mathbf{h}_t^R) \\\\\n\\mathbf{z}_t &= (1 - \\mathbf{g}_t) \\odot \\mathbf{m}_t + \\mathbf{g}_t \\odot \\mathbf{h}^R_t \\\\\np(x_{t+1}\\mid \\mathbf{x}_{\\leq t}) &= \\text{softmax}(\\mathbf{z}_t; \\mathbf{W})\n\\end{aligned}\n$$\nwhere $\\mathbf{w}_g$ is a parameter vector to learn; $\\sigma(.)$ is sigmoid; $\\mathbf{W}$ is the word embedding matrix shared between both input and output tokens. Different from $k$NN-LM, they didn’t find the nearest neighbor distance to be helpful in the aggregation of retrieved tokens.\nDuring training, the key representations in the long-term memory stay constant, produced by a pretrained LM, but the value encoder, aka the word embedding matrix, gets updated.\nMemorizing Transformer\n(\nWu et al. 2022\n) adds a $k$NN-augmented attention layer near the top stack of a decoder-only Transformer. This special layer maintains a Transformer-XL style FIFO cache of past key-value pairs.\nThe same QKV values are used for both local attention and $k$NN mechanisms. The $k$NN lookup returns top-$k$ (key, value) pairs for each query in the input sequence and then they are processed through the self-attention stack to compute a weighted average of retrieved values. Two types of attention are combined with a learnable per-head gating parameter. To prevent large distributional shifts in value magnitude, both keys and values in the cache are normalized.\nWhat they found during experiments with Memorizing Transformer:\nIt is observed in some experiments that training models with a small memory and then finetuned with a larger memory works better than training with a large memory from scratch.\nThe smaller Memorizing Transformer with just 8k tokens in memory can match the perplexity of a larger vanilla Transformer with 5X more trainable parameters.\nIncreasing the size of external memory provided consistent gains up to a size of 262K.\nA  non-memory transformer can be finetuned to use memory.\nFine-tuning a vanilla Transformer with a key-value memory can achieve similar performance as training a memorizing transformer from scratch. (Image source:\nWu et al. 2022\n).\nDistance-Enhanced Attention Scores\n#\nDistance Aware Transformer\n(\nDA-Transformer\n;\nWu, et al. 2021\n) and\nAttention with Linear Biases\n(\nALiBi\n;\nPress et al. 2022\n) are motivated by similar ideas — in order to encourage the model to extrapolate over longer context than what the model is trained on, we can explicitly attach the positional information to every pair of attention score based on the distance between key and query tokens.\nNote that the default positional encoding in vanilla Transformer only adds positional information to the input sequence, while later improved encoding mechanisms alter attention scores of every layer, such as\nrotary position embedding\n, and they take on form very similar to distance enhanced attention scores.\nDA-Transformer\n(\nWu, et al. 2021\n) multiplies attention scores at each layer by a learnable bias that is formulated as a function of the distance between key and query. Different attention heads use different parameters to distinguish diverse preferences to short-term vs long-term context. Given two positions, $i, j$, DA-Transformer uses the following weighting function to alter the self-attention score:\n$$\n\\begin{aligned}\n\\mathbf{R}^{(i)} &= \\alpha_i \\mathbf{R} \\quad \\text{where }R_{ij} = \\vert i-j \\vert\\\\\nf(\\mathbf{R}^{(i)}; \\beta_i) &= \\frac{1 + \\exp(\\beta_i)}{1 + \\exp(\\beta_i - \\mathbf{R}^{(i)})} \\\\\n\\text{attn}(\\mathbf{Q}^{(i)}, \\mathbf{K}^{(i)}, \\mathbf{V}^{(i)}) &= \\text{row-softmax}\\Big(\\frac{\\text{ReLU}(\\mathbf{Q}^{(i)}\\mathbf{K}^{(i)\\top})f(\\mathbf{R}^{(i)})}{\\sqrt{d}}\\Big) \\mathbf{V}^{(i)}\n\\end{aligned}\n$$\nwhere $\\alpha_i$ is a learnable parameters to weight relative distance differently per head where the head is indexed by superscript $^{(i)}$; $\\beta_i$ is a learnable parameter to control the upper bound and ascending slope wrt the distance for the $i$-th attention head. The weighting function $f(.)$ is designed in a way that: (1) $f(0)=1$; (2) $f(\\mathbf{R}^{(i)}) = 0$ when $\\mathbf{R}^{(i)} \\to -\\infty$; (3) $f(\\mathbf{R}^{(i)})$ is bounded when $\\mathbf{R}^{(i)} \\to +\\infty$; (4) the scale is tunable; (5) and the function is monotonic. The extra time complexity brought by $f(\\mathbf{R}^{(i)})$ is $\\mathcal{O}(L^2)$ and it is small relative to the self attention time complexity $\\mathcal{O}(L^2 d)$. The extra memory consumption is minimal, ~$\\mathcal{O}(2h)$.\nInstead of multipliers,\nALiBi\n(\nPress et al. 2022\n) adds a constant bias term on query-key attention scores, proportional to pairwise distances. The bias introduces a strong recency preference and penalizes keys that are too far away. The penalties are increased at different rates within different heads.\n$$\n\\text{softmax}(\\mathbf{q}_i \\mathbf{K}^\\top + \\alpha_i \\cdot [0, -1, -2, \\dots, -(i-1)])\n$$\nwhere $\\alpha_i$ is a head-specific weighting scalar. Different from DA-transformer, $\\alpha_i$ is not learned but fixed as a geometric sequence; for example, for 8 heads, ${\\alpha_i} = {\\frac{1}{2}, \\frac{1}{2^2}, \\dots, \\frac{1}{2^8}}$. The overall idea is very much similar to what relative positional encoding aims to solve.\nIllustration of how ALiBi enhances attention scores with a positional bias term. (Image source:\nPress et al. 2021\n).\nWith ALiBi,\nPress et al. (2022)\ntrained a 1.3B model on context length 1024 during training and extrapolated to 2046 at inference time.\nExtrapolation experiments for running inference with Transformers of different configs, including sinusoidal positional encoding, rotary positional encoding, simplified relative positional encoding in T5 and ALiBi. All models were trained with small context length but inference ran for much longer context. (Image source:\nPress et al. 2021\n).\nMake it Recurrent\n#\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN. Rather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{h}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{h}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{h}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{h}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{h}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses\nsinusoidal position signal\nbut with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{h}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nAdaptive Modeling\n#\nAdaptive modeling refers to a mechanism that can adjust the amount of computation according to different inputs. For example, some tokens may only need local information and thus demand a shorter attention span; Or some tokens are relatively easier to predict and do not need to be processed through the entire attention stack.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar et al (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 14) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys within its attention span of size $s$:\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clip}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nDepth-Adaptive Transformer\n#\nAt inference time, it is natural to assume that some tokens are easier to predict and thus do not require as much computation as others. Therefore we may only process its prediction through a limited number of layers to achieve a good balance between speed and performance.\nBoth\nDepth-Adaptive Transformer\n(\nElabyad et al. 2020\n) and\nConfident Adaptive Language Model\n(\nCALM\n;\nSchuster et al. 2022\n) are motivated by this idea and learn to predict optimal numbers of layers needed for different input tokens.\nDepth-adaptive transformer\n(\nElabyad et al. 2020\n) attaches an output classifier to every layer to produce exit predictions based on activations of that layer. The classifier weight matrices can be different per layer or shared across layers. During training, the model sample different sequences of exits such that the model is optimized with hidden states of different layers. The learning objective incorporates likelihood probabilities predicted at different layers, $n=1, \\dots, N$:\n$$\n\\text{LL}^n_t = \\log p(y_t \\vert \\mathbf{h}^n_{t-1}) \\quad\n\\text{LL}^n = \\sum_{t=1}^{\\vert\\mathbf{y}\\vert} LL^n_t\n$$\nAdaptive depth classifiers outputs a parametric distribution $q_t$. It is trained with cross entropy loss against an oracle distribution $q^*_t$. The paper explored three confiurations for how to learn such a classifier $q_t$.\nIllustration of three types of adaptive depth classifiers.\n(Image source:\nElabyad et al. 2020\n).\nSequence-specific depth classifier\n: All tokens of the same sequence share the same exit block. It depends on the average of the encoder representation of the sequence. Given an input sequence $\\mathbf{x}$ of length $L$, the classifier takes $\\bar{\\mathbf{x}} = \\frac{1}{L} \\sum_{t=1}^L \\mathbf{x}_t$ as input and outputs a multinomial distribution of $N$ dimensions, corresponding to $N$ layers.\n$$\n \\begin{aligned}\n q(n \\vert \\mathbf{x}) &=\\text{softmax}(\\mathbf{W}_n \\bar{\\mathbf{x}} + b_n) \\in \\mathbb{R}^N \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\text{LL}^n - \\lambda n) \\\\\n \\text{or }q_\\text{corr}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n C^n - \\lambda n) \\text{ where }C^n = \\vert\\{t \\vert y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})\\}\\vert \\\\\n \\end{aligned}\n $$\nwhere $\\delta$ is\ndirac delta\n(unit impulse) function and $-\\lambda n$ is a regularization term to encourage lower layer exits. The ground truth $q^*$ can be prepared in two way, based on maximum likelihood $q_\\text{lik}^*$ or correctness $q_\\text{corr}^*$.\nToken-specific depth classifier (multinomial)\n: Each token is decoded with different exit block, predicted conditioned on the first decoder hidden state $\\mathbf{h}^1_t$:\n$$\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) = \\text{softmax}(\\mathbf{W}_n \\mathbf{h}^1_t + b_n)\n $$\nToken-specific depth classifier (geometric-like)\n:  A binary exit prediction distribution is made per layer per token, $\\mathcal{X}^n_t$. The RBF kernel $\\kappa(t, t’) = \\exp(\\frac{\\vert t - t’ \\vert^2}{\\sigma})$ is used to smooth the predictions to incorporate the impact of current decision on future time steps.\n$$\n \\begin{aligned}\n \\mathcal{X}^n_t &= \\text{sigmoid}(\\mathbf{w}_n^\\top \\mathbf{h}^n_t + b_n)\\quad \\forall n \\in [1, \\dots, N-1] \\\\\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) &= \\begin{cases}\n \\mathcal{X}^n_t \\prod_{n' < n} (1 - \\mathcal{X}^{n'}_t) & \\text{if } n < N\\\\\n \\prod_{n' < N} (1 - \\mathcal{X}^{n'}_t) & \\text{otherwise}\n \\end{cases} \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\widetilde{\\text{LL}}^n_t - \\lambda n) \\text{ where } \\widetilde{\\text{LL}}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') LL^n_{t'} \\\\\n \\text{or }q_\\text{cor}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\tilde{C}_t^n - \\lambda n) \\text{ where }C_t^n = \\mathbb{1}[y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})],\\; \\tilde{C}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') C^n_{t'} \\\\\n \\end{aligned}\n $$\nAt inference time, the confidence threshold for making an exit decision needs to be calibrated. Depth-adaptive transformer finds such a threshold on a validation set via grid search.\nCALM\n(\nSchuster et al. 2022\n) applied the Learn then Test (LTT) framework (\nAngelopoulos et al. 2021\n) to identify a subset of valid thresholds and chose the minimum value as the threshold for inference. Except for training per-layer exit classifier, CALM also explored other methods for adaptive depth prediction, including the softmax responses (i.e. difference between top two softmax outputs) and hidden state saturation (i.e. $\\cos(\\mathbf{h}^n_t, \\mathbf{h}^{n+1}_t)$) as confidence scores for exit decisions. They found softmax responses result in best inference speedup.\nEfficient Attention\n#\nThe computation and memory cost of the vanilla Transformer grows quadratically with sequence length and hence it is hard to be applied on very long sequences. Many efficiency improvements for Transformer architecture have something to do with the self-attention module - making it cheaper, smaller or faster to run. See the survey paper on\nEfficient Transformers\n(\nTay et al. 2020\n).\nSparse Attention Patterns\n#\nFixed Local Context\n#\nA simple alternation to make self-attention less expensive is to restrict the attention span of each token to\nlocal\ncontext only, so that self-attention grows linearly with the sequence length.\nThe idea was introduced by\nImage Transformer\n(\nParmer, et al 2018\n), which formulates image generation as sequence modeling using an encoder-decoder transformer architecture:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThen the decoder autoregressively generates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nStrided Context\n#\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn auto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\n A_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n \\end{aligned}\n $$\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\n A_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n \\end{aligned}\n $$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. $\\rightarrow$ This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details or my previous post on\ntechniques for scaling up model training\n.\nBlockwise Attention\n(\nQiu et al. 2019\n) introduces a\nsparse block matrix\nto only allow each token to attend to a small set of other tokens. Each attention matrix of size $L \\times L$ is partitioned into $n \\times n$ smaller blocks of size $\\frac{L}{n}\\times\\frac{L}{n}$ and a sparse block matrix $\\mathbf{M} \\in \\{0, 1\\}^{L \\times L}$ is defined by a permutation $\\pi$ of ${1, \\dots, n}$, which records the column index per row in the block matrix.\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) &= \\text{softmax}\\Big(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{d}} \\odot \\mathbf{M}\\Big)\\mathbf{V} \\\\\n(\\mathbf{A} \\odot \\mathbf{M})_{ij} &= \\begin{cases}\nA_{ij} & \\text{if }M_{ij} = 1 \\\\\n-\\infty & \\text{if }M_{ij} = 0 \\\\\n\\end{cases} \\\\\n\\text{where } M_{ij} &= \\begin{cases}\n1 & \\text{if }\\pi\\big(\\lfloor\\frac{(i-1)n}{L} + 1\\rfloor\\big) = \\lfloor\\frac{(j-1)n}{L} + 1\\rfloor \\\\\n0 & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nThe actual implementation of Blockwise Attention only stores QKV as block matrices, each of size $n\\times n$:\n$$\n\\text{Blockwise-attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) = \\begin{bmatrix}\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_1\\hat{\\mathbf{k}}_{\\pi(1)}^\\top}{\\sqrt{d}} \\Big)\\hat{\\mathbf{v}}_{\\pi(1)} \\\\\n\\vdots \\\\\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_n\\hat{\\mathbf{k}}_{\\pi(n)}^\\top}{\\sqrt{d}} \\odot \\Big)\\hat{\\mathbf{v}}_{\\pi(n)} \\\\\n\\end{bmatrix}\n$$\nwhere $\\hat{\\mathbf{q}}_i$, $\\hat{\\mathbf{k}}_i$ and $\\hat{\\mathbf{v}}_i$ are the $i$-the row in the QKV block matrix respectively. Each $\\mathbf{q}_i\\mathbf{k}_{\\pi(i)}^\\top, \\forall i = 1, \\dots, n$ is of size $\\frac{N}{n}\\times\\frac{N}{n}$ and therefore Blockwise Attention is able to reduce the memory complexity of attention matrix from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(\\frac{L}{n}\\times\\frac{L}{n} \\times n) = \\mathcal{O}(L^2/n)$.\nCombination of Local and Global Context\n#\nETC\n(\nExtended Transformer Construction\n;\nAinslie et al. 2019\n),\nLongformer\n(\nBeltagy et al. 2020\n) and\nBig Bird\n(\nZaheer et al. 2020\n) models combine both local and global context when building an attention matrix. All these models can be initialized from existing pretrained models.\nGlobal-Local Attention\nof\nETC\n(\nAinslie et al. 2019\n) takes two inputs, (1) the long input $\\mathbf{x}^l$ of size $n_l$ which is the regular input sequence and (2) the global input $\\mathbf{x}^g$ of size $n_g$ which contains a smaller number of auxiliary tokens, $n_g \\ll n_l$. Attention is thus split into four components based on directional attention across these two inputs: g2g, g2l, l2g and l2l. Because the l2l attention piece can be very large, it is restricted to a fixed size attention span of radius $w$ (i.e. local attention span) and the l2l matrix can be reshaped to $n_l \\times (2w+1)$.\nETC utilizes four binary matrices to handle structured inputs, $\\mathbf{M}^{g2g}$, $\\mathbf{M}^{g2l}$, $\\mathbf{M}^{l2g}$ and $\\mathbf{M}^{l2l}$. For example, each element $z^g_i \\in \\mathbb{R}^d$ in the attention output $z^g = (z^g_1, \\dots, z^g_{n_g})$ for g2g attention piece is formatted as:\n$$\n\\begin{aligned}\na^{g2g}_{ij} = \\frac{1}{\\sqrt{d}} x^g_i \\mathbf{W}^Q (x^g_j \\mathbf{W}^K + P^K_{ij})^\\top - (1- M^{g2g}_{ij})C \\\\\nA^{g2g}_{ij} = \\frac{\\exp(a^{g2g}_{ij})}{\\sum_{k=1}^{n_g} \\exp(a^{g2g}_{ik})} \\quad\nz^g_i = \\sum^{n_g}_{j=1} A^{g2g}_{ij} x^g_j \\mathbf{W}^V\n\\end{aligned}\n$$\nwhere $P^K_{ij}$ is a learnable vector for relative position encoding and $C$ is a very large constant ($C=10000$ in the paper) to offset any attention weights when mask is off.\nAttention patterns of ETC, Longformer and Big Bird.\nOne more update in ETC is to incorporate a CPC (contrastive predictive coding) task using\nNCE loss\ninto the pretraining stage, besides the\nMLM\ntask: The representation of one sentence should be similar to the representation of context around it when this sentence is masked.\nThe global input $\\mathbf{x}^g$ for ETC is constructed as follows: Assuming there are some segments within the long inputs (e.g. by sentence), each segment is attached with one auxiliary token to learn global inputs.\nRelative position encoding\nis used to mark the global segment tokens with the token position. Hard masking in one direction (i.e., tokens before vs after are labeled differently) is found to bring performance gains in some datasets.\nAttention pattern in Longformer contains three components:\nLocal attention\n: Similar to ETC, local attention is controlled by a sliding window of fixed size $w$;\nGlobal attention of preselected tokens\n: Longformer has a few pre-selected tokens (e.g.\n[CLS]\ntoken) assigned with global attention span, that is, attending to all other tokens in the input sequence.\nDilated attention\n: Dilated sliding window of fixed size $r$ and gaps of dilation size $d$, similar to Sparse Transformer;\nBig Bird\nis quite similar to Longformer, equipped with both local attention and a few preselected tokens with global attention span, but Big Bird replaces dilated attention with a new mechanism where all tokens attend to a set of random tokens. The design is motivated by the fact that attention pattern can be viewed as a\ndirected graph\nand a\nrandom graph\nhas the property that information is able to rapidly flow between any pair of nodes.\nLongformer\nuses smaller window size at lower layers and larger window sizes at higher layers. Ablation studies showed that this setup works better than reversed or fixed size config. Lower layers do not have dilated sliding windows to better learn to use immediate local context. Longformer also has a staged training procedure where initially the model is trained with small window size to learn from local context and then subsequent stages of training have window sizes increased and learning rate decreased.\nContent-based Attention\n#\nThe improvements proposed by\nReformer\n(\nKitaev, et al. 2020\n) aim to solve the following pain points in vanilla Transformer:\nQuadratic time and memory complexity within self-attention module.\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 20:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nRouting Transformer\n(\nRoy et al. 2021\n) is also built on content-based clustering of keys and queries. Instead of using a static hashing function like LSH, it utilizes online $k$-means clustering and combines it with local, temporal sparse attention to reduce the attention complexity from $O(L^2)$ to $O(L^{1.5})$.\nWithin routing attention, both keys and queries are clustered with $k$-means clustering method and the same set of centroids $\\boldsymbol{\\mu} = (\\mu_1, \\dots, \\mu_k) \\in \\mathbb{R}^{k \\times d}$. Queries are routed to keys that get assigned to the same centroid. The total complexity is $O(Lkd + L^2d/k)$, where $O(Lkd)$ is for running clustering assignments and $O(L^2d/k)$ is for attention computation. The cluster centroids are updated by EMA (exponential moving average) using all associated keys and queries.\nIn the experiments for Routing Transformer, some best config only has routing attention enabled in the last two layers of the model and half of the attention heads, while the other half utilizing local attention. They also observed that local attention is a pretty strong baseline and larger attention window always leads to better results.\nLow-Rank Attention\n#\nLinformer\n(\nWang et al. 2020\n) approximates the full attention matrix with a\nlow rank\nmatrix, reducing the time & space complexity to be\nlinear\n. Instead of using expensive SVD to identify low rank decomposition, Linformer adds two linear projections $\\mathbf{E}_i, \\mathbf{F}_i \\in \\mathbb{R}^{L \\times k}$ for key and value matrices, respectively, reducing their dimensions from $L \\times d$ to $k \\times d$. As long as $k \\ll L$, the attention memory can be greatly reduced.\n$$\n\\begin{aligned}\n\\overline{\\text{head}}_i \n&= \\text{attn}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{E}_i\\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{F}_i\\mathbf{X}_v\\mathbf{W}^v_i) \\\\\n&= \\underbrace{\\text{softmax}\\Big( \\frac{\\mathbf{X}_q\\mathbf{W}^q_i (\\mathbf{E}_i \\mathbf{X}_k\\mathbf{W}^k_i)^\\top}{\\sqrt{d}} \\Big)}_{\\text{low rank attention matrix }\\bar{A} \\in \\mathbb{R}^{k \\times d}} \\mathbf{F}_i \\mathbf{X}_v\\mathbf{W}^v_i\n\\end{aligned}\n$$\nAdditional techniques can be applied to further improve efficiency of Linformer:\nParameter sharing between projection layers, such as head-wise, key-value  and layer-wise (across all layers) sharing.\nUse different $k$ at different layers, as heads in higher layers tend to have a more skewed distribution (lower rank) and thus we can use smaller $k$ at higher layers.\nUse different types of projections; e.g. mean/max pooling, convolution layer with kernel and stride $L/k$.\n(Left) Informer has two projection layers added for keys and values. (Right) Plot of inference time as a function of sequence length. (Image source:\nWang et al. 2020\n).\nRandom Feature Attention\n(\nRFA\n;\nPeng et al. 2021\n) relies on\nrandom feature methods\n(\nRahimi & Recht, 2007\n) to approximate softmax operation in self-attention with low rank feature maps in order to achieve linear time and space complexity.\nPerformers\n(\nChoromanski et al. 2021\n) also adopts random feature attention with improvements on the kernel construction to further reduce the kernel approximation error.\nThe main theorem behind RFA is from\nRahimi & Recht, 2007\n:\nLet $\\phi: \\mathbb{R}^d \\to \\mathbb{R}^{2D}$ be a nonlinear transformation:\n$$\n\\phi(\\mathbf{x}) = \\frac{1}{\\sqrt{D}}[\\sin(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\sin(\\mathbf{w}_D^\\top \\mathbf{x}), \\cos(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\cos(\\mathbf{w}_D^\\top \\mathbf{x})]^\\top\n$$\nWhen $d$-dimensional random vectors $\\mathbf{w}_i$ are i.i.d. from $\\mathcal{N}(\\mathbf{0}, \\sigma^2\\mathbf{I}_d)$,\n$$\n\\mathbb{E}_{\\mathbf{w}_i} [\\phi(\\mathbf{x}) \\cdot \\phi(\\mathbf{y})] = \\exp(-\\frac{\\| \\mathbf{x} - \\mathbf{y} \\|^2}{2\\sigma^2})\n$$\nAn unbiased estimation of $\\exp(\\mathbf{x} \\cdot \\mathbf{y})$ is:\n$$\n\\begin{aligned}\n\\exp(\\mathbf{x} \\cdot \\mathbf{y} / \\sigma^2) \n&= \\exp(\\frac{1}{2\\sigma^2}(\\|\\mathbf{x}\\|^2 + \\|\\mathbf{y}\\|^2 - \\|\\mathbf{x} - \\mathbf{y}\\|^2) \\\\\n&= \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2}) ( - \\frac{\\|\\mathbf{x} - \\mathbf{y}\\|^2}{2\\sigma^2}) \\\\\n&\\approx \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) \\\\\n&= \\exp(\\frac{1}{\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) & \\text{; unit vectors}\n\\end{aligned}\n$$\nThen we can write the attention function as follows, where $\\otimes$ is outer product operation and $\\sigma^2$ is the temperature:\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\}) \n&= \\sum_i \\frac{\\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_i/\\sigma^2)}{\\sum_j \\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_j/\\sigma^2)}\\mathbf{v}_i^\\top\n\\approx \\sum_i \\frac{\\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_i)\\mathbf{v}_i^\\top}{\\sum_j \\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_j)} \\\\\n&= \\color{green}{\\frac{\\phi(\\mathbf{q}_t)^\\top \\sum_i \\phi(\\mathbf{k}_i)\\otimes\\mathbf{v}_i}{\\phi(\\mathbf{q}_t)^\\top \\sum_j \\phi(\\mathbf{k}_j)}\n= \\text{RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\})}\n\\end{aligned}\n$$\n(Left) The order of computation for default softmax operation. (Right) The order of computation when using random feature attention, a lot cheaper than default softmax. (Image source:\nPeng et al. 2021\n).\nCausal Attention RFA\nhas token at time step $t$ only attend to earlier keys and values $\\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}$. Let us use a tuple of variables, $(\\mathbf{S}_t \\in \\mathbb{R}^{2D \\times d}, \\mathbf{z} \\in \\mathbb{R}^{2D})$, to track the hidden state history at time step $t$, similar to RNNs:\n$$\n\\begin{aligned}\n&\\text{causal-RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}) = \\frac{\\phi(\\mathbf{q}_t)^\\top \\mathbf{S}_t}{\\phi(\\mathbf{q}_t) \\cdot \\mathbf{z}_t} \\\\\n&\\text{where } \n\\mathbf{S}_t = \\mathbf{S}_{t-1} + \\phi(\\mathbf{k}_t)\\otimes\\mathbf{v}_t,\n\\quad \n\\mathbf{z}_t = \\mathbf{z}_{t-1} + \\phi(\\mathbf{k}_t)\n\\end{aligned}\n$$\nwhere $2D$ is the size of $\\phi(.)$ and $D$ should be no less than the model size $d$ for reasonable approximation.\nRFA leads to significant speedup in autoregressive decoding and the memory complexity mainly depends on the choice of $D$ when constructing the kernel $\\phi(.)$.\nPerformer modifies the random feature attention with positive random feature maps to reduce the estimation error. It also keeps the randomly sampled $\\mathbf{w}_1, \\dots, \\mathbf{w}_D$ to be orthogonal to further reduce the variance of the estimator.\nComparison of approximation error when using (Left) i.i.d vs orthogonal features and (Right) sin/cos vs positive random features. (Image source:\nChoromanski et al. 2021\n).\nTransformers for Reinforcement Learning\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nDecision Transformer\n(\nDT\n;\nChen et al 2021\n) formulates Reinforcement Learning problems as a process of\nconditional sequence modeling\n, outputting the optimal actions conditioned on the desired return, past states and actions. It therefore becomes straightforward to use Transformer architecture. Decision Transformer is for\noff-policy RL\n, where the model only has access to a fixed collection of trajectories collected by other policies.\nTo encourage the model to learn how to act in order to achieve a desired return, it feeds the model with desired future return $\\hat{R} = \\sum_{t’=t}^T r_{t’}$ instead of the current reward. The trajectory consists of a list of triplets, (return-to-go $\\hat{R}_t, state $s_t$, action $a_t$), and it is used as an input sequence for Transformer:\n$$\n\\tau = (\\hat{R}_1, s_1, a_1, \\hat{R}_2, s_2, a_2, \\dots, \\hat{R}_T, s_T, a_T)\n$$\nThree linear layers are added and trained for return-to-go, state and action respectively to extract token embeddings. The prediction head learns to predict $a_t$ corresponding to the input token $s_t$. The training uses cross-entropy loss for discrete actions or MSE for continuous actions. Predicting the states or return-to-go was not found to help improve the performance in their experiments.\nThe experiments compared DT with several model-free RL algorithm baselines and showed that:\nDT is more efficient than behavior cloning in low data regime;\nDT can model the distribution of returns very well;\nHaving a long context is crucial for obtaining good results;\nDT can work with sparse rewards.\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2023). The transformer family version 2.0. Lil’Log. https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/.\nOr\n@article{weng2023transformer,\n  title   = \"The Transformer Family Version 2.0\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2023\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/\"\n}\nReferences\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).\n[13] Rae et al.\n“Compressive Transformers for Long-Range Sequence Modelling.”\n2019.\n[14] Press et al.\n“Train Short, Test Long: Attention With Linear Biases Enables Input Length Extrapolation.”\nICLR 2022.\n[15] Wu, et al.\n“DA-Transformer: Distance Aware Transformer”\n2021.\n[16] Elabyad et al.\n“Depth-Adaptive Transformer.”\nICLR 2020.\n[17] Schuster et al.\n“Confident Adaptive Language Modeling”\n2022.\n[18] Qiu et al.\n“Blockwise self-attention for long document understanding”\n2019\n[19] Roy et al.\n“Efficient Content-Based Sparse Attention with Routing Transformers.”\n2021.\n[20] Ainslie et al.\n“ETC: Encoding Long and Structured Inputs in Transformers.”\nEMNLP 2019.\n[21] Beltagy et al.\n“Longformer: The long-document transformer.”\n2020.\n[22] Zaheer et al.\n“Big Bird: Transformers for Longer Sequences.”\n2020.\n[23] Wang et al.\n“Linformer: Self-Attention with Linear Complexity.”\narXiv preprint arXiv:2006.04768 (2020).\n[24] Tay et al. 2020\n“Sparse Sinkhorn Attention.”\nICML 2020.\n[25] Peng et al.\n“Random Feature Attention.”\nICLR 2021.\n[26] Choromanski et al.\n“Rethinking Attention with Performers.”\nICLR 2021.\n[27] Khandelwal et al.\n“Generalization through memorization: Nearest neighbor language models.”\nICLR 2020.\n[28] Yogatama et al.\n“Adaptive semiparametric language models.”\nACL 2021.\n[29] Wu et al.\n“Memorizing Transformers.”\nICLR 2022.\n[30] Su et al.\n“Roformer: Enhanced transformer with rotary position embedding.”\narXiv preprint arXiv:2104.09864 (2021).\n[31] Shaw et al.\n“Self-attention with relative position representations.”\narXiv preprint arXiv:1803.02155 (2018).\n[32] Tay et al.\n“Efficient Transformers: A Survey.”\nACM Computing Surveys 55.6 (2022): 1-28.\n[33] Chen et al.,\n“Decision Transformer: Reinforcement Learning via Sequence Modeling”\narXiv preprint arXiv:2106.01345 (2021).",
            "metadata": {
              "title": "The Transformer Family Version 2.0 | Lil'Log",
              "description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "keywords": "architecture, attention, transformer, foundation, long-read, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family Version 2.0",
              "og:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family Version 2.0",
              "twitter:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "article:section": "posts",
              "article:published_time": "2023-01-27T00:00:00+00:00",
              "article:modified_time": "2023-01-27T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bd2a1c61491f/code/body-000.txt",
                "chars": 272,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-cfd86d1d041d4e587dd2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-57e8505d379090b6a5c2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-eb72333120a9bf61db22.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "bytes": 517373,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-94806f3485ee4c7d4137.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-10c3f7a4432b939f41e9.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "bytes": 110695,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9af813630ff27b91e9f8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "bytes": 104844,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-2d52fb35835b8ffb9f5c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "bytes": 441748,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-b512db56c30433d4c252.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "bytes": 81702,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-701853184c4d260333df.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "bytes": 75150,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-440b77c01199a8fa47a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "bytes": 308982,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-321a0b363e9a6d1aa98b.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-65f1b4ee283f16066c80.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f6d1acbfbe9a2ebc5720.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-6801941ec960782dbcdd.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-aa7a4901bbb57ffba3a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "bytes": 144593,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-61300c84161edec245ef.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-e33cbf677e130ee48f58.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f5d3b8b9ebc8beb78c77.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "bytes": 135708,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-30a7b1c7f2d502623782.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-528e7d446bed9aeb5917.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-08fa8454100a632db05c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "bytes": 296726,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-5fade868b98da3fc740e.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "bytes": 150541,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-1864a0421abec41db939.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "bytes": 300912,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9bbffc5733b6530c7240.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-8ed5854240a34aa93f46.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "“The Transformer Family”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02155",
                "label": "Shaw et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.09864",
                "label": "Su et al. 2021",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Rotation_matrix",
                "label": "rotation matrix",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05507",
                "label": "Rae et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00172",
                "label": "Khandelwal et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research/google-research/tree/master/scann",
                "label": "ScaNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2102.02557",
                "label": "Yogatama et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2203.08913",
                "label": "Wu et al. 2022",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2021.naacl-main.166",
                "label": "Wu, et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2108.12409",
                "label": "Press et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar et al (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10073",
                "label": "Elabyad et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2207.07061",
                "label": "Schuster et al. 2022",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dirac_delta_function",
                "label": "dirac delta",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2110.01052",
                "label": "Angelopoulos et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.06732",
                "label": "Tay et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
                "label": "techniques for scaling up model training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.02972",
                "label": "Qiu et al. 2019",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2020.emnlp-main.19/",
                "label": "Ainslie et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004/05150",
                "label": "Beltagy et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.14062",
                "label": "Zaheer et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "NCE loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_graph",
                "label": "directed graph",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Random_graph",
                "label": "random graph",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.05997",
                "label": "Roy et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.04768",
                "label": "Wang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.02143",
                "label": "Peng et al. 2021",
                "type": "a"
              },
              {
                "href": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "label": "Rahimi & Recht, 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.14794",
                "label": "Choromanski et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2106.01345",
                "label": "Chen et al 2021",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "off-policy RL",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.11296",
                "label": "“Sparse Sinkhorn Attention.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:12Z",
            "source_url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": false,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": false,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02155",
                "bytes": 235373,
                "reused": false,
                "local_path": "papers/repair/f32df5aeac8714d373be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": false,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.09864",
                "bytes": 599289,
                "reused": true,
                "local_path": "papers/repair/b64aa8c5e278403b64ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05507",
                "bytes": 584093,
                "reused": false,
                "local_path": "papers/repair/244ccad8664efd18e77c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00172",
                "bytes": 451453,
                "reused": false,
                "local_path": "papers/repair/43f160fbf0fa81d77393.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2102.02557",
                "bytes": 1018474,
                "reused": false,
                "local_path": "papers/repair/b5c9e91bd79c1b9ef250.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2203.08913",
                "bytes": 1047591,
                "reused": false,
                "local_path": "papers/repair/691204beb9e3b5b17a09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2108.12409",
                "bytes": 759030,
                "reused": true,
                "local_path": "papers/repair/238b286ab4f338940590.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": false,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": false,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": false,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10073",
                "bytes": 480824,
                "reused": false,
                "local_path": "papers/repair/929832372275e4ca6acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2207.07061",
                "bytes": 3006455,
                "reused": false,
                "local_path": "papers/repair/3e493b8dcc10d3f89436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2110.01052",
                "bytes": 2934353,
                "reused": false,
                "local_path": "papers/repair/f48952de2c7830ad0fc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.06732",
                "bytes": 847824,
                "reused": true,
                "local_path": "papers/repair/5442c18a5d3ec7c8eca5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": false,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": false,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.02972",
                "bytes": 716586,
                "reused": false,
                "local_path": "papers/repair/e8d64283562a841b64f9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/2004/05150",
                "retried_at": "2026-10-20T18:03:23Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.14062",
                "bytes": 1153823,
                "reused": false,
                "local_path": "papers/repair/f56d7d4a1317893ab3ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": false,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": false,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.05997",
                "bytes": 727287,
                "reused": false,
                "local_path": "papers/repair/d2f0607b565e49aa10fe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.04768",
                "bytes": 922879,
                "reused": false,
                "local_path": "papers/repair/f20cd0da3a7534f96d1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.02143",
                "bytes": 1241988,
                "reused": false,
                "local_path": "papers/repair/e438f2e0a286bcd79311.pdf"
              },
              {
                "status": "ok",
                "url": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "bytes": 488453,
                "reused": false,
                "local_path": "papers/repair/38e94b7d3685dc5b22d9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.14794",
                "bytes": 5880177,
                "reused": true,
                "local_path": "papers/repair/26948568ccf004004970.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": false,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": false,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2106.01345",
                "bytes": 704784,
                "reused": false,
                "local_path": "papers/repair/9e056437cb3e5b4f695d.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": false,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.11296",
                "bytes": 450138,
                "reused": true,
                "local_path": "papers/repair/0008d87e3417535c824a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 68430,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/bd2a1c61491f/pages/source.html",
            "local_html": "attachments/bd2a1c61491f/pages/article.html",
            "body_base_path": "attachments/bd2a1c61491f/pages/",
            "body_markdown_path": "attachments/bd2a1c61491f/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/TBA",
          "status": "http_404"
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
          "status": "partial",
          "article_id": "6d3d9dca0d80",
          "local_path": "series-follow/1602/repair/bc5c14725294dbccfbb0.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
              "bytes": 117546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/834dca5b0e8f45a5caae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
              "bytes": 2066932,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/db79205a3fdc6b1972ac.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
              "bytes": 330686,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f4bbdd9860111196027c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
              "bytes": 77027,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7663a2768e6a5304e97d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
              "bytes": 92546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c0097767c26c92046b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
              "bytes": 710268,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6a8653bd53396d46c1fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
              "bytes": 1618413,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ec2093ad281b035abb92.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
              "bytes": 292184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5c3e06f69064d46da7a3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
              "bytes": 372187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f8d914d42f0dceb916fe.png"
            }
          ],
          "article": {
            "id": "6d3d9dca0d80",
            "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "bytes": 117546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-834dca5b0e8f45a5caae.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "bytes": 2066932,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-db79205a3fdc6b1972ac.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "bytes": 330686,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f4bbdd9860111196027c.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "bytes": 77027,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-7663a2768e6a5304e97d.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "bytes": 92546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-c0097767c26c92046b06.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "bytes": 710268,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-6a8653bd53396d46c1fa.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "bytes": 1618413,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-ec2093ad281b035abb92.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "bytes": 292184,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-5c3e06f69064d46da7a3.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "bytes": 372187,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f8d914d42f0dceb916fe.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "I’ve never worked in the field of computer vision and has no idea how the magic could work when an autonomous car is configured to tell apart a stop sign from a pedestrian in a red hat. To motivate myself to look into the maths behind object recognition and detection algorithms, I’m writing a few posts on this topic “Object Detection for Dummies”. This post, part 1, starts with super rudimentary concepts in image processing and a few methods for image segmentation. Nothing related to deep neural networks yet. Deep learning models for object detection and recognition will be discussed in\nPart 2\nand\nPart 3\n.\nDisclaimer: When I started, I was using “object recognition” and “object detection” interchangeably. I don’t think they are the same: the former is more about telling whether an object exists in an image while the latter needs to spot where the object is. However, they are highly related and many object recognition algorithms lay the foundation for detection.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nImage Gradient Vector\n#\nFirst of all, I would like to make sure we can distinguish the following terms. They are very similar, closely related, but not exactly the same.\nDerivative\nDirectional Derivative\nGradient\nValue type\nScalar\nScalar\nVector\nDefinition\nThe rate of change of a function $f(x,y,z,…)$ at a point $(x_0,y_0,z_0,…)$, which is the slope of the tangent line at the point.\nThe instantaneous rate of change of $f(x,y,z, …)$ in the direction of an unit vector $\\vec{u}$.\nIt points in the direction of the greatest rate of increase of the function, containing all the partial derivative information of a multivariable function.\nIn the image processing, we want to know the direction of colors changing from one extreme to the other (i.e. black to white on a grayscale image). Therefore, we want to measure “gradient” on pixels of colors. The gradient on an image is discrete because each pixel is independent and cannot be further split.\nThe\nimage gradient vector\nis defined as a metric for every individual pixel, containing the pixel color changes in both x-axis and y-axis. The definition is aligned with the gradient of a continuous multi-variable function, which is a vector of partial derivatives of all the variables. Suppose f(x, y) records the color of the pixel at location (x, y), the gradient vector of the pixel (x, y) is defined as follows:\n$$\n\\begin{align*}\n\\nabla f(x, y)\n= \\begin{bmatrix}\n  g_x \\\\\n  g_y\n\\end{bmatrix}\n= \\begin{bmatrix}\n  \\frac{\\partial f}{\\partial x} \\\\[6pt]\n  \\frac{\\partial f}{\\partial y}\n\\end{bmatrix}\n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n\\end{align*}\n$$\nThe $\\frac{\\partial f}{\\partial x}$ term is the partial derivative on the x-direction, which is computed as the color difference between the adjacent pixels on the left and right of the target, f(x+1, y) - f(x-1, y). Similarly, the $\\frac{\\partial f}{\\partial y}$ term is the partial derivative on the y-direction, measured as f(x, y+1) - f(x, y-1), the color difference between the adjacent pixels above and below the target.\nThere are two important attributes of an image gradient:\nMagnitude\nis the L2-norm of the vector, $g = \\sqrt{ g_x^2 + g_y^2 }$.\nDirection\nis the arctangent of the ratio between the partial derivatives on two directions, $\\theta = \\arctan{(g_y / g_x)}$.\nTo compute the gradient vector of a target pixel at location (x, y), we need to know the colors of its four neighbors (or eight surrounding pixels depending on the kernel).\nThe gradient vector of the example in is:\n$$\n\\begin{align*}\n\\nabla f \n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n= \\begin{bmatrix}\n  55-105\\\\\n  90-40\n\\end{bmatrix}\n= \\begin{bmatrix}\n  -50\\\\\n  50\n\\end{bmatrix}\n\\end{align*}\n$$\nThus,\nthe magnitude is $\\sqrt{50^2 + (-50)^2} = 70.7107$, and\nthe direction is $\\arctan{(-50/50)} = -45^{\\circ}$.\nRepeating the gradient computation process for every pixel iteratively is too slow. Instead, it can be well translated into applying a convolution operator on the entire image matrix, labeled as $\\mathbf{A}$ using one of the specially designed convolutional kernels.\nLet’s start with the x-direction of the example in Fig 1. using the kernel $[-1,0,1]$ sliding over the x-axis; $\\ast$ is the convolution operator:\n$$\n\\begin{align*}\n\\mathbf{G}_x &= \n[-1, 0, 1] \\ast [105, 255, 55] = -105 + 0 + 55 = -50\n\\end{align*}\n$$\nSimilarly, on the y-direction, we adopt the kernel $[+1, 0, -1]^\\top$:\n$$\n\\begin{align*}\n\\mathbf{G}_y &= \n[+1, 0, -1]^\\top \\ast\n\\begin{bmatrix}\n  90\\\\\n  255\\\\\n  40\n\\end{bmatrix} \n= 90 + 0 - 40 = 50\n\\end{align*}\n$$\nTry this in python:\nimport\nnumpy\nas\nnp\nimport\nscipy.signal\nas\nsig\ndata\n=\nnp\n.\narray([[\n0\n,\n105\n,\n0\n], [\n40\n,\n255\n,\n90\n], [\n0\n,\n55\n,\n0\n]])\nG_x\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n,\n0\n,\n1\n]]), mode\n=\n'valid'\n)\nG_y\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n], [\n0\n], [\n1\n]]), mode\n=\n'valid'\n)\nThese two functions return\narray([[0], [-50], [0]])\nand\narray([[0, 50, 0]])\nrespectively. (Note that in the numpy array representation, 40 is shown in front of 90, so -1 is listed before 1 in the kernel correspondingly.)\nCommon Image Processing Kernels\n#\nPrewitt operator\n: Rather than only relying on four directly adjacent neighbors, the Prewitt operator utilizes eight surrounding pixels for smoother results.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-1 & 0 & +1 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +1 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -1 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nSobel operator\n: To emphasize the impact of directly adjacent pixels more, they get assigned with higher weights.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-2 & 0 & +2 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +2 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -2 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nDifferent kernels are created for different goals, such as edge detection, blurring, sharpening and many more. Check\nthis wiki page\nfor more examples and references.\nExample: Manu in 2004\n#\nLet’s run a simple experiment on the photo of Manu Ginobili in 2004 [[Download Image]({{ ‘/assets/data/manu-2004.jpg’ | relative_url }}){:target=\"_blank\"}] when he still had a lot of hair. For simplicity, the photo is converted to grayscale first. For colored images, we just need to repeat the same process in each color channel respectively.\nManu Ginobili in 2004 with hair. (Image source:\nManu Ginobili's bald spot through the years\n)\nimport\nnumpy\nas\nnp\nimport\nscipy\nimport\nscipy.signal\nas\nsig\n# With mode=\"L\", we force the image to be parsed in the grayscale, so it is\n# actually unnecessary to convert the photo color beforehand.\nimg\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2004.jpg\"\n, mode\n=\n\"L\"\n)\n# Define the Sobel operator kernels.\nkernel_x\n=\nnp\n.\narray([[\n-\n1\n,\n0\n,\n1\n],[\n-\n2\n,\n0\n,\n2\n],[\n-\n1\n,\n0\n,\n1\n]])\nkernel_y\n=\nnp\n.\narray([[\n1\n,\n2\n,\n1\n], [\n0\n,\n0\n,\n0\n], [\n-\n1\n,\n-\n2\n,\n-\n1\n]])\nG_x\n=\nsig\n.\nconvolve2d(img, kernel_x, mode\n=\n'same'\n)\nG_y\n=\nsig\n.\nconvolve2d(img, kernel_y, mode\n=\n'same'\n)\n# Plot them!\nfig\n=\nplt\n.\nfigure()\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\n# Actually plt.imshow() can handle the value scale well even if I don't do\n# the transformation (G_x + 255) / 2.\nax1\n.\nimshow((G_x\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax1\n.\nset_xlabel(\n\"Gx\"\n)\nax2\n.\nimshow((G_y\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax2\n.\nset_xlabel(\n\"Gy\"\n)\nplt\n.\nshow()\nApply Sobel operator kernel on the example image.\nYou might notice that most area is in gray. Because the difference between two pixel is between -255 and 255 and we need to convert them back to [0, 255] for the display purpose.\nA simple linear transformation ($\\mathbf{G}$ + 255)/2 would interpret all the zeros (i.e., constant colored background shows no change in gradient) as 125 (shown as gray).\nHistogram of Oriented Gradients (HOG)\n#\nThe Histogram of Oriented Gradients (HOG) is an efficient way to extract features out of the pixel colors for building an object recognition classifier. With the knowledge of image gradient vectors, it is not hard to understand how HOG works. Let’s start!\nHow HOG works\n#\nPreprocess the image, including resizing and color normalization.\nCompute the gradient vector of every pixel, as well as its magnitude and direction.\nDivide the image into many 8x8 pixel cells. In each cell, the magnitude values of these 64 cells are binned and cumulatively added into 9 buckets of unsigned direction (no sign, so 0-180 degree rather than 0-360 degree; this is a practical choice based on empirical experiments).\nFor better robustness, if the direction of the gradient vector of a pixel lays between two buckets, its magnitude does not all go into the closer one but proportionally split between two. For example, if a pixel’s gradient vector has magnitude 8 and degree 15, it is between two buckets for degree 0 and 20 and we would assign 2 to bucket 0 and 6 to bucket 20.\nThis interesting configuration makes the histogram much more stable when small distortion is applied to the image.\nHow to split one gradient vector's magnitude if its degress is between two degree bins. (Image source: https://www.learnopencv.com/histogram-of-oriented-gradients/)\nThen we slide a 2x2 cells (thus 16x16 pixels) block across the image. In each block region, 4 histograms of 4 cells are concatenated into one-dimensional vector of 36 values and then normalized to have an unit weight.\nThe final HOG feature vector is the concatenation of all the block vectors. It can be fed into a classifier like SVM for learning object recognition tasks.\nExample: Manu in 2004\n#\nLet’s reuse the same example image in the previous section. Remember that we have computed $\\mathbf{G}_x$ and $\\mathbf{G}_y$ for the whole image.\nN_BUCKETS\n=\n9\nCELL_SIZE\n=\n8\n# Each cell is 8x8 pixels\nBLOCK_SIZE\n=\n2\n# Each block is 2x2 cells\ndef\nassign_bucket_vals\n(m, d, bucket_vals):\nleft_bin\n=\nint(d\n/\n20.\n)\n# Handle the case when the direction is between [160, 180)\nright_bin\n=\n(int(d\n/\n20.\n)\n+\n1\n)\n%\nN_BUCKETS\nassert\n0\n<=\nleft_bin\n<\nright_bin\n<\nN_BUCKETS\nleft_val\n=\nm\n*\n(right_bin\n*\n20\n-\nd)\n/\n20\nright_val\n=\nm\n*\n(d\n-\nleft_bin\n*\n20\n)\n/\n20\nbucket_vals[left_bin]\n+=\nleft_val\nbucket_vals[right_bin]\n+=\nright_val\ndef\nget_magnitude_hist_cell\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target cell.\ncell_x\n=\nG_x[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\ncell_y\n=\nG_y[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\nmagnitudes\n=\nnp\n.\nsqrt(cell_x\n*\ncell_x\n+\ncell_y\n*\ncell_y)\ndirections\n=\nnp\n.\nabs(np\n.\narctan(cell_y\n/\ncell_x)\n*\n180\n/\nnp\n.\npi)\nbuckets\n=\nnp\n.\nlinspace(\n0\n,\n180\n, N_BUCKETS\n+\n1\n)\nbucket_vals\n=\nnp\n.\nzeros(N_BUCKETS)\nmap(\nlambda\n(m, d): assign_bucket_vals(m, d, bucket_vals),\nzip(magnitudes\n.\nflatten(), directions\n.\nflatten())\n)\nreturn\nbucket_vals\ndef\nget_magnitude_hist_block\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target block.\nreturn\nreduce(\nlambda\narr1, arr2: np\n.\nconcatenate((arr1, arr2)),\n[get_magnitude_hist_cell(x, y)\nfor\nx, y\nin\nzip(\n[loc_x, loc_x\n+\nCELL_SIZE, loc_x, loc_x\n+\nCELL_SIZE],\n[loc_y, loc_y, loc_y\n+\nCELL_SIZE, loc_y\n+\nCELL_SIZE],\n)]\n)\nThe following code simply calls the functions to construct a histogram and plot it.\n# Random location [200, 200] as an example.\nloc_x\n=\nloc_y\n=\n200\nydata\n=\nget_magnitude_hist_block(loc_x, loc_y)\nydata\n=\nydata\n/\nnp\n.\nlinalg\n.\nnorm(ydata)\nxdata\n=\nrange(len(ydata))\nbucket_names\n=\nnp\n.\ntile(np\n.\narange(N_BUCKETS), BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(ydata)\n==\nN_BUCKETS\n*\n(BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(bucket_names)\n==\nlen(ydata)\nplt\n.\nfigure(figsize\n=\n(\n10\n,\n3\n))\nplt\n.\nbar(xdata, ydata, align\n=\n'center'\n, alpha\n=\n0.8\n, width\n=\n0.9\n)\nplt\n.\nxticks(xdata, bucket_names\n*\n20\n, rotation\n=\n90\n)\nplt\n.\nxlabel(\n'Direction buckets'\n)\nplt\n.\nylabel(\n'Magnitude'\n)\nplt\n.\ngrid(ls\n=\n'--'\n, color\n=\n'k'\n, alpha\n=\n0.1\n)\nplt\n.\ntitle(\n\"HOG of block at [\n%d\n,\n%d\n]\"\n%\n(loc_x, loc_y))\nplt\n.\ntight_layout()\nIn the code above, I use the block with top left corner located at [200, 200] as an example and here is the final normalized histogram of this block. You can play with the code to change the block location to be identified by a sliding window.\nDemonstration of a HOG histogram for one block.\nThe code is mostly for demonstrating the computation process. There are many off-the-shelf libraries with HOG algorithm implemented, such as\nOpenCV\n,\nSimpleCV\nand\nscikit-image\n.\nImage Segmentation (Felzenszwalb’s Algorithm)\n#\nWhen there exist multiple objects in one image (true for almost every real-world photos), we need to identify a region that potentially contains a target object so that the classification can be executed more efficiently.\nFelzenszwalb and Huttenlocher (\n2004\n) proposed an algorithm for segmenting an image into similar regions using a graph-based approach. It is also the initialization method for Selective Search (a popular region proposal algorithm) that we are gonna discuss later.\nSay, we use a undirected graph $G=(V, E)$ to represent an input image. One vertex $v_i \\in V$ represents one pixel. One edge $e = (v_i, v_j) \\in E$ connects two vertices $v_i$ and $v_j$. Its associated weight $w(v_i, v_j)$ measures the dissimilarity between $v_i$ and $v_j$. The dissimilarity can be quantified in dimensions like color, location, intensity, etc. The higher the weight, the less similar two pixels are. A segmentation solution $S$ is a partition of $V$ into multiple connected components, $\\{C\\}$. Intuitively similar pixels should belong to the same components while dissimilar ones are assigned to different components.\nGraph Construction\n#\nThere are two approaches to constructing a graph out of an image.\nGrid Graph\n: Each pixel is only connected with surrounding neighbours (8 other cells in total). The edge weight is the absolute difference between the intensity values of the pixels.\nNearest Neighbor Graph\n: Each pixel is a point in the feature space (x, y, r, g, b), in which (x, y) is the pixel location and (r, g, b) is the color values in RGB. The weight is the Euclidean distance between two pixels’ feature vectors.\nKey Concepts\n#\nBefore we lay down the criteria for a good graph partition (aka image segmentation), let us define a couple of key concepts:\nInternal difference\n: $Int(C) = \\max_{e\\in MST(C, E)} w(e)$, where $MST$ is the minimum spanning tree of the components. A component $C$ can still remain connected even when we have removed all the edges with weights < $Int(C)$.\nDifference between two components\n: $Dif(C_1, C_2) = \\min_{v_i \\in C_1, v_j \\in C_2, (v_i, v_j) \\in E} w(v_i, v_j)$. $Dif(C_1, C_2) = \\infty$ if there is no edge in-between.\nMinimum internal difference\n: $MInt(C_1, C_2) = min(Int(C_1) + \\tau(C_1), Int(C_2) + \\tau(C_2))$, where $\\tau(C) = k / \\vert C \\vert$ helps make sure we have a meaningful threshold for the difference between components. With a higher $k$, it is more likely to result in larger components.\nThe quality of a segmentation is assessed by a pairwise region comparison predicate defined for given two regions $C_1$ and $C_2$:\n$$\nD(C_1, C_2) = \n\\begin{cases}\n  \\text{True} & \\text{ if } Dif(C_1, C_2) > MInt(C_1, C_2) \\\\\n  \\text{False} & \\text{ otherwise}\n\\end{cases}\n$$\nOnly when the predicate holds True, we consider them as two independent components; otherwise the segmentation is too fine and they probably should be merged.\nHow Image Segmentation Works\n#\nThe algorithm follows a bottom-up procedure. Given $G=(V, E)$ and $|V|=n, |E|=m$:\nEdges are sorted by weight in ascending order, labeled as $e_1, e_2, \\dots, e_m$.\nInitially, each pixel stays in its own component, so we start with $n$ components.\nRepeat for $k=1, \\dots, m$:\nThe segmentation snapshot at the step $k$ is denoted as $S^k$.\nWe take  the k-th edge in the order, $e_k = (v_i, v_j)$.\nIf $v_i$ and $v_j$ belong to the same component, do nothing and thus $S^k = S^{k-1}$.\nIf $v_i$ and $v_j$ belong to two different components $C_i^{k-1}$ and $C_j^{k-1}$ as in the segmentation $S^{k-1}$, we want to merge them into one if $w(v_i, v_j) \\leq MInt(C_i^{k-1}, C_j^{k-1})$; otherwise do nothing.\nIf you are interested in the proof of the segmentation properties and why it always exists, please refer to the\npaper\n.\nAn indoor scene with segmentation detected by the grid graph construction in Felzenszwalb's graph-based segmentation algorithm (k=300).\nExample: Manu in 2013\n#\nThis time I would use the photo of old Manu Ginobili in 2013 [[Image]({{ ‘/assets/data/manu-2013.jpg’ | relative_url }})] as the example image when his bald spot has grown up strong. Still for simplicity, we use the picture in grayscale.\nManu Ginobili in 2013 with bald spot. (Image source:\nManu Ginobili's bald spot through the years\n)\nRather than coding from scratch, let us apply\nskimage.segmentation.felzenszwalb\nto the image.\nimport\nskimage.segmentation\nfrom\nmatplotlib\nimport\npyplot\nas\nplt\nimg2\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2013.jpg\"\n, mode\n=\n\"L\"\n)\nsegment_mask1\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n100\n)\nsegment_mask2\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n1000\n)\nfig\n=\nplt\n.\nfigure(figsize\n=\n(\n12\n,\n5\n))\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\nax1\n.\nimshow(segment_mask1); ax1\n.\nset_xlabel(\n\"k=100\"\n)\nax2\n.\nimshow(segment_mask2); ax2\n.\nset_xlabel(\n\"k=1000\"\n)\nfig\n.\nsuptitle(\n\"Felsenszwalb's efficient graph based image segmentation\"\n)\nplt\n.\ntight_layout()\nplt\n.\nshow()\nThe code ran two versions of Felzenszwalb’s algorithms as shown in The left k=100 generates a finer-grained segmentation with small regions where Manu’s bald spot is identified. The right one k=1000 outputs a coarser-grained segmentation where regions tend to be larger.\nFelsenszwalb's efficient graph-based image segmentation is applied on the photo of Manu in 2013.\nSelective Search\n#\nSelective search is a common algorithm to provide region proposals that potentially contain objects. It is built on top of the image segmentation output and use region-based characteristics (NOTE: not just attributes of a single pixel) to do a bottom-up hierarchical grouping.\nHow Selective Search Works\n#\nAt the initialization stage, apply Felzenszwalb and Huttenlocher’s graph-based image segmentation algorithm to create regions to start with.\nUse a greedy algorithm to iteratively group regions together:\nFirst the similarities between all neighbouring regions are calculated.\nThe two most similar regions are grouped together, and new similarities are calculated between the resulting region and its neighbours.\nThe process of grouping the most similar regions (Step 2) is repeated until the whole image becomes a single region.\nThe detailed algorithm of Selective Search.\nConfiguration Variations\n#\nGiven two regions $(r_i, r_j)$, selective search proposed four complementary similarity measures:\nColor\nsimilarity\nTexture\n: Use algorithm that works well for material recognition such as\nSIFT\n.\nSize\n: Small regions are encouraged to merge early.\nShape\n: Ideally one region can fill the gap of the other.\nBy (i) tuning the threshold $k$ in Felzenszwalb and Huttenlocher’s algorithm, (ii) changing the color space and (iii) picking different combinations of similarity metrics, we can produce a diverse set of Selective Search strategies. The version that produces the region proposals with best quality is configured with (i) a mixture of various initial segmentation proposals, (ii) a blend of multiple color spaces and (iii) a combination of all similarity measures. Unsurprisingly we need to balance between the quality (the model complexity) and the speed.\nCited as:\n@article{weng2017detection1,\n  title   = \"Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/\"\n}\nReferences\n#\n[1] Dalal, Navneet, and Bill Triggs.\n“Histograms of oriented gradients for human detection.”\nComputer Vision and Pattern Recognition (CVPR), 2005.\n[2] Pedro F. Felzenszwalb, and Daniel P. Huttenlocher.\n“Efficient graph-based image segmentation.”\nIntl. journal of computer vision 59.2 (2004): 167-181.\n[3]\nHistogram of Oriented Gradients by Satya Mallick\n[4]\nGradient Vectors by Chris McCormick\n[5]\nHOG Person Detector Tutorial by Chris McCormick",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:55Z",
            "title": "Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/6d3d9dca0d80/code/body-000.txt",
                "chars": 239,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-001.txt",
                "chars": 840,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-002.txt",
                "chars": 1510,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-003.txt",
                "chars": 655,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-004.txt",
                "chars": 547,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-005.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "download_error",
                "url": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='cvcl.mit.edu', port=80): Max retries exceeded with url: /SUNSeminar/Felzenszwalb_IJCV04.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='cvcl.mit.e",
                "retried_at": "2026-10-20T22:24:59Z"
              },
              {
                "status": "ok",
                "url": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "bytes": 490132,
                "reused": true,
                "local_path": "papers/repair/e62fbcd20fd040b4335d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "bytes": 577941,
                "reused": true,
                "local_path": "papers/repair/93aa482d821738ade913.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:56:53Z"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20363,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/6d3d9dca0d80/pages/source.html",
            "local_html": "attachments/6d3d9dca0d80/pages/article.html",
            "body_base_path": "attachments/6d3d9dca0d80/pages/",
            "body_markdown_path": "attachments/6d3d9dca0d80/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_gradient",
                "label": "image gradient vector",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Prewitt_operator",
                "label": "Prewitt operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Sobel_operator",
                "label": "Sobel operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "this wiki page",
                "type": "a"
              },
              {
                "href": "http://ftw.usatoday.com/2013/05/manu-ginobilis-bald-spot-through-the-years",
                "label": "Manu Ginobili's bald spot through the years",
                "type": "a"
              },
              {
                "href": "https://github.com/opencv/opencv",
                "label": "OpenCV",
                "type": "a"
              },
              {
                "href": "http://simplecv.org/",
                "label": "SimpleCV",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/",
                "label": "scikit-image",
                "type": "a"
              },
              {
                "href": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "label": "2004",
                "type": "a"
              },
              {
                "href": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/docs/dev/api/skimage.segmentation.html",
                "label": "skimage.segmentation.felzenszwalb",
                "type": "a"
              },
              {
                "href": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "label": "SIFT",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "label": "“Histograms of oriented gradients for human detection.”",
                "type": "a"
              },
              {
                "href": "https://www.learnopencv.com/histogram-of-oriented-gradients/",
                "label": "Histogram of Oriented Gradients by Satya Mallick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/07/gradient-vectors/",
                "label": "Gradient Vectors by Chris McCormick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/09/hog-person-detector-tutorial/",
                "label": "HOG Person Detector Tutorial by Chris McCormick",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
          "status": "partial",
          "article_id": "b9468080b799",
          "local_path": "series-follow/1602/repair/93da665e04c347feb576.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
              "bytes": 788352,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4bea384db100fbf3fa0e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
              "bytes": 109138,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/227c6111eda2f97ab1f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
              "bytes": 3136069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b0d9d2dda61d5528b14d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
              "bytes": 437592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e837b0cac457a4dfa174.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
              "bytes": 269669,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/283d484fb68c4e61aa0b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
              "bytes": 27821,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c7816ecf6f5265465238.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
              "bytes": 432129,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9794f4d3172e6d7ec6e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
              "bytes": 855836,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ad16881681864ec9a905.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
              "bytes": 1600504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/db8216b190ed77df91ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
              "bytes": 98699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/de07b29467385da73bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
              "bytes": 1000184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/781e719388c2d1788151.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Object Detection for Dummies Part 3: R-CNN Family",
            "keywords": "目标检测,R-CNN,Faster R-CNN",
            "domain": "图像处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "publish_date": "2017-12",
            "corpus_stage": "预训练/SFT",
            "notes": "目标检测R-CNN家族综述",
            "id": "b9468080b799",
            "collected_at": "2026-10-02T14:13:33",
            "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
            "body_markdown": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n[Updated on 2018-12-27: Add\nbbox regression\nand\ntricks\nsections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in\nPart 1\n. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in\nPart 2\n. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nHere is a list of papers covered in this post ;)\nModel\nGoal\nResources\nR-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFast R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFaster R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nMask R-CNN\nImage segmentation\n[\npaper\n][\ncode\n]\nR-CNN\n#\nR-CNN (\nGirshick et al., 2014\n) is short for “Region-based Convolutional Neural Networks”. The main idea is composed of two steps. First, using\nselective search\n, it identifies a manageable number of bounding-box object region candidates (“region of interest” or “RoI”). And then it extracts CNN features from each region independently for classification.\nThe architecture of R-CNN. (Image source:\nGirshick et al., 2014\n)\nModel Workflow\n#\nHow R-CNN works can be summarized as follows:\nPre-train\na CNN network on image classification tasks; for example, VGG or ResNet trained on\nImageNet\ndataset. The classification task involves N classes.\nNOTE: You can find a pre-trained\nAlexNet\nin Caffe Model\nZoo\n. I don’t think you can\nfind it\nin Tensorflow, but Tensorflow-slim model\nlibrary\nprovides pre-trained ResNet, VGG, and others.\nPropose category-independent regions of interest by selective search (~2k candidates per image). Those regions may contain target objects and they are of different sizes.\nRegion candidates are\nwarped\nto have a fixed size as required by CNN.\nContinue fine-tuning the CNN on warped proposal regions for K + 1 classes; The additional one class refers to the background (no object of interest). In the fine-tuning stage, we should use a much smaller learning rate and the mini-batch oversamples the positive cases because most proposed regions are just background.\nGiven every image region, one forward propagation through the CNN generates a feature vector. This feature vector is then consumed by a\nbinary SVM\ntrained for\neach class\nindependently.\nThe positive samples are proposed regions with IoU (intersection over union) overlap threshold >= 0.3, and negative samples are irrelevant others.\nTo reduce the localization errors, a regression model is trained to correct the predicted detection window on bounding box correction offset using CNN features.\nBounding Box Regression\n#\nGiven a predicted bounding box coordinate $\\mathbf{p} = (p_x, p_y, p_w, p_h)$ (center coordinate, width, height) and its corresponding ground truth box coordinates $\\mathbf{g} = (g_x, g_y, g_w, g_h)$ , the regressor is configured to learn scale-invariant transformation between two centers and log-scale transformation between widths and heights. All the transformation functions take $\\mathbf{p}$ as input.\n$$\n\\begin{aligned}\n\\hat{g}_x &= p_w d_x(\\mathbf{p}) + p_x \\\\\n\\hat{g}_y &= p_h d_y(\\mathbf{p}) + p_y \\\\\n\\hat{g}_w &= p_w \\exp({d_w(\\mathbf{p})}) \\\\\n\\hat{g}_h &= p_h \\exp({d_h(\\mathbf{p})})\n\\end{aligned}\n$$\nIllustration of transformation between predicted and ground truth bounding boxes.\nAn obvious benefit of applying such transformation is that all the bounding box correction functions, $d_i(\\mathbf{p})$ where $i \\in \\{ x, y, w, h \\}$, can take any value between [-∞, +∞]. The targets for them to learn are:\n$$\n\\begin{aligned}\nt_x &= (g_x - p_x) / p_w \\\\\nt_y &= (g_y - p_y) / p_h \\\\\nt_w &= \\log(g_w/p_w) \\\\\nt_h &= \\log(g_h/p_h)\n\\end{aligned}\n$$\nA standard regression model can solve the problem by minimizing the SSE loss with regularization:\n$$\n\\mathcal{L}_\\text{reg} = \\sum_{i \\in \\{x, y, w, h\\}} (t_i - d_i(\\mathbf{p}))^2 + \\lambda \\|\\mathbf{w}\\|^2\n$$\nThe regularization term is critical here and RCNN paper picked the best λ by cross validation. It is also noteworthy that not all the predicted bounding boxes have corresponding ground truth boxes. For example, if there is no overlap, it does not make sense to run bbox regression. Here, only a predicted box with a nearby ground truth box with at least 0.6 IoU is kept for training the bbox regression model.\nCommon Tricks\n#\nSeveral tricks are commonly used in RCNN and other detection models.\nNon-Maximum Suppression\nLikely the model is able to find multiple bounding boxes for the same object. Non-max suppression helps avoid repeated detection of the same instance. After we get a set of matched bounding boxes for the same object category:\nSort all the bounding boxes by confidence score.\nDiscard boxes with low confidence scores.\nWhile\nthere is any remaining bounding box, repeat the following:\nGreedily select the one with the highest score.\nSkip the remaining boxes with high IoU (i.e. > 0.5) with previously selected one.\nMultiple bounding boxes detect the car in the image. After non-maximum suppression, only the best remains and the rest are ignored as they have large overlaps with the selected one. (Image source:\nDPM paper\n)\nHard Negative Mining\nWe consider bounding boxes without objects as negative examples. Not all the negative examples are equally hard to be identified. For example, if it holds pure empty background, it is likely an “\neasy negative\n”; but if the box contains weird noisy texture or partial object, it could be hard to be recognized and these are “\nhard negative\n”.\nThe hard negative examples are easily misclassified. We can explicitly find those false positive samples during the training loops and include them in the training data so as to improve the classifier.\nSpeed Bottleneck\n#\nLooking through the R-CNN learning steps, you could easily find out that training an R-CNN model is expensive and slow, as the following steps involve a lot of work:\nRunning selective search to propose 2000 region candidates for every image;\nGenerating the CNN feature vector for every image region (N images * 2000).\nThe whole process involves three models separately without much shared computation: the convolutional neural network for image classification and feature extraction; the top SVM classifier for identifying target objects; and the regression model for tightening region bounding boxes.\nFast R-CNN\n#\nTo make R-CNN faster, Girshick (\n2015\n) improved the training procedure by unifying three independent models into one jointly trained framework and increasing shared computation results, named\nFast R-CNN\n. Instead of extracting CNN feature vectors independently for each region proposal, this model aggregates them into one CNN forward pass over the entire image and the region proposals share this feature matrix. Then the same feature matrix is branched out to be used for learning the object classifier and the bounding-box regressor. In conclusion, computation sharing speeds up R-CNN.\nThe architecture of Fast R-CNN. (Image source:\nGirshick, 2015\n)\nRoI Pooling\n#\nIt is a type of max pooling to convert features in the projected region of the image of any size, h x w, into a small fixed window, H x W. The input region is divided into H x W grids, approximately every subwindow of size h/H x w/W. Then apply max-pooling in each grid.\nRoI pooling (Image source:\nStanford CS231n slides\n.)\nModel Workflow\n#\nHow Fast R-CNN works is summarized as follows; many steps are same as in R-CNN:\nFirst, pre-train a convolutional neural network on image classification tasks.\nPropose regions by selective search (~2k candidates per image).\nAlter the pre-trained CNN:\nReplace the last max pooling layer of the pre-trained CNN with a\nRoI pooling\nlayer. The RoI pooling layer outputs fixed-length feature vectors of region proposals. Sharing the CNN computation makes a lot of sense, as many region proposals of the same images are highly overlapped.\nReplace the last fully connected layer and the last softmax layer (K classes) with a fully connected layer and softmax over K + 1 classes.\nFinally the model branches into two output layers:\nA softmax estimator of K + 1 classes (same as in R-CNN, +1 is the “background” class), outputting a discrete probability distribution per RoI.\nA bounding-box regression model which predicts offsets relative to the original RoI for each of K classes.\nLoss Function\n#\nThe model is optimized for a loss combining two tasks (classification + localization):\n|\nSymbol\n|\nExplanation\n|\n| $u$ | True class label, $ u \\in 0, 1, \\dots, K$; by convention, the catch-all background class has $u = 0$. |\n| $p$ | Discrete probability distribution (per RoI) over K + 1 classes: $p = (p_0, \\dots, p_K)$, computed by a softmax over the K + 1 outputs of a fully connected layer. |\n| $v$ | True bounding box $ v = (v_x, v_y, v_w, v_h) $. |\n| $t^u$ | Predicted bounding box correction, $t^u = (t^u_x, t^u_y, t^u_w, t^u_h)$. See\nabove\n. |\n{:.info}\nThe loss function sums up the cost of classification and bounding box prediction: $\\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box}$. For “background” RoI, $\\mathcal{L}_\\text{box}$ is ignored by the indicator function $\\mathbb{1} [u \\geq 1]$, defined as:\n$$\n\\mathbb{1} [u >= 1] = \\begin{cases}\n    1  & \\text{if } u \\geq 1\\\\\n    0  & \\text{otherwise}\n\\end{cases}\n$$\nThe overall loss function is:\n$$\n\\begin{align*}\n\\mathcal{L}(p, u, t^u, v) &= \\mathcal{L}_\\text{cls} (p, u) + \\mathbb{1} [u \\geq 1] \\mathcal{L}_\\text{box}(t^u, v) \\\\\n\\mathcal{L}_\\text{cls}(p, u) &= -\\log p_u \\\\\n\\mathcal{L}_\\text{box}(t^u, v) &= \\sum_{i \\in \\{x, y, w, h\\}} L_1^\\text{smooth} (t^u_i - v_i)\n\\end{align*}\n$$\nThe bounding box loss $\\mathcal{L}_{box}$ should measure the difference between $t^u_i$ and $v_i$ using a\nrobust\nloss function. The\nsmooth L1 loss\nis adopted here and it is claimed to be less sensitive to outliers.\n$$\nL_1^\\text{smooth}(x) = \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases}\n$$\nThe plot of smooth L1 loss, $y = L\\_1^\\text{smooth}(x)$. (Image source:\nlink\n)\nSpeed Bottleneck\n#\nFast R-CNN is much faster in both training and testing time. However, the improvement is not dramatic because the region proposals are generated separately by another model and that is very expensive.\nFaster R-CNN\n#\nAn intuitive speedup solution is to integrate the region proposal algorithm into the CNN model.\nFaster R-CNN\n(\nRen et al., 2016\n) is doing exactly this: construct a single, unified model composed of RPN (region proposal network) and fast R-CNN with shared convolutional feature layers.\nAn illustration of Faster R-CNN model. (Image source:\nRen et al., 2016\n)\nModel Workflow\n#\nPre-train a CNN network on image classification tasks.\nFine-tune the RPN (region proposal network) end-to-end for the region proposal task, which is initialized by the pre-train image classifier. Positive samples have IoU (intersection-over-union) > 0.7, while negative samples have IoU < 0.3.\nSlide a small n x n spatial window over the conv feature map of the entire image.\nAt the center of each sliding window, we predict multiple regions of various scales and ratios simultaneously. An anchor is a combination of (sliding window center, scale, ratio). For example, 3 scales + 3 ratios => k=9 anchors at each sliding position.\nTrain a Fast R-CNN object detection model using the proposals generated by the current RPN\nThen use the Fast R-CNN network to initialize RPN training. While keeping the shared convolutional layers, only fine-tune the RPN-specific layers. At this stage, RPN and the detection network have shared convolutional layers!\nFinally fine-tune the unique layers of Fast R-CNN\nStep 4-5 can be repeated to train RPN and Fast R-CNN alternatively if needed.\nLoss Function\n#\nFaster R-CNN is optimized for a multi-task loss function, similar to fast R-CNN.\n|\nSymbol\n|\nExplanation\n|\n| $p_i$     | Predicted probability of anchor i being an object. |\n| $p^*_i$   | Ground truth label (binary) of whether anchor i is an object. |\n| $t_i$     | Predicted four parameterized coordinates. |\n| $t^*_i$   | Ground truth coordinates. |\n| $N_\\text{cls}$ | Normalization term, set to be mini-batch size (~256) in the paper. |\n| $N_\\text{box}$ | Normalization term, set to the number of anchor locations (~2400) in the paper. |\n| $\\lambda$ | A balancing parameter, set to be ~10 in the paper (so that both $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ terms are roughly equally weighted). |\n{:.info}\nThe multi-task loss function combines the losses of classification and bounding box regression:\n$$\n\\begin{align*}\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} \\\\\n\\mathcal{L}(\\{p_i\\}, \\{t_i\\}) &= \\frac{1}{N_\\text{cls}} \\sum_i \\mathcal{L}_\\text{cls} (p_i, p^*_i) + \\frac{\\lambda}{N_\\text{box}} \\sum_i p^*_i \\cdot L_1^\\text{smooth}(t_i - t^*_i) \\\\\n\\end{align*}\n$$\nwhere $\\mathcal{L}_\\text{cls}$ is the log loss function over two classes, as we can easily translate a multi-class classification into a binary classification by predicting a sample being a target object versus not. $L_1^\\text{smooth}$ is the smooth L1 loss.\n$$\n\\mathcal{L}_\\text{cls} (p_i, p^*_i) = - p^*_i \\log p_i - (1 - p^*_i) \\log (1 - p_i)\n$$\nMask R-CNN\n#\nMask R-CNN (\nHe et al., 2017\n) extends Faster R-CNN to pixel-level\nimage segmentation\n. The key point is to decouple the classification and the pixel-level mask prediction tasks. Based on the framework of\nFaster R-CNN\n, it added a third branch for predicting an object mask in parallel with the existing branches for classification and localization. The mask branch is a small fully-connected network applied to each RoI, predicting a segmentation mask in a pixel-to-pixel manner.\nMask R-CNN is Faster R-CNN model with image segmentation. (Image source:\nHe et al., 2017\n)\nBecause pixel-level segmentation requires much more fine-grained alignment than bounding boxes, mask R-CNN improves the RoI pooling layer (named “RoIAlign layer”) so that RoI can be better and more precisely mapped to the regions of the original image.\nPredictions by Mask R-CNN on COCO test set. (Image source:\nHe et al., 2017\n)\nRoIAlign\n#\nThe RoIAlign layer is designed to fix the location misalignment caused by quantization in the RoI pooling. RoIAlign removes the hash quantization, for example, by using x/16 instead of [x/16], so that the extracted features can be properly aligned with the input pixels.\nBilinear interpolation\nis used for computing the floating-point location values in the input.\nA region of interest is mapped **accurately** from the original image onto the feature map without rounding up to integers. (Image source:\nlink\n)\nLoss Function\n#\nThe multi-task loss function of Mask R-CNN combines the loss of classification, localization and segmentation mask: $ \\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} + \\mathcal{L}_\\text{mask}$, where $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ are same as in Faster R-CNN.\nThe mask branch generates a mask of dimension m x m for each RoI and each class; K classes in total. Thus, the total output is of size $K \\cdot m^2$. Because the model is trying to learn a mask for each class, there is no competition among classes for generating masks.\n$\\mathcal{L}_\\text{mask}$ is defined as the average binary cross-entropy loss, only including k-th mask if the region is associated with the ground truth class k.\n$$\n\\mathcal{L}_\\text{mask} = - \\frac{1}{m^2} \\sum_{1 \\leq i, j \\leq m} \\big[ y_{ij} \\log \\hat{y}^k_{ij} + (1-y_{ij}) \\log (1- \\hat{y}^k_{ij}) \\big]\n$$\nwhere $y_{ij}$ is the label of a cell (i, j) in the true mask for the region of size m x m; $\\hat{y}_{ij}^k$ is the predicted value of the same cell in the mask learned for the ground-truth class k.\nSummary of Models in the R-CNN family\n#\nHere I illustrate model designs of R-CNN, Fast R-CNN, Faster R-CNN and Mask R-CNN. You can track how one model evolves to the next version by comparing the small differences.\nCited as:\n@article{weng2017detection3,\n  title   = \"Object Detection for Dummies Part 3: R-CNN Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/\"\n}\nReference\n#\n[1] Ross Girshick, Jeff Donahue, Trevor Darrell, and Jitendra Malik.\n“Rich feature hierarchies for accurate object detection and semantic segmentation.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 580-587. 2014.\n[2] Ross Girshick.\n“Fast R-CNN.”\nIn Proc. IEEE Intl. Conf. on computer vision, pp. 1440-1448. 2015.\n[3] Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun.\n“Faster R-CNN: Towards real-time object detection with region proposal networks.”\nIn Advances in neural information processing systems (NIPS), pp. 91-99. 2015.\n[4] Kaiming He, Georgia Gkioxari, Piotr Dollár, and Ross Girshick.\n“Mask R-CNN.”\narXiv preprint arXiv:1703.06870, 2017.\n[5] Joseph Redmon, Santosh Divvala, Ross Girshick, and Ali Farhadi.\n“You only look once: Unified, real-time object detection.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 779-788. 2016.\n[6]\n“A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN”\nby Athelas.\n[7] Smooth L1 Loss:\nhttps://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
            "metadata": {
              "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
              "description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "keywords": "object-detection, object-recognition, vision-model",
              "author": "Lilian Weng",
              "og:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "og:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
              "twitter:card": "summary",
              "twitter:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "twitter:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "article:section": "posts",
              "article:published_time": "2017-12-31T00:00:00+00:00",
              "article:modified_time": "2017-12-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/b9468080b799/code/body-000.txt",
                "chars": 267,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "bytes": 788352,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-4bea384db100fbf3fa0e.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "bytes": 109138,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-227c6111eda2f97ab1f2.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "bytes": 3136069,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-b0d9d2dda61d5528b14d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "bytes": 437592,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-e837b0cac457a4dfa174.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "bytes": 269669,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-283d484fb68c4e61aa0b.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "bytes": 27821,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-c7816ecf6f5265465238.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "bytes": 432129,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-9794f4d3172e6d7ec6e1.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "bytes": 855836,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-ad16881681864ec9a905.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "bytes": 1600504,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-db8216b190ed77df91ef.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "bytes": 98699,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-de07b29467385da73bbf.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "bytes": 1000184,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-781e719388c2d1788151.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1311.2524",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1504.08083",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/fast-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.01497",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06870",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/CharlesShang/FastMaskRCNN",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://image-net.org/index",
                "label": "ImageNet",
                "type": "a"
              },
              {
                "href": "https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet",
                "label": "AlexNet",
                "type": "a"
              },
              {
                "href": "https://github.com/caffe2/caffe2/wiki/Model-Zoo",
                "label": "Zoo",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/issues/1394",
                "label": "find it",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/tree/master/research/slim",
                "label": "library",
                "type": "a"
              },
              {
                "href": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "label": "DPM paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1504.08083.pdf",
                "label": "2015",
                "type": "a"
              },
              {
                "href": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "label": "Stanford CS231n slides",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.01497.pdf",
                "label": "Ren et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06870.pdf",
                "label": "He et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bilinear_interpolation",
                "label": "Bilinear interpolation",
                "type": "a"
              },
              {
                "href": "https://blog.athelas.com/a-brief-history-of-cnns-in-image-segmentation-from-r-cnn-to-mask-r-cnn-34ea83205de4",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "label": "“Rich feature hierarchies for accurate object detection and semantic segmentation.”",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "label": "“Faster R-CNN: Towards real-time object detection with region proposal networks.”",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "“You only look once: Unified, real-time object detection.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:37Z",
            "source_url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1311.2524",
                "bytes": 6537772,
                "reused": false,
                "local_path": "papers/repair/5a971c9318fd8ef99b6d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/6389d2bce9bb81657bc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/713fc776568d336b3d68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/664bbc784da30edacdb6.pdf"
              },
              {
                "status": "http_404",
                "url": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "retried_at": "2026-10-20T18:02:44Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083.pdf",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/95f875d1b93587451953.pdf"
              },
              {
                "status": "ok",
                "url": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "bytes": 5264822,
                "reused": false,
                "local_path": "papers/repair/6704307d3926afe480a0.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": false,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497.pdf",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/9037a5243698d57ca173.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870.pdf",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/2f0eeff44085ec6f68ba.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "bytes": 1847626,
                "reused": false,
                "local_path": "papers/repair/99bf7bde4d6390550327.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "bytes": 761683,
                "reused": false,
                "local_path": "papers/repair/b13d014f28dadd2b7070.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": false,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 17566,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b9468080b799/pages/source.html",
            "local_html": "attachments/b9468080b799/pages/article.html",
            "body_base_path": "attachments/b9468080b799/pages/",
            "body_markdown_path": "attachments/b9468080b799/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
          "status": "partial",
          "article_id": "466144a71db1",
          "local_path": "series-follow/1602/repair/42584a00573758a53824.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
              "bytes": 947849,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7b981ee4ba3f0de9c69e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
              "bytes": 193831,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/d2d51b39b0c71b0793d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
              "bytes": 141158,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f004873880c2663f6f27.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
              "bytes": 285879,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b686cd210511644b9482.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
              "bytes": 862890,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/37c5aefd5995be6d0a22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
              "bytes": 155905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/4e81399abad9997ff29c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
              "bytes": 120909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/ac3a14a3f394f51725f0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
              "bytes": 1623681,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bf58d167b991ee5982f3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
              "bytes": 328470,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7b68e660a804f6fdedfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
              "bytes": 77640,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2a4ecbef4a9439ed154d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
              "bytes": 310680,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/955d0dc9f36806474855.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
              "bytes": 905917,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2098115c6b769573d03c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
              "bytes": 332323,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/90988a475dbc99affc49.png"
            }
          ],
          "article": {
            "id": "466144a71db1",
            "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "bytes": 947849,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b981ee4ba3f0de9c69e.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "bytes": 193831,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-d2d51b39b0c71b0793d1.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "bytes": 141158,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-f004873880c2663f6f27.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "bytes": 285879,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-b686cd210511644b9482.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "bytes": 862890,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-37c5aefd5995be6d0a22.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "bytes": 155905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-4e81399abad9997ff29c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "bytes": 120909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-ac3a14a3f394f51725f0.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "bytes": 1623681,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-bf58d167b991ee5982f3.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "bytes": 328470,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b68e660a804f6fdedfc.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "bytes": 77640,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2a4ecbef4a9439ed154d.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "bytes": 310680,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-955d0dc9f36806474855.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "bytes": 905917,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2098115c6b769573d03c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "bytes": 332323,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-90988a475dbc99affc49.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In\nPart 3\n, we have reviewed models in the R-CNN family. All of them are region-based object detection algorithms. They can achieve high accuracy but could be too slow for certain applications such as autonomous driving. In Part 4, we only focus on fast object detection models, including SSD, RetinaNet, and models in the YOLO family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nTwo-stage vs One-stage Detectors\n#\nModels in the R-CNN family are all region-based. The detection happens in two stages: (1) First, the model proposes a set of regions of interests by select search or regional proposal network. The proposed regions are sparse as the potential bounding box candidates can be infinite. (2) Then a classifier only processes the region candidates.\nThe other different approach skips the region proposal stage and runs detection directly over a dense sampling of possible locations. This is how a one-stage object detection algorithm works. This is faster and simpler, but might potentially drag down the performance a bit.\nAll the models introduced in this post are one-stage detectors.\nYOLO: You Only Look Once\n#\nThe\nYOLO\nmodel (\n“You Only Look Once”\n;\nRedmon et al., 2016\n) is the very first attempt at building a fast real-time object detector. Because YOLO does not undergo the region proposal step and only predicts over a limited number of bounding boxes, it is able to do inference super fast.\nWorkflow\n#\nPre-train\na CNN network on image classification task.\nSplit an image into $S \\times S$ cells. If an object’s center falls into a cell, that cell is “responsible” for detecting the existence of that object. Each cell predicts (a) the location of $B$ bounding boxes, (b) a confidence score, and (c) a probability of object class conditioned on the existence of an object in the bounding box.\nThe\ncoordinates\nof bounding box are defined by a tuple of 4 values, (center x-coord, center y-coord, width, height) — $(x, y, w, h)$, where $x$ and $y$ are set to be offset of a cell location. Moreover, $x$, $y$, $w$ and $h$ are normalized by the image width and height, and thus all between (0, 1].\nA\nconfidence score\nindicates the likelihood that the cell contains an object:\nPr(containing an object) x IoU(pred, truth)\n; where\nPr\n= probability and\nIoU\n= interaction under union.\nIf the cell contains an object, it predicts a\nprobability\nof this object belonging to every class $C_i, i=1, \\dots, K$:\nPr(the object belongs to the class C_i | containing an object)\n. At this stage, the model only predicts one set of class probabilities per cell, regardless of the number of bounding boxes, $B$.\nIn total, one image contains $S \\times S \\times B$ bounding boxes, each box corresponding to 4 location predictions, 1 confidence score, and K conditional probabilities for object classification. The total prediction values for one image is $S \\times S \\times (5B + K)$, which is the tensor shape of the final conv layer of the model.\nThe final layer of the pre-trained CNN is modified to output a prediction tensor of size $S \\times S \\times (5B + K)$.\nThe workflow of YOLO model. (Image source:\noriginal paper\n)\nNetwork Architecture\n#\nThe base model is similar to\nGoogLeNet\nwith inception module replaced by 1x1 and 3x3 conv layers. The final prediction of shape $S \\times S \\times (5B + K)$ is produced by two fully connected layers over the whole conv feature map.\nThe network architecture of YOLO.\nLoss Function\n#\nThe loss consists of two parts, the\nlocalization loss\nfor bounding box offset prediction and the\nclassification loss\nfor conditional class probabilities. Both parts are computed as the sum of squared errors. Two scale parameters are used to control how much we want to increase the loss from bounding box coordinate predictions ($\\lambda_\\text{coord}$) and how much we want to decrease the loss of confidence score predictions for boxes without objects ($\\lambda_\\text{noobj}$). Down-weighting the loss contributed by background boxes is important as most of the bounding boxes involve no instance. In the paper, the model sets $\\lambda_\\text{coord} = 5$ and $\\lambda_\\text{noobj} = 0.5$.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\lambda_\\text{coord} \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\mathbb{1}_{ij}^\\text{obj} [(x_i - \\hat{x}_i)^2 + (y_i - \\hat{y}_i)^2 + (\\sqrt{w_i} - \\sqrt{\\hat{w}_i})^2 + (\\sqrt{h_i} - \\sqrt{\\hat{h}_i})^2 ] \\\\\n\\mathcal{L}_\\text{cls}  &= \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\big( \\mathbb{1}_{ij}^\\text{obj} + \\lambda_\\text{noobj} (1 - \\mathbb{1}_{ij}^\\text{obj})\\big) (C_{ij} - \\hat{C}_{ij})^2 + \\sum_{i=0}^{S^2} \\sum_{c \\in \\mathcal{C}} \\mathbb{1}_i^\\text{obj} (p_i(c) - \\hat{p}_i(c))^2\\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{loc} + \\mathcal{L}_\\text{cls}\n\\end{aligned}\n$$\nNOTE: In the original YOLO paper, the loss function uses $C_i$ instead of $C_{ij}$ as confidence score. I made the correction based on my own understanding, since every bounding box should have its own confidence score. Please kindly let me if you do not agree. Many thanks.\nwhere,\n$\\mathbb{1}_i^\\text{obj}$: An indicator function of whether the cell i contains an object.\n$\\mathbb{1}_{ij}^\\text{obj}$: It indicates whether the j-th bounding box of the cell i is “responsible” for the object prediction (see Fig. 3).\n$C_{ij}$: The confidence score of cell i,\nPr(containing an object) * IoU(pred, truth)\n.\n$\\hat{C}_{ij}$: The predicted confidence score.\n$\\mathcal{C}$: The set of all classes.\n$p_i(c)$: The conditional probability of whether cell i contains an object of class $c \\in \\mathcal{C}$.\n$\\hat{p}_i(c)$: The predicted conditional class probability.\nAt one location, in cell i, the model proposes B bounding box candidates and the one that has highest overlap with the ground truth is the \"responsible\" predictor.\nThe loss function only penalizes classification error if an object is present in that grid cell, $\\mathbb{1}_i^\\text{obj} = 1$. It also only penalizes bounding box coordinate error if that predictor is “responsible” for the ground truth box, $\\mathbb{1}_{ij}^\\text{obj} = 1$.\nAs a one-stage object detector, YOLO is super fast, but it is not good at recognizing irregularly shaped objects or a group of small objects due to a limited number of bounding box candidates.\nSSD: Single Shot MultiBox Detector\n#\nThe\nSingle Shot Detector\n(\nSSD\n;\nLiu et al, 2016\n) is one of the first attempts at using convolutional neural network’s pyramidal feature hierarchy for efficient detection of objects of various sizes.\nImage Pyramid\n#\nSSD uses the\nVGG-16\nmodel pre-trained on ImageNet as its base model for extracting useful image features.\nOn top of VGG16, SSD adds several conv feature layers of decreasing sizes. They can be seen as a\npyramid representation\nof images at different scales. Intuitively large fine-grained feature maps at earlier levels are good at capturing small objects and small coarse-grained feature maps can detect large objects well. In SSD, the detection happens in every pyramidal layer, targeting at objects of various sizes.\nThe model architecture of SSD.\nWorkflow\n#\nUnlike YOLO, SSD does not split the image into grids of arbitrary size but predicts offset of predefined\nanchor boxes\n(this is called “default boxes” in the paper) for every location of the feature map. Each box has a fixed size and position relative to its corresponding cell. All the anchor boxes tile the whole feature map in a convolutional manner.\nFeature maps at different levels have different receptive field sizes. The anchor boxes on different levels are rescaled so that one feature map is only responsible for objects at one particular scale. For example, in Fig. 5 the dog can only be detected in the 4x4 feature map (higher level) while the cat is just captured by the 8x8 feature map (lower level).\nThe SSD framework. (a) The training data contains images and ground truth boxes for every object. (b) In a fine-grained feature maps (8 x 8), the anchor boxes of different aspect ratios correspond to smaller area of the raw input. (c) In a coarse-grained feature map (4 x 4), the anchor boxes cover larger area of the raw input. (Image source:\noriginal paper\n)\nThe width, height and the center location of an anchor box are all normalized to be (0, 1). At a location $(i, j)$ of the $\\ell$-th feature layer of size $m \\times n$, $i=1,\\dots,n, j=1,\\dots,m$, we have a unique linear scale proportional to the layer level and 5 different box aspect ratios (width-to-height ratios), in addition to a special scale (why we need this? the paper didn’t explain. maybe just a heuristic trick) when the aspect ratio is 1. This gives us 6 anchor boxes in total per feature cell.\n$$\n\\begin{aligned}\n\\text{level index: } &\\ell = 1, \\dots, L \\\\\n\\text{scale of boxes: } &s_\\ell = s_\\text{min} + \\frac{s_\\text{max} - s_\\text{min}}{L - 1} (\\ell - 1) \\\\\n\\text{aspect ratio: } &r \\in \\{1, 2, 3, 1/2, 1/3\\}\\\\\n\\text{additional scale: } & s'_\\ell = \\sqrt{s_\\ell s_{\\ell + 1}} \\text{ when } r = 1 \\text{thus, 6 boxes in total.}\\\\\n\\text{width: } &w_\\ell^r = s_\\ell \\sqrt{r} \\\\\n\\text{height: } &h_\\ell^r = s_\\ell / \\sqrt{r} \\\\\n\\text{center location: } & (x^i_\\ell, y^j_\\ell) = (\\frac{i+0.5}{m}, \\frac{j+0.5}{n})\n\\end{aligned}\n$$\nAn example of how the anchor box size is scaled up with the layer index $\\ell$ for $L=6, s\\_\\text{min} = 0.2, s\\_\\text{max} = 0.9$. Only the boxes of aspect ratio $r=1$ are illustrated.\nAt every location, the model outputs 4 offsets and $c$ class probabilities by applying a $3 \\times 3 \\times p$ conv filter (where $p$ is the number of channels in the feature map) for every one of $k$ anchor boxes. Therefore, given a feature map of size $m \\times n$, we need $kmn(c+4)$ prediction filters.\nLoss Function\n#\nSame as YOLO, the loss function is the sum of a localization loss and a classification loss.\n$\\mathcal{L} = \\frac{1}{N}(\\mathcal{L}_\\text{cls} + \\alpha \\mathcal{L}_\\text{loc})$\nwhere $N$ is the number of matched bounding boxes and $\\alpha$ balances the weights between two losses, picked by cross validation.\nThe\nlocalization loss\nis a\nsmooth L1 loss\nbetween the predicted bounding box correction and the true values. The coordinate correction transformation is same as what\nR-CNN\ndoes in\nbounding box regression\n.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\sum_{i,j} \\sum_{m\\in\\{x, y, w, h\\}} \\mathbb{1}_{ij}^\\text{match}\n L_1^\\text{smooth}(d_m^i - t_m^j)^2\\\\\nL_1^\\text{smooth}(x) &= \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases} \\\\\nt^j_x &= (g^j_x - p^i_x) / p^i_w \\\\\nt^j_y &= (g^j_y - p^i_y) / p^i_h \\\\\nt^j_w &= \\log(g^j_w / p^i_w) \\\\\nt^j_h &= \\log(g^j_h / p^i_h)\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{ij}^\\text{match}$ indicates whether the $i$-th bounding box with coordinates $(p^i_x, p^i_y, p^i_w, p^i_h)$ is matched to the $j$-th ground truth box with coordinates $(g^j_x, g^j_y, g^j_w, g^j_h)$ for any object. $d^i_m, m\\in\\{x, y, w, h\\}$ are the predicted correction terms. See\nthis\nfor how the transformation works.\nThe\nclassification loss\nis a softmax loss over multiple classes (\nsoftmax_cross_entropy_with_logits\nin tensorflow):\n$$\n\\mathcal{L}_\\text{cls} = -\\sum_{i \\in \\text{pos}} \\mathbb{1}_{ij}^k \\log(\\hat{c}_i^k) - \\sum_{i \\in \\text{neg}} \\log(\\hat{c}_i^0)\\text{, where }\\hat{c}_i^k = \\text{softmax}(c_i^k)\n$$\nwhere $\\mathbb{1}_{ij}^k$ indicates whether the $i$-th bounding box and the $j$-th ground truth box are matched for an object in class $k$. $\\text{pos}$ is the set of matched bounding boxes ($N$ items in total) and  $\\text{neg}$ is the set of negative examples. SSD uses\nhard negative mining\nto select easily misclassified negative examples to construct this $\\text{neg}$ set: Once all the anchor boxes are sorted by objectiveness confidence score, the model picks the top candidates for training so that neg:pos is at most 3:1.\nYOLOv2 / YOLO9000\n#\nYOLOv2\n(\nRedmon & Farhadi, 2017\n) is an enhanced version of YOLO.\nYOLO9000\nis built on top of YOLOv2 but trained with joint dataset combining the COCO detection dataset and the top 9000 classes from ImageNet.\nYOLOv2 Improvement\n#\nA variety of modifications are applied to make YOLO prediction more accurate and faster, including:\n1. BatchNorm helps\n: Add\nbatch norm\non all the convolutional layers, leading to significant improvement over convergence.\n2. Image resolution matters\n: Fine-tuning the base model with\nhigh resolution\nimages improves the detection performance.\n3. Convolutional anchor box detection\n: Rather than predicts the bounding box position with fully-connected layers over the whole feature map, YOLOv2 uses\nconvolutional layers\nto predict locations of\nanchor boxes\n, like in faster R-CNN. The prediction of spatial locations and class probabilities are decoupled. Overall, the change leads to a slight decrease in mAP, but an increase in recall.\n4. K-mean clustering of box dimensions\n: Different from faster R-CNN that uses hand-picked sizes of anchor boxes, YOLOv2 runs k-mean clustering on the training data to find good priors on anchor box dimensions. The distance metric is designed to\nrely on IoU scores\n:\n$$\n\\text{dist}(x, c_i) = 1 - \\text{IoU}(x, c_i), i=1,\\dots,k\n$$\nwhere $x$ is a ground truth box candidate and $c_i$ is one of the centroids. The best number of centroids (anchor boxes) $k$ can be chosen by the\nelbow method\n.\nThe anchor boxes generated by clustering provide better average IoU conditioned on a fixed number of boxes.\n5. Direct location prediction\n: YOLOv2 formulates the bounding box prediction in a way that it would\nnot diverge\nfrom the center location too much. If the box location prediction can place the box in any part of the image, like in regional proposal network, the model training could become unstable.\nGiven the anchor box of size $(p_w, p_h)$ at the grid cell with its top left corner at $(c_x, c_y)$, the model predicts the offset and the scale, $(t_x, t_y, t_w, t_h)$ and the corresponding predicted bounding box $b$ has center $(b_x, b_y)$ and size $(b_w, b_h)$. The confidence score is the sigmoid ($\\sigma$) of another output $t_o$.\n$$\n\\begin{aligned}\nb_x &= \\sigma(t_x) + c_x\\\\\nb_y &= \\sigma(t_y) + c_y\\\\\nb_w &= p_w e^{t_w}\\\\\nb_h &= p_h e^{t_h}\\\\\n\\text{Pr}(\\text{object}) &\\cdot \\text{IoU}(b, \\text{object}) = \\sigma(t_o)\n\\end{aligned}\n$$\nYOLOv2 bounding box location prediction. (Image source:\noriginal paper\n)\n6. Add fine-grained features\n: YOLOv2 adds a passthrough layer to bring\nfine-grained features\nfrom an earlier layer to the last output layer. The mechanism of this passthrough layer is similar to\nidentity mappings in ResNet\nto extract higher-dimensional features from previous layers. This leads to 1% performance increase.\n7. Multi-scale training\n: In order to train the model to be robust to input images of different sizes, a\nnew size\nof input dimension is\nrandomly sampled\nevery 10 batches. Since conv layers of YOLOv2 downsample the input dimension by a factor of 32, the newly sampled size is a multiple of 32.\n8. Light-weighted base model\n: To make prediction even faster, YOLOv2 adopts a light-weighted base model, DarkNet-19, which has 19 conv layers and 5 max-pooling layers. The key point is to insert avg poolings and 1x1 conv filters between 3x3 conv layers.\nYOLO9000: Rich Dataset Training\n#\nBecause drawing bounding boxes on images for object detection is much more expensive than tagging images for classification, the paper proposed a way to combine small object detection dataset with large ImageNet so that the model can be exposed to a much larger number of object categories. The name of YOLO9000 comes from the top 9000 classes in ImageNet. During joint training, if an input image comes from the classification dataset, it only backpropagates the classification loss.\nThe detection dataset has much fewer and more general labels and, moreover, labels cross multiple datasets are often not mutually exclusive. For example, ImageNet has a label “Persian cat” while in COCO the same image would be labeled as “cat”. Without mutual exclusiveness, it does not make sense to apply softmax over all the classes.\nIn order to efficiently merge ImageNet labels (1000 classes, fine-grained) with COCO/PASCAL (< 100 classes, coarse-grained), YOLO9000 built a hierarchical tree structure with reference to\nWordNet\nso that general labels are closer to the root and the fine-grained class labels are leaves. In this way, “cat” is the parent node of “Persian cat”.\nThe WordTree hierarchy merges labels from COCO and ImageNet. Blue nodes are COCO labels and red nodes are ImageNet labels. (Image source:\noriginal paper\n)\nTo predict the probability of a class node, we can follow the path from the node to the root:\nPr(\"persian cat\" | contain a \"physical object\") \n= Pr(\"persian cat\" | \"cat\") \n  Pr(\"cat\" | \"animal\") \n  Pr(\"animal\" | \"physical object\") \n  Pr(contain a \"physical object\")    # confidence score.\nNote that\nPr(contain a \"physical object\")\nis the confidence score, predicted separately in the bounding box detection pipeline. The path of conditional probability prediction can stop at any step, depending on which labels are available.\nRetinaNet\n#\nThe\nRetinaNet\n(\nLin et al., 2018\n) is a one-stage dense object detector. Two crucial building blocks are\nfeaturized image pyramid\nand the use of\nfocal loss\n.\nFocal Loss\n#\nOne issue for object detection model training is an extreme imbalance between background that contains no object and foreground that holds objects of interests.\nFocal loss\nis designed to assign more weights on hard, easily misclassified examples (i.e. background with noisy texture or partial object) and to down-weight easy examples (i.e. obviously empty background).\nStarting with a normal cross entropy loss for binary classification,\n$$\n\\text{CE}(p, y) = -y\\log p - (1-y)\\log(1-p)\n$$\nwhere $y \\in \\{0, 1\\}$ is a ground truth binary label, indicating whether a bounding box contains a object, and $p \\in [0, 1]$ is the predicted probability of objectiveness (aka confidence score).\nFor notational convenience,\n$$\n\\text{let } p_t = \\begin{cases}\np    & \\text{if } y = 1\\\\\n1-p  & \\text{otherwise}\n\\end{cases},\n\\text{then } \\text{CE}(p, y)=\\text{CE}(p_t) = -\\log p_t\n$$\nEasily classified examples with large $p_t \\gg 0.5$, that is, when $p$ is very close to 0 (when y=0) or 1 (when y=1), can incur a loss with non-trivial magnitude. Focal loss explicitly adds a weighting factor $(1-p_t)^\\gamma, \\gamma \\geq 0$ to each term in cross entropy so that the weight is small when $p_t$ is large and therefore easy examples are down-weighted.\n$$\n\\text{FL}(p_t) = -(1-p_t)^\\gamma \\log p_t\n$$\nThe focal loss focuses less on easy examples with a factor of $(1-p\\_t)^\\gamma$. (Image source:\noriginal paper\n)\nFor a better control of the shape of the weighting function (see Fig. 10.), RetinaNet uses an $\\alpha$-balanced variant of the focal loss, where $\\alpha=0.25, \\gamma=2$ works the best.\n$$\n\\text{FL}(p_t) = -\\alpha (1-p_t)^\\gamma \\log p_t\n$$\nThe plot of focal loss weights $\\alpha (1-p\\_t)^\\gamma$ as a function of $p\\_t$, given different values of $\\alpha$ and $\\gamma$.\nFeaturized Image Pyramid\n#\nThe\nfeaturized image pyramid\n(\nLin et al., 2017\n) is the backbone network for RetinaNet. Following the same approach by\nimage pyramid\nin SSD, featurized image pyramids provide a basic vision component for object detection at different scales.\nThe key idea of feature pyramid network is demonstrated in The base structure contains a sequence of\npyramid levels\n, each corresponding to one network\nstage\n. One stage contains multiple convolutional layers of the same size and the stage sizes are scaled down by a factor of 2. Let’s denote the last layer of the $i$-th stage as $C_i$.\nThe illustration of the featurized image pyramid module. (Replot based on figure 3 in\nFPN paper\n)\nTwo pathways connect conv layers:\nBottom-up pathway\nis the normal feedforward computation.\nTop-down pathway\ngoes in the inverse direction, adding coarse but semantically stronger feature maps back into the previous pyramid levels of a larger size via lateral connections.\nFirst, the higher-level features are upsampled spatially coarser to be 2x larger. For image upscaling, the paper used nearest neighbor upsampling. While there are many\nimage upscaling algorithms\nsuch as using\ndeconv\n, adopting another image scaling method might or might not improve the performance of RetinaNet.\nThe larger feature map undergoes a 1x1 conv layer to reduce the channel dimension.\nFinally, these two feature maps are merged by element-wise addition.\nThe lateral connections only happen at the last layer in stages, denoted as $\\{C_i\\}$, and the process continues until the finest (largest) merged feature map is generated. The prediction is made out of every merged map after a 3x3 conv layer, $\\{P_i\\}$.\nAccording to ablation studies, the importance rank of components of the featurized image pyramid design is as follows:\n1x1 lateral connection\n> detect object across multiple layers  > top-down enrichment > pyramid representation (compared to only check the finest layer).\nModel Architecture\n#\nThe featurized pyramid is constructed on top of the ResNet architecture. Recall that\nResNet\nhas 5 conv blocks (= network stages / pyramid levels). The last layer of the $i$-th pyramid level, $C_i$, has resolution $2^i$ lower than the raw input dimension.\nRetinaNet utilizes feature pyramid levels $P_3$ to $P_7$:\n$P_3$ to $P_5$ are computed from the corresponding ResNet residual stage from $C_3$ to $C_5$. They are connected by both top-down and bottom-up pathways.\n$P_6$ is obtained via a 3×3 stride-2 conv on top of $C_5$\n$P_7$ applies ReLU and a 3×3 stride-2 conv on $P_6$.\nAdding higher pyramid levels on ResNet improves the performance for detecting large objects.\nSame as in SSD, detection happens in all pyramid levels by making a prediction out of every merged feature map. Because predictions share the same classifier and the box regressor, they are all formed to have the same channel dimension d=256.\nThere are A=9 anchor boxes per level:\nThe base size corresponds to areas of $32^2$ to $512^2$ pixels on $P_3$ to $P_7$ respectively. There are three size ratios, $\\{2^0, 2^{1/3}, 2^{2/3}\\}$.\nFor each size, there are three aspect ratios {1/2, 1, 2}.\nAs usual, for each anchor box, the model outputs a class probability for each of $K$ classes in the classification subnet and regresses the offset from this anchor box to the nearest ground truth object in the box regression subnet. The classification subnet adopts the focal loss introduced above.\nThe RetinaNet model architecture uses a\nFPN\nbackbone on top of ResNet. (Image source: the\nFPN\npaper)\nYOLOv3\n#\nYOLOv3\nis created by applying a bunch of design tricks on YOLOv2. The changes are inspired by recent advances in the object detection world.\nHere are a list of changes:\n1. Logistic regression for confidence scores\n: YOLOv3 predicts an confidence score for each bounding box using\nlogistic regression\n, while YOLO and YOLOv2 uses sum of squared errors for classification terms (see the\nloss function\nabove). Linear regression of offset prediction leads to a decrease in mAP.\n2. No more softmax for class prediction\n: When predicting class confidence, YOLOv3 uses\nmultiple independent logistic classifier\nfor each class rather than one softmax layer. This is very helpful especially considering that one image might have multiple labels and not all the labels are guaranteed to be mutually exclusive.\n3. Darknet + ResNet as the base model\n: The new Darknet-53 still relies on successive 3x3 and 1x1 conv layers, just like the original dark net architecture, but has residual blocks added.\n4. Multi-scale prediction\n: Inspired by image pyramid, YOLOv3 adds several conv layers after the base feature extractor model and makes prediction at three different scales among these conv layers. In this way, it has to deal with many more bounding box candidates of various sizes overall.\n5. Skip-layer concatenation\n: YOLOv3 also adds cross-layer connections between two prediction layers (except for the output layer) and earlier finer-grained feature maps. The model first up-samples the coarse feature maps and then merges it with the previous features by concatenation. The combination with finer-grained information makes it better at detecting small objects.\nInterestingly, focal loss does not help YOLOv3, potentially it might be due to the usage of $\\lambda_\\text{noobj}$ and $\\lambda_\\text{coord}$ — they increase the loss from bounding box location predictions and decrease the loss from confidence predictions for background boxes.\nOverall YOLOv3 performs better and faster than SSD, and worse than RetinaNet but 3.8x faster.\nThe comparison of various fast object detection models on speed and mAP performance. (Image source:\nfocal loss\npaper with additional labels from the\nYOLOv3\npaper.)\nCited as:\n@article{weng2018detection4,\n  title   = \"Object Detection Part 4: Fast Detection Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/\"\n}\nReference\n#\n[1] Joseph Redmon, et al.\n“You only look once: Unified, real-time object detection.”\nCVPR 2016.\n[2] Joseph Redmon and Ali Farhadi.\n“YOLO9000: Better, Faster, Stronger.”\nCVPR 2017.\n[3] Joseph Redmon, Ali Farhadi.\n“YOLOv3: An incremental improvement.”\n.\n[4] Wei Liu et al.\n“SSD: Single Shot MultiBox Detector.”\nECCV 2016.\n[5] Tsung-Yi Lin, et al.\n“Feature Pyramid Networks for Object Detection.”\nCVPR 2017.\n[6] Tsung-Yi Lin, et al.\n“Focal Loss for Dense Object Detection.”\nIEEE transactions on pattern analysis and machine intelligence, 2018.\n[7]\n“What’s new in YOLO v3?”\nby  Ayoosh Kathuria on “Towards Data Science”, Apr 23, 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:43Z",
            "title": "Object Detection Part 4: Fast Detection Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/466144a71db1/code/body-000.txt",
                "chars": 195,
                "language": "text"
              },
              {
                "file": "attachments/466144a71db1/code/body-001.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": true,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "retried_at": "2026-10-20T17:55:04Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.02325",
                "bytes": 2494225,
                "reused": true,
                "local_path": "papers/repair/b5f5e9ca4f7f92190f2f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.1556",
                "bytes": 200010,
                "reused": true,
                "local_path": "papers/repair/01560c40deef0c339e01.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": true,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.08242",
                "bytes": 5256083,
                "reused": true,
                "local_path": "papers/repair/1288fc7e9385e0345e39.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02002",
                "bytes": 1297358,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c9512e3ffac1aabce76e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.03144",
                "bytes": 789142,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0cd1e11096f8a72ff39b.pdf"
              },
              {
                "status": "ok",
                "url": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "bytes": 2241388,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5bc4175dabe4accf71a9.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "bytes": 5392639,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/edb99b1cb9792a271703.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25701,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/466144a71db1/pages/source.html",
            "local_html": "attachments/466144a71db1/pages/article.html",
            "body_base_path": "attachments/466144a71db1/pages/",
            "body_markdown_path": "attachments/466144a71db1/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "Redmon et al., 2016",
                "type": "a"
              },
              {
                "href": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "label": "GoogLeNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.02325",
                "label": "Liu et al, 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.1556",
                "label": "VGG-16",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits",
                "label": "softmax_cross_entropy_with_logits",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.08242",
                "label": "Redmon & Farhadi, 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Elbow_method_(clustering)",
                "label": "elbow method",
                "type": "a"
              },
              {
                "href": "https://wordnet.princeton.edu/",
                "label": "WordNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02002",
                "label": "Lin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.03144",
                "label": "Lin et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_scaling",
                "label": "image upscaling algorithms",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/layers/conv2d_transpose",
                "label": "deconv",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/TBA",
                "label": "ResNet",
                "type": "a"
              },
              {
                "href": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "label": "YOLOv3",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "label": "“YOLO9000: Better, Faster, Stronger.”",
                "type": "a"
              },
              {
                "href": "https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b",
                "label": "“What’s new in YOLO v3?”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
          "status": "partial",
          "article_id": "e63a1e66232d",
          "local_path": "series-follow/1602/repair/b1aa14adf7d8adb2ac0a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
              "bytes": 189766,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/afc61371a02b455239c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
              "bytes": 13941,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9d81c38b488b3632ed8d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
              "bytes": 339657,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c3b89516ea58d513c6e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
              "bytes": 46457,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5e6d7c0353c6dcedff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
              "bytes": 55893,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7f08154f4714c6af05cf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
              "bytes": 77504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/c47361447354e9dc9408.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
              "bytes": 141447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/128df9c78ce434cf9940.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
              "bytes": 42173,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/f5c3b685a188e7a1f7ea.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
              "bytes": 87321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bb941fda00c0e424d832.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
              "bytes": 1969955,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/1c06e799c7666968bc4d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
              "bytes": 709079,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/35ad6bb4c9b5f2023552.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
              "bytes": 313503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/69879f285ee667db6764.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
              "bytes": 157401,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/2ee071176ef01990b7b2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
              "bytes": 134727,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/b639597a6e7d3aecf854.png"
            }
          ],
          "article": {
            "id": "e63a1e66232d",
            "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "bytes": 189766,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-afc61371a02b455239c2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "bytes": 13941,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-9d81c38b488b3632ed8d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "bytes": 339657,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c3b89516ea58d513c6e4.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "bytes": 46457,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-5e6d7c0353c6dcedff22.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "bytes": 55893,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-7f08154f4714c6af05cf.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "bytes": 77504,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c47361447354e9dc9408.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "bytes": 141447,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-128df9c78ce434cf9940.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "bytes": 42173,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-f5c3b685a188e7a1f7ea.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "bytes": 87321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-bb941fda00c0e424d832.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "bytes": 1969955,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-1c06e799c7666968bc4d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "bytes": 709079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-35ad6bb4c9b5f2023552.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "bytes": 313503,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-69879f285ee667db6764.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "bytes": 157401,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-2ee071176ef01990b7b2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "bytes": 134727,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-b639597a6e7d3aecf854.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=vFr3K2DORc8",
                "src": "https://youtu.be/vFr3K2DORc8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-vFr3K2DORc8.mp4",
                "bytes": 753957028,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "14106.021000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=F1ka6a13S9I",
                "src": "https://youtu.be/F1ka6a13S9I",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-F1ka6a13S9I.mp4",
                "bytes": 456526601,
                "valid": true,
                "height": 720,
                "width": 1280,
                "duration": "4787.481000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=uAu3jQWaN6E",
                "src": "https://youtu.be/uAu3jQWaN6E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-uAu3jQWaN6E.mp4",
                "bytes": 183061332,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "438.401000",
                "reused": false
              }
            ],
            "body_markdown": "(The post was originated from my talk for\nWiMLDS x Fintech meetup\nhosted by\nAffirm\n.)\nI believe many of you have watched or heard of the\ngames\nbetween AlphaGo and professional Go player\nLee Sedol\nin 2016. Lee has the highest rank of nine dan and many world championships. No doubt, he is one of the best Go players in the world, but he\nlost by 1-4\nin this series versus AlphaGo. Before this, Go was considered to be an intractable game for computers to master, as its simple rules lay out an exponential number of variations in the board positions, many more than what in Chess. This event surely highlighted 2016 as a big year for AI. Because of AlphaGo, much attention has been attracted to the progress of AI.\nMeanwhile, many companies are spending resources on pushing the edges of AI applications, that indeed have the potential to change or even revolutionize how we are gonna live. Familiar examples include self-driving cars, chatbots, home assistant devices and many others. One of the secret receipts behind the progress we have had in recent years is deep learning.\nWhy Does Deep Learning Work Now?\n#\nDeep learning models, in simple words, are large and deep artificial neural nets. A neural network (“NN”) can be well presented in a\ndirected acyclic graph\n: the input layer takes in signal vectors; one or multiple hidden layers process the outputs of the previous layer. The initial concept of a neural network can be traced back to more than\nhalf a century ago\n. But why does it work now? Why do people start talking about them all of a sudden?\nA three-layer artificial neural network. (Image source:\nhttp://cs231n.github.io/convolutional-networks/#conv\n)\nThe reason is surprisingly simple:\nWe have a lot\nmore data\n.\nWe have\nmuch powerful computers\n.\nA large and deep neural network has many more layers + many more nodes in each layer, which results in exponentially many more parameters to tune. Without enough data, we cannot learn parameters efficiently. Without powerful computers, learning would be too slow and insufficient.\nHere is an interesting plot presenting the relationship between the data scale and the model performance, proposed by Andrew Ng in his “\nNuts and Bolts of Applying Deep Learning\n” talk. On a small dataset, traditional algorithms (Regression, Random Forests, SVM, GBM, etc.) or statistical learning does a great job, but once the data scale goes up to the sky, the large NN outperforms others. Partially because compared to a traditional ML model, a neural network model has many more parameters and has the capability to learn complicated nonlinear patterns. Thus we expect the model to pick the most helpful features by itself without too much expert-involved manual feature engineering.\nThe data scale versus the model performance. (Recreated based on:\nhttps://youtu.be/F1ka6a13S9I\n)\nDeep Learning Models\n#\nNext, let’s go through a few classical deep learning models.\nConvolutional Neural Network\n#\nConvolutional neural networks, short for “CNN”, is a type of feed-forward artificial neural networks, in which the connectivity pattern between its neurons is inspired by the organization of the visual cortex system. The primary visual cortex (V1) does edge detection out of the raw visual input from the retina. The secondary visual cortex (V2), also called prestriate cortex, receives the edge features from V1 and extracts simple visual properties such as orientation, spatial frequency, and color. The visual area V4 handles more complicated object attributes. All the processed visual features flow into the final logic unit, inferior temporal gyrus (IT), for object recognition. The shortcut between V1 and V4 inspires a special type of CNN with connections between non-adjacent layers: Residual Net (\nHe, et al. 2016\n) containing “Residual Block” which supports some input of one layer to be passed to the component two layers later.\nIllustration of the human visual cortex system. (Image source:\nWang & Raj 2017\n)\nConvolution is a mathematical term, here referring to an operation between two matrices. The convolutional layer has a fixed small matrix defined, also called kernel or filter. As the kernel is sliding, or convolving, across the matrix representation of the input image, it is computing the element-wise multiplication of the values in the kernel matrix and the original image values.\nSpecially designed kernels\ncan process images for common purposes like blurring, sharpening, edge detection and many others, fast and efficiently.\nThe LeNet architecture consists of two sets of convolutional, activation, and pooling layers, followed by a fully-connected layer, activation, another fully-connected layer, and finally a softmax classifier (Image source:\nhttp://deeplearning.net/tutorial/lenet.html\n)\nConvolutional\nand\npooling\n(or “sub-sampling” in Fig. 4) layers act like the V1, V2 and V4 visual cortex units, responding to feature extraction. The object recognition reasoning happens in the later fully-connected layers which consume the extracted features.\nRecurrent Neural Network\n#\nA sequence model is usually designed to transform an input sequence into an output sequence that lives in a different domain. Recurrent neural network, short for “RNN”, is suitable for this purpose and has shown tremendous improvement in problems like handwriting recognition, speech recognition, and machine translation (\nSutskever et al. 2011\n,\nLiwicki et al. 2007\n).\nA recurrent neural network model is born with the capability to process long sequential data and to tackle tasks with context spreading in time. The model processes one element in the sequence at one time step. After computation, the newly updated unit state is passed down to the next time step to facilitate the computation of the next element. Imagine the case when an RNN model reads all the Wikipedia articles, character by character, and then it can predict the following words given the context.\nA recurrent neural network with one hidden unit (left) and its unrolling version in time (right). The unrolling version illustrates what happens in time: $s\\_{t-1}$, $s\\_{t}$, and $s\\_{t+1}$ are the same unit with different states at different time steps $t-1$, $t$, and $t+1$. (Image source:\nLeCun, Bengio, and Hinton, 2015\n;\nFig. 5\n)\nHowever, simple perceptron neurons that linearly combine the current input element and the last unit state may easily lose the long-term dependencies. For example, we start a sentence with “Alice is working at …” and later after a whole paragraph, we want to start the next sentence with “She” or “He” correctly. If the model forgets the character’s name “Alice”, we can never know. To resolve the issue, researchers created a special neuron with a much more complicated internal structure for memorizing long-term context, named\n“Long-short term memory (LSTM)”\ncell. It is smart enough to learn for how long it should memorize the old information, when to forget, when to make use of the new data, and how to combine the old memory with new input. This\nintroduction\nis so well written that I recommend everyone with interest in LSTM to read it. It has been officially promoted in the\nTensorflow documentation\n;-)\nThe structure of a LSTM cell. (Image source:\nhttp://colah.github.io/posts/2015-08-Understanding-LSTMs\n)\nTo demonstrate the power of RNNs,\nAndrej Karpathy\nbuilt a character-based language model using RNN with LSTM cells.  Without knowing any English vocabulary beforehand, the model could learn the relationship between characters to form words and then the relationship between words to form sentences. It could achieve a decent performance even without a huge set of training data.\nA character-based recurrent neural network model writes like a Shakespeare. (Image source:\nhttp://karpathy.github.io/2015/05/21/rnn-effectiveness\n)\nRNN: Sequence-to-Sequence Model\n#\nThe\nsequence-to-sequence model\nis an extended version of RNN, but its application field is distinguishable enough that I would like to list it in a separated section. Same as RNN, a sequence-to-sequence model operates on sequential data, but particularly it is commonly used to develop chatbots or personal assistants, both generating meaningful response for input questions. A sequence-to-sequence model consists of two RNNs, encoder and decoder. The encoder learns the contextual information from the input words and then hands over the knowledge to the decoder side through a “\ncontext vector\n” (or “thought vector”, as shown in Fig 8.). Finally, the decoder consumes the context vector and generates proper responses.\nA sequence-to-sequence model for generating Gmail auto replies. (Image source:\nhttps://research.googleblog.com/2015/11/computer-respond-to-this-email.html\n)\nAutoencoders\n#\nDifferent from the previous models, autoencoders are for unsupervised learning. It is designed to learn a\nlow-dimensional\nrepresentation of a\nhigh-dimensional\ndata set, similar to what\nPrincipal Components Analysis (PCA)\ndoes. The autoencoder model tries to learn an approximation function $ f(x) \\approx x $ to reproduce the input data. However, it is restricted by a bottleneck layer in the middle with a very small number of nodes. With limited capacity, the model is forced to form a very efficient encoding of the data, that is essentially the low-dimensional code we learned.\nAn autoencoder model has a bottleneck layer with only a few neurons. (Image source: Geoffrey Hinton’s Coursera class\n\"Neural Networks for Machine Learning\"\n-\nWeek 15\n)\nHinton and Salakhutdinov\nused autoencoders to compress documents on a variety of topics. As shown in Fig 10, when both PCA and autoencoder were applied to reduce the documents onto two dimensions, autoencoder demonstrated a much better outcome. With the help of autoencoder, we can do efficient data compression to speed up the information retrieval including both documents and images.\nThe outputs of PCA (left) and autoencoder (right) when both try to compress documents into two numbers. (Image source:\nHinton & Salakhutdinov 2006\n)\nReinforcement (Deep) Learning\n#\nSince I started my post with AlphaGo, let us dig a bit more on why AlphaGo worked out.\nReinforcement learning (“RL”)\nis one of the secrets behind its success. RL is a subfield of machine learning which allows machines and software agents to automatically determine the optimal behavior within a given context, with a goal to maximize the long-term performance measured by a given metric.\nAlphaGo neural network training pipeline and architecture. (Image source:\nSilver et al. 2016\n)\nThe AlphaGo system starts with a supervised learning process to train a fast rollout policy and a policy network, relying on the manually curated training dataset of professional players’ games. It learns what is the best strategy given the current position on the game board. Then it applies reinforcement learning by setting up self-play games. The RL policy network gets improved when it wins more and more games against previous versions of the policy network. In the self-play stage, AlphaGo becomes stronger and stronger by playing against itself without requiring additional external training data.\nGenerative Adversarial Network\n#\nGenerative adversarial network\n, short for “GAN”, is a type of deep generative models. GAN is able to create new examples after learning through the real data.  It is consist of two models competing against each other in a zero-sum game framework. The famous deep learning researcher\nYann LeCun\ngave it a super high praise: Generative Adversarial Network is the most interesting idea in the last ten years in machine learning. (See the Quora question:\n“What are some recent and potentially upcoming breakthroughs in deep learning?”\n)\nThe architecture of a generative adversarial network. (Image source:\nhttp://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html\n)\nIn the\noriginal GAN paper\n, GAN was proposed to generate meaningful images after learning from real photos. It comprises two independent models: the\nGenerator\nand the\nDiscriminator\n. The generator produces fake images and sends the output to the discriminator model. The discriminator works like a judge, as it is optimized for identifying the real photos from the fake ones. The generator model is trying hard to cheat the discriminator while the judge is trying hard not to be cheated. This interesting zero-sum game between these two models motivates both to develop their designed skills and improve their functionalities. Eventually, we take the generator model for producing new images.\nToolkits and Libraries\n#\nAfter learning all these models, you may start wondering how you can implement the models and use them for real. Fortunately, we have many open source toolkits and libraries for building deep learning models.\nTensorflow\nis fairly new but has attracted a lot of popularity. It turns out, TensorFlow was\nthe most forked Github project of 2015\n. All that happened in a period of 2 months after its release in Nov 2015.\nHow to Learn?\n#\nIf you are very new to the field and willing to devote some time to studying deep learning in a more systematic way, I would recommend you to start with the book\nDeep Learning\nby Ian Goodfellow, Yoshua Bengio, and Aaron Courville. The Coursera course\n“Neural Networks for Machine Learning”\nby Geoffrey Hinton (\nGodfather of deep learning!\n). The content for the course was prepared around 2006, pretty old, but it helps you build up a solid foundation for understanding deep learning models and expedite further exploration.\nMeanwhile, maintain your curiosity and passion. The field is making progress every day. Even classical or widely adopted deep learning models may just have been proposed 1-2 years ago. Reading academic papers can help you learn stuff in depth and keep up with the cutting-edge findings.\nUseful resources\n#\nGoogle Scholar:\nhttp://scholar.google.com\narXiv cs section:\nhttps://arxiv.org/list/cs/recent\nUnsupervised Feature Learning and Deep Learning Tutorial\nTensorflow Tutorials\nData Science Weekly\nKDnuggets\nTons of blog posts and online tutorials\nRelated\nCousera\ncourses\nawesome-deep-learning-papers\nBlog posts mentioned\n#\nExplained Visually: Image Kernels\nUnderstanding LSTM Networks\nThe Unreasonable Effectiveness of Recurrent Neural Networks\nComputer, respond to this email.\nInteresting blogs worthy of checking\n#\nwww.wildml.com\ncolah.github.io\nkarpathy.github.io\nblog.openai.com\nPapers mentioned\n#\n[1] He, Kaiming, et al.\n“Deep residual learning for image recognition.”\nProc. IEEE Conf. on computer vision and pattern recognition. 2016.\n[2] Wang, Haohan, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800, 2017.\n[3] Sutskever, Ilya, James Martens, and Geoffrey E. Hinton.\n“Generating text with recurrent neural networks.”\nProc. of the 28th Intl. Conf. on Machine Learning (ICML). 2011.\n[4] Liwicki, Marcus, et al.\n“A novel approach to on-line handwriting recognition based on bidirectional long short-term memory networks.”\nProc. of 9th Intl. Conf. on Document Analysis and Recognition. 2007.\n[5] LeCun, Yann, Yoshua Bengio, and Geoffrey Hinton.\n“Deep learning.”\nNature 521.7553 (2015): 436-444.\n[6] Hochreiter, Sepp, and Jurgen Schmidhuber.\n“Long short-term memory.”\nNeural computation 9.8 (1997): 1735-1780.\n[7] Cho, Kyunghyun. et al.\n“Learning phrase representations using RNN encoder-decoder for statistical machine translation.”\nProc. Conference on Empirical Methods in Natural Language Processing 1724–1734 (2014).\n[8] Hinton, Geoffrey E., and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nscience 313.5786 (2006): 504-507.\n[9] Silver, David, et al.\n“Mastering the game of Go with deep neural networks and tree search.”\nNature 529.7587 (2016): 484-489.\n[10] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:58Z",
            "title": "An Overview of Deep Learning for Curious People | Lil'Log",
            "audio": [],
            "code_blocks": [],
            "papers": [
              {
                "status": "ok",
                "url": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "bytes": 603123,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ed3b4a363f27c6c78ac0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd56c51399250ef0ff86.pdf"
              },
              {
                "status": "download_error",
                "url": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='machinelearning.wustl.edu', port=80): Max retries exceeded with url: /mlpapers/paper_files/ICML2011Sutskever_524.pdf (Caused by NameResolutionError(\"HTTPCo",
                "retried_at": "2026-10-20T22:23:46Z"
              },
              {
                "status": "invalid_file_type",
                "url": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:50:42Z"
              },
              {
                "status": "ok",
                "url": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "bytes": 2083627,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6fc2936fa52baa80ec2c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "reason": "SSLError: HTTPSConnectionPool(host='web.eecs.utk.edu', port=443): Max retries exceeded with url: /~itamar/courses/ECE-692/Bobby_paper1.pdf (Caused by SSLError(SSLCertVerificationError(1, '[S",
                "retried_at": "2026-10-20T22:23:49Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.1078.pdf",
                "bytes": 1142296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/009ff3a0e4de38cf4fd9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": true,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": true,
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              },
              {
                "status": "ok",
                "url": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "bytes": 2682222,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/478be2320822b77dc4d3.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 15875,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404；invalid_file_type",
            "raw_html": "attachments/e63a1e66232d/pages/source.html",
            "local_html": "attachments/e63a1e66232d/pages/article.html",
            "body_base_path": "attachments/e63a1e66232d/pages/",
            "body_markdown_path": "attachments/e63a1e66232d/pages/article.md",
            "links": [
              {
                "href": "http://wimlds.org/chapters/about-bay-area/",
                "label": "WiMLDS x Fintech meetup",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/www.affirm.com",
                "label": "Affirm",
                "type": "a"
              },
              {
                "href": "https://youtu.be/vFr3K2DORc8",
                "label": "games",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lee_Sedol",
                "label": "Lee Sedol",
                "type": "a"
              },
              {
                "href": "https://www.scientificamerican.com/article/how-the-computer-beat-the-go-master/",
                "label": "lost by 1-4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_acyclic_graph",
                "label": "directed acyclic graph",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/eroberts/courses/soco/projects/neural-networks/History/history1.html",
                "label": "half a century ago",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/convolutional-networks/",
                "label": "http://cs231n.github.io/convolutional-networks/#conv",
                "type": "a"
              },
              {
                "href": "https://youtu.be/F1ka6a13S9I",
                "label": "Nuts and Bolts of Applying Deep Learning",
                "type": "a"
              },
              {
                "href": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "label": "He, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.07800",
                "label": "Wang & Raj 2017",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels/",
                "label": "Specially designed kernels",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/tutorial/lenet.html",
                "label": "http://deeplearning.net/tutorial/lenet.html",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/",
                "label": "Convolutional",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/Pooling/",
                "label": "pooling",
                "type": "a"
              },
              {
                "href": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "label": "Sutskever et al. 2011",
                "type": "a"
              },
              {
                "href": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "label": "Liwicki et al. 2007",
                "type": "a"
              },
              {
                "href": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "label": "LeCun, Bengio, and Hinton, 2015",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/nature/journal/v521/n7553/fig_tab/nature14539_F5.html",
                "label": "Fig. 5",
                "type": "a"
              },
              {
                "href": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "label": "“Long-short term memory (LSTM)”",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "introduction",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/recurrent",
                "label": "Tensorflow documentation",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "label": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness/",
                "label": "Andrej Karpathy",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "label": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.1078.pdf",
                "label": "sequence-to-sequence model",
                "type": "a"
              },
              {
                "href": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "label": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Principal_component_analysis",
                "label": "Principal Components Analysis (PCA)",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks",
                "label": "\"Neural Networks for Machine Learning\"",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks/home/week/15",
                "label": "Week 15",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "label": "Hinton and Salakhutdinov",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "label": "Hinton & Salakhutdinov 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Reinforcement_learning",
                "label": "Reinforcement learning (“RL”)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/nature16961",
                "label": "Silver et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/",
                "label": "Yann LeCun",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/What-are-some-recent-and-potentially-upcoming-breakthroughs-in-deep-learning",
                "label": "“What are some recent and potentially upcoming breakthroughs in deep learning?”",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/",
                "label": "Tensorflow",
                "type": "a"
              },
              {
                "href": "http://deliprao.com/archives/168",
                "label": "the most forked Github project of 2015",
                "type": "a"
              },
              {
                "href": "https://www.amazon.com/Deep-Learning-Adaptive-Computation-Machine/dp/0262035618/ref=sr_1_1?s=books&ie=UTF8&qid=1499413305&sr=1-1&keywords=deep+learning",
                "label": "Deep Learning",
                "type": "a"
              },
              {
                "href": "https://youtu.be/uAu3jQWaN6E",
                "label": "Godfather of deep learning!",
                "type": "a"
              },
              {
                "href": "http://scholar.google.com/",
                "label": "http://scholar.google.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/list/cs/recent",
                "label": "https://arxiv.org/list/cs/recent",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/",
                "label": "Unsupervised Feature Learning and Deep Learning Tutorial",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/",
                "label": "Tensorflow Tutorials",
                "type": "a"
              },
              {
                "href": "http://coursera.com/",
                "label": "Cousera",
                "type": "a"
              },
              {
                "href": "https://github.com/terryum/awesome-deep-learning-papers",
                "label": "awesome-deep-learning-papers",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels",
                "label": "Explained Visually: Image Kernels",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/",
                "label": "www.wildml.com",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/",
                "label": "colah.github.io",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/",
                "label": "karpathy.github.io",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/",
                "label": "blog.openai.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              },
              {
                "href": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "label": "“Mastering the game of Go with deep neural networks and tree search.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
          "status": "ok",
          "article_id": "c811c8fa03ef",
          "local_path": "series-follow/1602/repair/30b6e9434771c5fcef0e.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
              "bytes": 439380,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/cd75f36109d9a8976ce6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
              "bytes": 581069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e0cb70b1716fc6541886.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
              "bytes": 124447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/bae92611d020d867c823.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
              "bytes": 234189,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/5ede211aaa74090777be.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
              "bytes": 1134478,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/037e75ccc6667d3dd676.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
              "bytes": 169121,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/eb009e9e4995ad677d20.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
              "bytes": 238097,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e98d393b3034f7b93c42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
              "bytes": 3433956,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/931034d1f77fea4a9b89.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
              "bytes": 279963,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/67ca3976dba24dedc5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
              "bytes": 137174,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/e95985488d6654cc5673.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
              "bytes": 884311,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/6291c7ba7f2547d16349.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
              "bytes": 472655,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/49d8a2995980c00d678d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
              "bytes": 191203,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/a407ab83faa199042c24.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
              "bytes": 237219,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/54c0cf380132c67d2456.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
              "bytes": 986067,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/595316073143c8f09324.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
              "bytes": 334330,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/7f21eb25c4d7577b7655.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
              "bytes": 235579,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1602/repair/assets/9ff79113319b46733509.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Train Really Large Models on Many GPUs?",
            "keywords": "分布式训练,并行,大模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "publish_date": "2021-09",
            "corpus_stage": "预训练/SFT",
            "notes": "多GPU大规模模型训练技术综述",
            "id": "c811c8fa03ef",
            "collected_at": "2026-10-02T14:12:59",
            "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
            "body_markdown": "[Updated on 2022-03-13: add\nexpert choice routing\n.]\n[Updated on 2022-06-10]:\nGreg\nand I wrote a shorted and upgraded version of this post, published on OpenAI Blog:\n“Techniques for Training Large Neural Networks”\nIn recent years, we are seeing better results on many NLP benchmark tasks with larger pre-trained\nlanguage models\n. How to train large and deep neural networks is challenging, as it demands a large amount of GPU memory and a long horizon of training time.\nHowever an individual GPU worker has limited memory and the sizes of many large models have grown beyond a single GPU. There are several parallelism paradigms to enable model training across multiple GPUs, as well as a variety of model architecture and memory saving designs to help make it possible to train\nvery large\nneural networks.\nTraining Parallelism\n#\nThe main bottleneck for training very large neural network models is the intense demand for a large amount of GPU memory, way above what can be hosted on an individual GPU machine. Besides the model weights (e.g. tens of billions of floating point numbers), it is usually even more expensive to store intermediate computation outputs such as gradients and optimizer states (e.g. momentums & variations in Adam). Additionally training a large model often pairs with a large training corpus and thus a single process may just take forever.\nAs a result, parallelism is necessary. Parallelism can happen at different dimensions, including data, model architecture, and tensor operation.\nData Parallelism\n#\nThe most naive way for\nData parallelism (DP)\nis to copy the same model weights into multiple workers and assign a fraction of data to each worker to be processed at the same time.\nNaive DP cannot work well if the model size is larger than a single GPU node’s memory. Methods like\nGeePS\n(\nCui et al. 2016\n) offload temporarily unused parameters back to CPU to work with limited GPU memory when the model is too big to fit into one machine. The data swapping transfer should happen at the backend and not interfere with training computation.\nAt the end of each minibatch, workers need to synchronize gradients or weights to avoid staleness. There are two main synchronization approaches and both have clear pros & cons.\nBulk synchronous parallels (BSP)\n: Workers sync data at the end of every minibatch. It prevents model weights staleness and good learning efficiency but each machine has to halt and wait for others to send gradients.\nAsynchronous  parallel (ASP)\n: Every GPU worker processes the data asynchronously, no waiting or stalling. However, it can easily lead to stale weights being used and thus lower the statistical learning efficiency. Even though it increases the computation time, it may not speed up training time to convergence.\nSomewhere in the middle is to synchronize gradients globally once every $x$ iterations ($x > 1$). This feature is called “gradient accumulation” in Distribution Data Parallel (\nDDP\n) since Pytorch v1.5 (\nLi et al. 2021\n). Bucketing gradients avoid immediate\nAllReduce\noperations but instead buckets multiple gradients into one\nAllReduce\nto improve throughput. Computation and communication scheduling optimization can be made based on the computation graph.\nPseudo code for Pytorch DDP. (Image source:\nLi et al. 2021\n)\nModel Parallelism\n#\nModel parallelism (MP)\naims to solve the case when the model weights cannot fit into a single node. The computation and model parameters are partitioned across multiple machines. Different from data parallelism where each worker hosts a full copy of the entire model, MP only allocates a fraction of model parameters on one worker and thus both the memory usage and the computation are reduced.\nSince deep neural networks usually contain a stack of vertical layers, it feels straightforward to split a large model by layer, where a small consecutive set of layers are grouped into one partition on one worker. However, a naive implementation for running every data batch through multiple such workers with sequential dependency leads to big bubbles of waiting time and severe under-utilization of computation resources.\nA naive model parallelism setup where the model is vertically split into 4 partitions. Data is processed by one worker at a time due to sequential dependency, leading to large “bubbles” of idle time. (Image source:\nHuang et al. 2019\n)\nPipeline Parallelism\n#\nPipeline parallelism (PP)\ncombines model parallelism with data parallelism to reduce inefficient time “bubbles’’. The main idea is to split one minibatch into multiple microbatches and enable each stage worker to process one microbatch simultaneously. Note that every microbatch needs two passes, one forward and one backward. Inter-worker communication only transfers activations (forward) and gradients (backward). How these passes are scheduled and how the gradients are aggregated vary in different approaches. The number of partitions (workers) is also known as\npipeline depth\n.\nIn\nGPipe\n(\nHuang et al. 2019\n) gradients from multiple microbatches are aggregated and applied synchronously at the end. The synchronous gradient descent guarantees learning consistency and efficiency irrespective of the number of workers. As shown in Fig. 3, bubbles still exist but are much smaller than what’s in Given $m$ evenly split microbatches and $d$ partitions, assuming both forward and backward per microbatch take one unit of time, the fraction of bubble is:\n$$\n1 - \\frac{2md}{(2m + 2(d-1))d} = \\frac{d-1}{m+d-1}\n$$\nThe GPipe paper observed that the bubble overhead is almost negligible if the number of microbatches is more than 4x the number of partitions $m > 4d$ (when\nactivation recomputation\nis applied).\nIllustration of pipeline parallelism in GPipe with 4 microbatches and 4 partitions. GPipe aggregates and updates gradients across devices synchronously at the end of every batch. (Image source:\nHuang et al. 2019\n)\nGPipe achieves almost linear speedup in throughput with the number of devices, although it is not always guaranteed if the model parameters are not evenly distributed across workers.\nPipeDream\n(\nNarayanan et al. 2019\n) schedules each worker to alternatively process the forward and backward passes (\n1F1B\n).\nPipeDream names each model partition “stage” and each stage worker can have multiple replicas to run data parallelism. In this process, PipeDream uses a deterministic round-robin load balancing strategy to assign work among multiple replicas of stages to ensure that the forward and backward passes for the same minibatch happen on the same replica.\nIllustration of `1F1B` microbatch scheduling in PipeDream. (Image source:\nHarlap et al. 2018\n)\nSince PipeDream does not have an end-of-batch global gradient sync across all the workers, an native implementation of 1F1B can easily lead to the forward and backward passes of one microbatch using different versions of model weights, thus lowering the learning efficiency. PipeDream proposed a few designs to tackle this issue:\nWeight stashing\n: Each worker keeps track of several model versions and makes sure that the same version of weights are used in the forward and backward passes given one data batch.\nVertical sync\n(Optional): The version of model weights flows between stage workers together with activations and gradients. Then the computation adopts the corresponding stashed version propagated from the previous worker. This process keeps version consistency across workers. Note that it is asynchronous, different from GPipe.\nAt the beginning of a training run, PipeDream first profiles the computation memory cost and time of each layer in the model and then optimizes a solution for partitioning layers into stages, which is a dynamic programming problem.\nResults for VGG16 on ILSVRC12. (Top) Accuracy vs time. The integer marks the number of stage workers. ASP =  Asynchronous  parallel & BSP = Bulk synchronous parallels. (Bottom) Training time speedup for different parallelism configurations. Straight pipeline refers to pipeline parallelism without data parallelism. (Image source:\nHarlap et al. 2018\n)\nTwo variations of PipeDream were later proposed to reduce the memory footprint by stashed model versions (\nNarayanan et al. 2021\n).\nPipeDream-flush\nadds a globally synchronized pipeline flush periodically, just like GPipe. In this way, it greatly reduces the memory footprint (i.e. only maintain a single version of model weights) by sacrificing a little throughput.\nIllustration of pipeline scheduling in PipeDream-flush. (Image source: (\nNarayanan et al. 2021\n)\nPipeDream-2BW\nmaintains only two versions of model weights, where “2BW” is short for “double-buffered weights”. It generates a new model version every $k$ microbatches and $k$ should be larger than the pipeline depth $d$, $k > d$. A newly updated model version cannot fully replace the old version immediately since some leftover backward passes still depend on the old version. In total only two versions need to be saved so the memory cost is much reduced.\nIllustration of pipeline scheduling in PipeDream-2BW. (Image source: (\nNarayanan et al. 2021\n)\nTensor Parallelism\n#\nBoth model and pipeline parallelisms split a model vertically. OTOH we can horizontally partition the computation for one tensor operation across multiple devices, named\nTensor parallelism (TP)\n.\nLet’s take the transformer as an example given its popularity. The transformer model mainly consists of layers of MLP and self-attention blocks.\nMegatron-LM\n(\nShoeybi et al. 2020\n) adopts a simple way to parallelize intra-layer computation for MLP and self-attention.\nA MLP layer in a transformer contains a GEMM (General matrix multiply) followed by an non-linear GeLU transfer. Let’s split weight matrix $A$ by column:\n$$\n\\begin{aligned}\n\\text{Split }A &= [A_1, A_2] \\\\\nY &=\\text{GeLU}(XA) \\\\\n[Y_1, Y_2] &= [\\text{GeLU}(XA_1), \\text{GeLU}(XA_2)]\n\\end{aligned}\n$$\nThe attention block runs GEMM with query ($Q$), key ($K$), and value weights ($V$) according to the above partitioning in parallel and then combines them with another GEMM to produce the attention head results.\n$$\n\\text{Attention}(X, Q, K, V) = \\text{softmax}(\\frac{(XQ) (XK)^\\top}{\\sqrt{d_k}}) XV\n$$\nIllustration of tensor parallelism for key transformer components proposed in Megatron-LM. (Image source:\nShoeybi et al. 2020\n)\nNarayanan et al. (2021)\ncombined pipeline, tensor and data parallelism with a new pipeline scheduling strategy and named their approach\nPTD-P\n. Instead of only positioning a continuous set of layers (“model chunk”) on a device, each worker can be assigned with multiple chunks of smaller continuous subsets of layers (e.g. device 1 has layers 1, 2, 9, 10; device 2 has layers 3, 4, 11, 12; each has two model chunks). The number of microbatches in one batch should be exactly divided by the number of workers ($m % d = 0$). If there are $v$ model chunks per worker, the pipeline bubble time can be reduced by a multiplier of $v$ compared to a GPipe scheduling.\n(Top) Default `1F1B` pipeline schedule as in PipeDream-flush. (Bottom) Interleaved 1F1B pipeline schedule. First model chunks are in dark colors and second chunks are in light colors. (Image source:\nNarayanan et al. 202)\n)\nMixture-of-Experts (MoE)\n#\nThe\nMixture-of-Experts (MoE)\napproach attracts a lot of attention recently as researchers (mainly from Google) try to push the limit of model size. The core of the idea is\nensembling learning\n:\nCombination of multiple weak learners gives you a strong learner!\nWithin one deep neural network, ensembling can be implemented with a gating mechanism connecting multiple experts (\nShazeer et al., 2017\n). The gating mechanism controls which subset of the network (e.g. which experts) should be activated to produce outputs. The paper named it “sparsely gated mixture-of-experts” (MoE) layer.\nPrecisely one MoE layer contains\n$n$ feed-forward networks as experts $\\{E_i\\}^n_{i=1}$\nA trainable gating network $G$ to learn a probability distribution over $n$ experts so as to route the traffic to a few selected experts.\nDepending on the gating outputs, not every expert has to be evaluated. When the number of experts is too large, we can consider using a two-level hierarchical MoE.\nIllustration of a mixture-of-experts (MoE) layer. Only 2 out of $n$ experts are selected and activated by the gating network. (Image source:\nShazeer et al., 2017\n)\nA simple choice of $G$ is to multiply the input with a trainable weight matrix $G_g$ and then do softmax: $G_\\sigma (x) = \\text{softmax}(x W_g)$. However, this produces a dense control vector for gating and does not help save computation resources because we don’t need to evaluate an expert only when $G^{(i)}(x)=0$. Thus the MoE layer only keeps the top $k$ values. It also adds tunable Gaussian noise into $G$ to improve load balancing. This mechanism is called\nnoisy top-k gating\n.\n$$\n\\begin{aligned} \nG(x) &= \\text{softmax}( \\text{topk}(H(x), k)) \\\\\nH^{(i)}(x) &= (xW_g)^{(i)} + \\epsilon \\cdot \\text{softplus}((xW_\\text{noise})^{(i)} ); \\quad \\epsilon \\sim \\mathcal{N}(0, \\mathbf{1}) \\\\\n\\text{topk}^{(i)}(v, k) &= \\begin{cases} v^{(i)} & \\text{if }v^{(i)}\\text{ is in the top }k\\text{ elements of }v \\\\ -\\infty & \\text{otherwise} \n\\end{cases} \n\\end{aligned}\n$$\nwhere the superscript $v^{(i)}$ denotes the i-th dimension of the vector $v$. The function $\\text{topk}(., k)$ selected the top $k$ dimensions with highest values by setting other dimensions to $-\\infty$.\nTo avoid the self-reinforcing effect that the gating network may favor a few strong experts all the time,\nShazeer et al. (2017)\nproposed a soft constraint via an additional importance loss to encourage all the experts to have the same weights. It is equivalent to the square of the\ncoefficient of variation\nof batchwise average value per expert.\n$$\nL_\\text{aux} = w_\\text{aux} \\cdot \\text{CV}(\\sum_{x \\in X} G(x))^2\n$$\nwhere $ \\text{CV}$ is the coefficient of variation and the loss weight $w_\\text{aux}$ is a hyperparameter to tune.\nBecause every expert network only gets a fraction of training samples (“The shrinking batch problem”), we should try to use a batch size as large as possible in MoE. However, it is restricted by GPU memory. Data parallelism and model parallelism can be applied to improve the throughput.\nTest perplexity on 1-Billion-Word language modeling benchmark. (Left) The model capacity increases from left to right, containing 4, 32, 256, 256, 1024 and 4096 experts. (Right) Performance of the 4 billion parameters MoE model, the largest one in the left figure, under different computation budgets. (Image source:\nShazeer et al., 2017\n)\nGShard\n(\nLepikhin et al., 2020\n) scales the MoE transformer model up to 600 billion parameters with sharding. The MoE transformer replaces every other feed forward layer with a MoE layer. The\nsharded MoE transformer\nonly has the MoE layers sharded across multiple machines, while other layers are simply duplicated.\nThere are several improved designs for the gating function $G$ in GShard:\nExpert capacity\n: The amount of tokens going through one expert should not go above a threshold, named “expert capacity”. If a token is routed to experts that have reached their capacity, the token would be marked “overflowed” and the gating output is changed to a zero vector.\nLocal group dispatching\n: Tokens are evenly partitioned into multiple local groups and the expert capacity is enforced on the group level.\nAuxiliary loss\n: The motivation is similar to the original MoE aux loss. They add an auxiliary loss to minimize the mean square of the fraction of data routed to each expert.\nRandom routing\n: The 2nd-best expert is selected with a probability proportional to its weight; otherwise, GShard follows a random routing, so as to add some randomness.\nPseudo code of the group-level top-2 gating mechanism with auxiliary loss in GShard. (Image source:\nLepikhin et al., 2020\n)\nSwitch Transformer\n(\nFedus et al. 2021\n) scales the model size up to trillions of parameters (!!) by replacing the dense feed forward layer with a\nsparse switch FFN layer\nin which each input is only routed to\none\nexpert network. The auxiliary loss for load balancing is $\\text{loss}_\\text{aux} = w_\\text{aux} \\sum_{i=1}^n f_i p_i$ given $n$ experts, where $f_i$ is the fraction of tokens routed to the $i$-th expert and $p_i$ is the routing probability for expert $i$ predicted by the gating network.\nSwitch transformer. The sparse switch FFN layer is in the blue boxes. (Image source:\nFedus et al. 2021\n)\nTo improve training stability, switch transformer incorporates the following designs:\nSelective precision\n. They showed that selectively casting only a local part of the model to FP32 precision improves stability, while avoiding the expensive communication cost of FP32 tensors. The FP32 precision is only used within the body of the router function and the results are recast to FP16.\nSmaller initialization\n. The initialization of weight matrices is sampled from a truncated normal distribution with mean $\\mu=0$ and stdev $\\sigma = \\sqrt{s/n}$. They also recommended reducing the transformer initialization scale parameter $s=1$ to $s=0.1$.\nUse higher expert dropout\n. Fine-tuning often works with a small dataset. To avoid overfitting, the dropout rate within each expert is increased by a significant amount. Interestingly they found that increasing dropout across all layers lead to poor performance. In the paper, they used a dropout rate 0.1 at non-expert layers but 0.4 within expert FF layers.\nThe switch transformer paper summarized different data and model parallelism strategies for training large models with a nice illustration:\nAn illustration of various parallelism strategies on how (Top) model weights and (Bottom) data are split over multiple GPU cores. In the top row, each color denotes a unique weight matrix. In the bottom row, different colors indicate different sets of tokens.  (Image source:\nFedus et al. 2021\n)\nBoth GShard top-2 and Switch Transformer top-1 depend on\ntoken choice\n, where each token picks the best one or two experts to route through. They both adopt an auxiliary loss to encourage more balanced load allocation but it does not guarantee the best performance. Furthermore, the expert capacity limit may lead to wasted tokens as they would be discarded if an expert reaches its capacity limit.\nExport Choice (EC)\n(\nZhou et al. 2022\n) routing instead enables each expert to select the top-$k$ tokens. In this way, each expert naturally guarantees a fixed capacity and each token may be routed to multiple experts. EC can achieve perfect load balancing and is shown to improve training convergence by 2x.\nGiven $e$ experts and an input matrix $X \\in \\mathbb{R}^{n \\times d}$, the token-to-expert affinity scores are computed by:\n$$\nS = \\text{softmax}(X \\cdot W_g), \\text{where } W_g \\in \\mathbb{R}^{d \\times e}, S \\in \\mathbb{R}^{n \\times e}\n$$\nA token-to-expert assignment is represented by three matrices, $I, G \\in \\mathbb{R}^{e\\times k}$ and $P \\in \\mathbb{R}^{e \\times k \\times n}$. $I[i,j]$ annotates which token is the $j$-th selection by the $i$-th expert. The gating matrix $G$ stores the routing weights of selected tokens. $P$ is the one-hot version of $I$, used to produce the input matrix ($P \\cdot X \\in \\mathbb{R}^{e \\times k \\times d}$) for the gated FFN layer.\n$$\nG, I = \\text{top-k}(S^\\top, k)\\quad P = \\text{one-hot}(I)\n$$\nOne regularization that export choice routing explored is to limit the maximum number of experts per token.\n$$\n\\begin{aligned}\n& \\max_A \\langle S^\\top, A\\rangle + \\lambda H(A) \\\\\n\\text{s.t.} & \n\\forall i: \\sum_{j'} A[i, j'] = k,\\quad\n\\forall j: \\sum_{i'} A[i', j] \\leq b,\\quad\n\\forall i,j: 0 \\leq A[i,j] \\leq 1\n\\end{aligned}\n$$\nwhere each entry $A[i,j]$ in $A \\in \\mathbb{R}^{e \\times n}$ marks whether the $i$-the expert selects the $j$-th token. Solving this is non-trivial. The paper used\nDykstra’s algorithm\nthat runs a sequence of multiple iterative computation steps. Capped expert choice results in a slight decrease in the fine-tuning performance in the experiments.\nThe parameter $k$ is determined by $k=nc/e$, where $n$ is the total number of tokens in one batch and $c$ is a capacity factor indicating the average number of experts used by one token. The paper used $c=2$ in most experiments, but EC with $c=1$ still outperforms the top-1 token choice gating. Interestingly, $c=0.5$ only marginally hurts the training performance.\nOne big drawback of EC is that it does not work when the batch size is too small, neither for auto-regressive text generation, because it needs to know the future tokens to do the top-$k$ selection.\nOther Memory Saving Designs\n#\nCPU Offloading\n#\nWhen the GPU memory is full, one option is to offload temporarily unused data to CPU and read them back when needed later (\nRhu et al. 2016\n). The idea of\nCPU offloading\nis straightforward but is less popular in recent years due to the slowdown it brings into the training time.\nActivation Recomputation\n#\nActivation recomputation\n(also known as “activation checkpointing” or “gradient checkpointing”;\nChen et al. 2016\n) is a smart yet simple idea to reduce memory footprint at the cost of computation time. It reduces the memory cost of training a $\\ell$ layer deep neural net to $O(\\sqrt{\\ell})$, which only additionally consumes an extra forward pass computation per batch.\nLet’s say, we evenly divide an $\\ell$-layer network into $d$ partitions. Only activations at partition boundaries are saved and communicated between workers. Intermediate activations at intra-partition layers are still needed for computing gradients so they are recomputed during backward passes. With activation recomputation, the memory cost for training $M(\\ell)$ is:\n$$\nM(\\ell) \n=\\max_{i=1,\\dots,k} \\underbrace{\\text{cost-of-one-partition}(i)}_\\text{cost of back-propagation on the i-th partition} + \\underbrace{O(d)}_\\text{store intermediate outputs} \n= O(\\frac{\\ell}{d}) + O(d)\n$$\nThe minimum cost is $O(\\sqrt{\\ell})$ at $d=\\sqrt{\\ell}$.\nActivation recompuation trick can give sublinear memory cost with respect to the model size.\nThe memory cost of different memory saving algorithms.\nSharing\n: Memory used by intermediate results is recycled when no longer needed.\nInplace\n: Save the output directly into memory of an input value. (Image source:\nChen et al. 2016\n)\nMixed Precision Training\n#\nNarang & Micikevicius et al. (2018)\nintroduced a method to train models using half-precision floating point (FP16) numbers without losing model accuracy.\nThe procedure of mixed precision training at one layer. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nThree techniques to avoid losing critical information at half-precision:\nFull-precision master copy of weights\n. Maintain a full precision (FP32) copy of model weights that accumulates gradients. The numbers are rounded up to half-precision for forward & backward passes. The motivation is that each gradient update (i.e. gradient times the learning rate) might be too small to be fully contained within the FP16 range (i.e. $2^{-24}$ becomes zero in FP16).\nLoss scaling\n. Scale up the loss to better handle gradients with small magnitudes (See Fig. 16). Scaling up the gradients helps shift them to occupy a larger section towards the right section (containing larger values) of the representable range, preserving values that are otherwise lost.\nArithmetic precision\n. For common network arithmetic (e.g. vector dot-product, reduction by summing up vector elements), we can accumulate the partial results in FP32 and then save the final output as FP16 before saving into memory. Point-wise operations can be executed in either FP16 or FP32.\nThe histogram of gradients in full precision. The left part up to $2^{-24}$ will be zero-ed off once the model switches to FP16. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nIn their experiments, loss scaling is not needed for some networks (e.g. image classification, Faster R-CNN), but necessary for others (e.g. Multibox SSD, big LSTM language model).\nCompression\n#\nIntermediate results often consume a lot of memory, although they are only needed in one forward pass and one backward pass. There is a noticeable temporal gap between these two uses. Thus\nJain et al. (2018)\nproposed a data encoding strategy to compress the intermediate results after the first use in the first pass and then decode it back for back-propagation later.\nTheir system\nGist\nincorporates two encoding schemes:\nLayer-specific lossless encoding\n; focus on ReLU-Pool (“Binarize”) and ReLU-Conv (“Sparse storage and dense computation”) patterns.\nAggressive lossy encoding\n; use delayed precision reduction (DPR). They observed that the first immediate use of feature maps should be kept at high precision but the second use can tolerate lower precision.\nThe experiments showed that Gist can reduce the memory cost by 2x across 5 SOTA image classification DNNs, with an average of 1.8x with only 4% performance overhead.\nMemory Efficient Optimizer\n#\nOptimizers are eager for memory consumption. Take the popular Adam optimizer as an example, it internally needs to maintain momentums and variances, both at the same scale as gradients and model parameters. All out of a sudden, we need to save 4x the memory of model weights.\nSeveral optimizers have been proposed to reduce the memory footprint.\nFor example, instead of storing the full momentums and variations as in Adam,\nAdafactor\n(\nShazeer et al. 2018\n) only tracks the per-row and per-column sums of the moving averages and then estimates the second moments based on these sums.\nSM3\n(\nAnil et al. 2019\n) describes a different adaptive optimization method, leading to largely reduced memory as well.\nZeRO\n(\nZero Redundancy Optimizer\n;\nRajbhandari et al. 2019\n) optimizes the memory used for training large models based on the observation about two major memory consumption of large model training:\nThe majority is occupied by\nmodel states\n, including optimizer states (e.g. Adam momentums and variances), gradients and parameters. Mixed-precision training demands a lot of memory since the optimizer needs to keep a copy of FP32 parameters and other optimizer states, besides the FP16 version.\nThe remaining is consumed by activations, temporary buffers and unusable fragmented memory (named\nresidual states\nin the paper).\nZeRO combines two approaches,\nZeRO-DP\nand\nZeRO-R\n.\nZeRO-DP is an enhanced data parallelism to avoid simple redundancy over model states. It partitions optimizer state, gradients and parameters across multiple data parallel processes via a dynamic communication schedule to minimize the communication volume.\nZeRO-R optimizes the memory consumption of residual states, using partitioned activation recomputation, constant buffer size and on-the-fly memory defragmentation.\nCitation\n#\nCited as:\nWeng, Lilian. (Sep 2021). How to train really large models on many GPUs? Lil’Log. https://lilianweng.github.io/posts/2021-09-25-train-large/.\nOr\n@article{weng2021large,\n  title   = \"How to Train Really Large Models on Many GPUs?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Sep\",\n  url     = \"https://lilianweng.github.io/posts/2021-09-25-train-large/\"\n}\nReferences\n#\n[1] Li et al.\n“PyTorch Distributed: Experiences on Accelerating Data Parallel Training”\nVLDB 2020.\n[2] Cui et al.\n“GeePS: Scalable deep learning on distributed GPUs with a GPU-specialized parameter server”\nEuroSys 2016\n[3] Shoeybi et al.\n“Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism.”\narXiv preprint arXiv:1909.08053 (2019).\n[4] Narayanan et al.\n“Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM.”\narXiv preprint arXiv:2104.04473 (2021).\n[5] Huang et al.\n“GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism.”\narXiv preprint arXiv:1811.06965 (2018).\n[6] Narayanan et al.\n“PipeDream: Generalized Pipeline Parallelism for DNN Training.”\nSOSP 2019.\n[7] Narayanan et al.\n“Memory-Efficient Pipeline-Parallel DNN Training.”\nICML 2021.\n[8] Shazeer et al.\n“The Sparsely-Gated Mixture-of-Experts Layer Noam.”\narXiv preprint arXiv:1701.06538 (2017).\n[9] Lepikhin et al.\n“GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding.”\narXiv preprint arXiv:2006.16668 (2020).\n[10] Fedus et al.\n“Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity.”\narXiv preprint arXiv:2101.03961 (2021).\n[11] Narang & Micikevicius, et al.\n“Mixed precision training.”\nICLR 2018.\n[12] Chen et al. 2016\n“Training Deep Nets with Sublinear Memory Cost.”\narXiv preprint arXiv:1604.06174 (2016).\n[13] Jain et al.\n“Gist: Efficient data encoding for deep neural network training.”\nISCA 2018.\n[14] Shazeer & Stern.\n“Adafactor: Adaptive learning rates with sublinear memory cost.”\narXiv preprint arXiv:1804.04235 (2018).\n[15] Anil et al.\n“Memory-Efficient Adaptive Optimization.”\narXiv preprint arXiv:1901.11150 (2019).\n[16] Rajbhandari et al.\n“ZeRO: Memory Optimization Towards Training A Trillion Parameter Models Samyam.”\narXiv preprint arXiv:1910.02054 (2019).\n[17] Zhou et al.\n“Mixture-of-Experts with Expert Choice Routing”\narXiv preprint arXiv:2202.09368 (2022).",
            "metadata": {
              "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
              "description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "keywords": "architecture, transformer, foundation",
              "author": "Lilian Weng",
              "og:title": "How to Train Really Large Models on Many GPUs?",
              "og:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
              "twitter:card": "summary",
              "twitter:title": "How to Train Really Large Models on Many GPUs?",
              "twitter:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "article:section": "posts",
              "article:published_time": "2021-09-24T00:00:00+00:00",
              "article:modified_time": "2021-09-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c811c8fa03ef/code/body-000.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "bytes": 439380,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-cd75f36109d9a8976ce6.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "bytes": 581069,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e0cb70b1716fc6541886.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "bytes": 124447,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-bae92611d020d867c823.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "bytes": 234189,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-5ede211aaa74090777be.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "bytes": 1134478,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-037e75ccc6667d3dd676.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "bytes": 169121,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-eb009e9e4995ad677d20.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "bytes": 238097,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e98d393b3034f7b93c42.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "bytes": 3433956,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-931034d1f77fea4a9b89.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "bytes": 279963,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-67ca3976dba24dedc5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "bytes": 137174,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e95985488d6654cc5673.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "bytes": 884311,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-6291c7ba7f2547d16349.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "bytes": 472655,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-49d8a2995980c00d678d.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "bytes": 191203,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-a407ab83faa199042c24.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "bytes": 237219,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-54c0cf380132c67d2456.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "bytes": 986067,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-595316073143c8f09324.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "bytes": 334330,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-7f21eb25c4d7577b7655.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "bytes": 235579,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-9ff79113319b46733509.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://gregbrockman.com/",
                "label": "Greg",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/techniques-for-training-large-neural-networks/",
                "label": "“Techniques for Training Large Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language models",
                "type": "a"
              },
              {
                "href": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "label": "Cui et al. 2016",
                "type": "a"
              },
              {
                "href": "https://pytorch.org/tutorials/intermediate/ddp_tutorial.html",
                "label": "DDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.15704",
                "label": "Li et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06965",
                "label": "Huang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "label": "Narayanan et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03377",
                "label": "Harlap et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09503",
                "label": "Narayanan et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.08053",
                "label": "Shoeybi et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.04473",
                "label": "Narayanan et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Ensemble_learning",
                "label": "ensembling learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1701.06538",
                "label": "Shazeer et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coefficient_of_variation",
                "label": "coefficient of variation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.16668",
                "label": "Lepikhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2101.03961",
                "label": "Fedus et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2202.09368",
                "label": "Zhou et al. 2022",
                "type": "a"
              },
              {
                "href": "https://projecteuclid.org/journals/annals-of-probability/volume-13/issue-3/An-Iterative-Procedure-for-Obtaining-I-Projections-onto-the-Intersection/10.1214/aop/1176992918.full",
                "label": "Dykstra’s algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.08124",
                "label": "Rhu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arvix.org/abs/1604.06174",
                "label": "Chen et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.03740",
                "label": "Narang & Micikevicius et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "label": "Jain et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.04235",
                "label": "Shazeer et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11150",
                "label": "Anil et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.02054",
                "label": "Rajbhandari et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.06174",
                "label": "“Training Deep Nets with Sublinear Memory Cost.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:18Z",
            "source_url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "bytes": 632686,
                "reused": false,
                "local_path": "papers/repair/52908466880352800110.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.15704",
                "bytes": 1189823,
                "reused": false,
                "local_path": "papers/repair/de67a2fc418e4e979224.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06965",
                "bytes": 539195,
                "reused": false,
                "local_path": "papers/repair/b679a01b9227418fd9a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "bytes": 1093659,
                "reused": false,
                "local_path": "papers/repair/df34f04afbea02133521.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03377",
                "bytes": 629717,
                "reused": false,
                "local_path": "papers/repair/2ff8970af5c2784cd9ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09503",
                "bytes": 2191490,
                "reused": false,
                "local_path": "papers/repair/e138d247bfb6dcf7dea8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.08053",
                "bytes": 3850425,
                "reused": false,
                "local_path": "papers/repair/331df4b1898d1b3265b5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.04473",
                "bytes": 1035739,
                "reused": false,
                "local_path": "papers/repair/27509164ea73ad0d546e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.06538",
                "bytes": 544288,
                "reused": true,
                "local_path": "papers/repair/f715adc72d48cc7ef55f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.16668",
                "bytes": 1747868,
                "reused": false,
                "local_path": "papers/repair/1a83e3dc287448c001ca.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2101.03961",
                "bytes": 1304157,
                "reused": false,
                "local_path": "papers/repair/a780b9df79db7592bd38.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2202.09368",
                "bytes": 605773,
                "reused": true,
                "local_path": "papers/repair/d8e47d8172aa52a16403.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.08124",
                "bytes": 2639789,
                "reused": false,
                "local_path": "papers/repair/84f5a94a2ee879df8044.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.03740",
                "bytes": 1404641,
                "reused": false,
                "local_path": "papers/repair/ac214b6a40a9661371fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "bytes": 376198,
                "reused": false,
                "local_path": "papers/repair/743cd4a4899a05f67033.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.04235",
                "bytes": 380566,
                "reused": false,
                "local_path": "papers/repair/367ee59650fbf06da8e5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11150",
                "bytes": 7715288,
                "reused": false,
                "local_path": "papers/repair/f11d7704ae7d73afb205.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.02054",
                "bytes": 779206,
                "reused": false,
                "local_path": "papers/repair/f9be62e9c42c011fccb3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.06174",
                "bytes": 608189,
                "reused": false,
                "local_path": "papers/repair/ab261736da2d952b7190.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29214,
            "expected_body_images": 17,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c811c8fa03ef/pages/source.html",
            "local_html": "attachments/c811c8fa03ef/pages/article.html",
            "body_base_path": "attachments/c811c8fa03ef/pages/",
            "body_markdown_path": "attachments/c811c8fa03ef/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:46:21Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 7,
      "source_url": "https://magazine.sebastianraschka.com/p/llms-building-training-finetuning",
      "items": [
        {
          "url": "https://magazine.sebastianraschka.com/p/llms-building-training-finetuning",
          "status": "ok",
          "article_id": "5c65a47f7c10",
          "local_path": "series-follow/7/repair/40158e26ff1a6d1aba80.html",
          "images": [
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!96vs!,w_40,h_40,c_fill,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f25d0a-212b-4853-8bcb-128d0a3edbbf_1196x1196.png",
              "bytes": 4638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/7/repair/assets/920ce5c0c94112fc8a9f.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!xQ0c!,e_trim:10:white/e_trim:10:transparent/h_108,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5083e6d3-fbc9-4870-95b9-6e85d02f62a6_9366x2023.png",
              "bytes": 5271,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/7/repair/assets/71086f9116582f0ba4da.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "Substack",
            "author": "Sebastian Raschka / Ahead of AI",
            "title_listed": "Developing an LLM: Building, Training, Finetuning",
            "keywords": "LLM开发,训练,微调,部署",
            "domain": "大模型算法",
            "content_type": "教程系列",
            "is_paid_flag": "否",
            "url": "https://magazine.sebastianraschka.com/p/llms-building-training-finetuning",
            "publish_date": "2024-08",
            "corpus_stage": "预训练/SFT/RLHF",
            "notes": "LLM全生命周期开发指南，从架构到部署",
            "id": "5c65a47f7c10",
            "collected_at": "2026-10-01T19:49:26",
            "title": "Developing an LLM: Building, Training, Finetuning",
            "body_markdown": "If your weekend plans include catching up on AI developments and understanding Large Language Models (LLMs), I've prepared a 1-hour presentation on the development cycle of LLMs, covering everything from architectural implementation to the finetuning stages.\nThe presentation also includes an overview and discussion of the different ways LLMs are evaluated, along with the caveats of each method.\nBelow, you'll find a table of contents to get an idea of what this video covers (the video itself has clickable chapter marks, allowing you to jump directly to topics of interest):\n00:00 – Using LLMs\n02:50 – The stages of developing an LLM\n05:26 – The dataset\n10:15 – Generating multi-word outputs\n12:30 – Tokenization\n15:35 – Pretraining datasets\n21:53 – LLM architecture\n27:20 – Pretraining\n35:21 – Classification finetuning\n39:48 – Instruction finetuning\n43:06 – Preference finetuning\n46:04 – Evaluating LLMs\n53:59 – Pretraining & finetuning rules of thumb\nIt's a slight departure from my usual text-based content, but if you find this format useful and informative, I might occasionally create and share more of them in the future.\nHappy viewing!\nAhead of AI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.\nSubscribe",
            "metadata": {
              "title": "Developing an LLM: Building, Training, Finetuning",
              "description": "A Deep Dive into the Lifecycle of LLM Development",
              "keywords": null,
              "author": "Sebastian Raschka, PhD",
              "og:type": "article",
              "og:title": "Developing an LLM: Building, Training, Finetuning",
              "og:description": "A Deep Dive into the Lifecycle of LLM Development",
              "og:image": "https://substackcdn.com/image/youtube/w_728,c_limit/kPGTx4wcm_w",
              "og:url": "https://magazine.sebastianraschka.com/p/llms-building-training-finetuning",
              "twitter:title": "Developing an LLM: Building, Training, Finetuning",
              "twitter:description": "A Deep Dive into the Lifecycle of LLM Development",
              "twitter:image": "https://substackcdn.com/image/fetch/$s_!h4xI!,f_auto,q_auto:best,fl_progressive:steep/https%3A%2F%2Fsebastianraschka.substack.com%2Fapi%2Fv1%2Fpost_preview%2F145442372%2Ftwitter.jpg%3Fversion%3D4",
              "twitter:card": "summary_large_image",
              "article:modified_time": "2025-02-09T12:38:40.275Z"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=kPGTx4wcm_w",
                "src": "https://www.youtube-nocookie.com/embed/kPGTx4wcm_w?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/5c65a47f7c10/videos/repair-kPGTx4wcm_w.mp4",
                "bytes": 98531810,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "3525.221000",
                "reused": true,
                "reused_from": "xinxing-zimeiti-corpus/attachments/d815393aeef3/videos/kPGTx4wcm_w.mp4"
              }
            ],
            "links": [
              {
                "href": "https://www.youtube-nocookie.com/embed/kPGTx4wcm_w?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:46:54Z",
            "source_url": "https://magazine.sebastianraschka.com/p/llms-building-training-finetuning",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 1292,
            "expected_body_images": 0,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/5c65a47f7c10/pages/source.html",
            "local_html": "attachments/5c65a47f7c10/pages/article.html",
            "body_base_path": "attachments/5c65a47f7c10/pages/",
            "body_markdown_path": "attachments/5c65a47f7c10/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:08Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1727,
      "source_url": "https://distill.pub/2020/circuits/zoom-in/",
      "items": [
        {
          "url": "https://distill.pub/2020/circuits/zoom-in/",
          "status": "page_size_limit"
        }
      ],
      "updated_at": "2026-10-14T11:43:19Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1600,
      "source_url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
      "items": [
        {
          "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
          "status": "ok",
          "article_id": "76583c4985bd",
          "local_path": "series-follow/1600/repair/74bca82addbb696cd397.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
              "bytes": 77905,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/22f8744911da963ff507.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
              "bytes": 83063,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2431b04e51e95d44cbfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
              "bytes": 147122,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3704ca968b8b036dd979.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
              "bytes": 449224,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/264593afb504dba40862.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
              "bytes": 270328,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/fe1f57c36a0c6b35ff30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
              "bytes": 299310,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/686784e7314725fbdcc3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
              "bytes": 375554,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/abc3c1e68e088b944f70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
              "bytes": 278212,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/20f5ad7f538bcfcaa51f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
              "bytes": 3492681,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/09be84ee222f7edd8341.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
              "bytes": 340862,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/41918aaaac4a38312f21.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
              "bytes": 373018,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/151ce877219f628d821e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
              "bytes": 130110,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/52dcd8696c072fec5989.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
              "bytes": 519536,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/60ae1da08ae38b4e5477.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
              "bytes": 124124,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1f3e79d5973995850e17.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
              "bytes": 548196,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/b8bdf2d20d1fcc25c810.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
              "bytes": 218342,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/015dfefe2091cea2d5d5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
              "bytes": 306334,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/de572b70c4267a43c66a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
              "bytes": 470728,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cf42d45d1104e492f130.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
              "bytes": 176722,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/452ce3c3d7e9a8712c06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
              "bytes": 411449,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9d2b0d8db4abe7b366db.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
            "keywords": "半监督学习,少数据,标注",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "publish_date": "2021-12",
            "corpus_stage": "数据处理",
            "notes": "半监督学习系列综述之一",
            "id": "76583c4985bd",
            "collected_at": "2026-10-02T14:13:01",
            "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
            "body_markdown": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.\nPre-training + fine-tuning\n: Pre-train a powerful task-agnostic model on a large unsupervised data corpus, e.g.\npre-training LMs\non free text, or pre-training vision models on unlabelled images via\nself-supervised learning\n, and then fine-tune it on the downstream task with a small set of labeled samples.\nSemi-supervised learning\n: Learn from the labelled and unlabeled samples together. A lot of research has happened on vision tasks within this approach.\nActive learning\n: Labeling is expensive, but we still want to collect more given a cost budget. Active learning learns to select most valuable unlabeled samples to be collected next and helps us act smartly with a limited budget.\nPre-training + dataset auto-generation\n: Given a capable pre-trained model, we can utilize it to auto-generate a lot more labeled samples. This has been especially popular within the language domain driven by the success of few-shot learning.\nI plan to write a series of posts on the topic of “Learning with not enough data”. Part 1 is on\nSemi-Supervised Learning\n.\nWhat is semi-supervised learning?\n#\nSemi-supervised learning uses both labeled and unlabeled data to train a model.\nInterestingly most existing literature on semi-supervised learning focuses on vision tasks. And instead pre-training + fine-tuning is a more common paradigm for language tasks.\nAll the methods introduced in this post have a loss combining two parts: $\\mathcal{L} = \\mathcal{L}_s +  \\mu(t) \\mathcal{L}_u$. The supervised loss $\\mathcal{L}_s$ is easy to get given all the labeled examples. We will focus on how the unsupervised loss $\\mathcal{L}_u$ is designed. A common choice of the weighting term $\\mu(t)$ is a ramp function increasing the importance of $\\mathcal{L}_u$ in time, where $t$ is the training step.\nDisclaimer\n: The post is not gonna cover semi-supervised methods with focus on model architecture modification. Check\nthis survey\nfor how to use generative models and graph-based methods in semi-supervised learning.\nNotations\n#\nSymbol\nMeaning\n$L$\nNumber of unique labels.\n$(\\mathbf{x}^l, y) \\sim \\mathcal{X}, y \\in \\{0, 1\\}^L$\nLabeled dataset. $y$ is a one-hot representation of the true label.\n$\\mathbf{u} \\sim \\mathcal{U}$\nUnlabeled dataset.\n$\\mathcal{D} = \\mathcal{X} \\cup \\mathcal{U}$\nThe entire dataset, including both labeled and unlabeled examples.\n$\\mathbf{x}$\nAny sample which can be either labeled or unlabeled.\n$\\bar{\\mathbf{x}}$\n$\\mathbf{x}$ with augmentation applied.\n$\\mathbf{x}_i$\nThe $i$-th sample.\n$\\mathcal{L}$, $\\mathcal{L}_s$, $\\mathcal{L}_u$\nLoss, supervised loss, and unsupervised loss.\n$\\mu(t)$\nThe unsupervised loss weight, increasing in time.\n$p(y \\vert \\mathbf{x}), p_\\theta(y \\vert \\mathbf{x})$\nThe conditional probability over the label set given the input.\n$f_\\theta(.)$\nThe implemented neural network with weights $\\theta$, the model that we want to train.\n$\\mathbf{z} = f_\\theta(\\mathbf{x})$\nA vector of logits output by $f$.\n$\\hat{y} = \\text{softmax}(\\mathbf{z})$\nThe predicted label distribution.\n$D[.,.]$\nA distance function between two distributions, such as MSE, cross entropy, KL divergence, etc.\n$\\beta$\nEMA weighting hyperparameter for\nteacher\nmodel weights.\n$\\alpha, \\lambda$\nParameters for MixUp, $\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)$.\n$T$\nTemperature for sharpening the predicted distribution.\n$\\tau$\nA confidence threshold for selecting the qualified prediction.\nHypotheses\n#\nSeveral hypotheses have been discussed in literature to support certain design decisions in semi-supervised learning methods.\nH1:\nSmoothness Assumptions\n: If two data samples are close in a high-density region of the feature space, their labels should be the same or very similar.\nH2:\nCluster Assumptions\n: The feature space has both dense regions and sparse regions. Densely grouped data points naturally form a cluster. Samples in the same cluster are expected to have the same label. This is a small extension of H1.\nH3:\nLow-density Separation Assumptions\n: The decision boundary between classes tends to be located in the sparse, low density regions, because otherwise the decision boundary would cut a high-density cluster into two classes, corresponding to two clusters, which invalidates H1 and H2.\nH4:\nManifold Assumptions\n: The high-dimensional data tends to locate on a low-dimensional manifold. Even though real-world data might be observed in very high dimensions (e.g. such as images of real-world objects/scenes), they actually can be captured by a lower dimensional manifold where certain attributes are captured and similar points are grouped closely (e.g. images of real-world objects/scenes are not drawn from a uniform distribution over all pixel combinations). This enables us to learn a more efficient representation for us to discover and measure similarity between unlabeled data points. This is also the foundation for representation learning. [see\na helpful link\n].\nConsistency Regularization\n#\nConsistency Regularization\n, also known as\nConsistency Training\n, assumes that randomness within the neural network (e.g. with Dropout) or data augmentation transformations should not modify model predictions given the same input. Every method in this section has a consistency regularization loss as $\\mathcal{L}_u$.\nThis idea has been adopted in several\nself-supervised\nlearning\nmethods, such as SimCLR, BYOL, SimCSE, etc. Different augmented versions of the same sample should result in the same representation.\nCross-view training\nin language modeling and multi-view learning in self-supervised learning all share the same motivation.\nΠ-model\n#\nOverview of the Π-model. Two versions of the same input with different stochastic augmentation and dropout masks pass through the network and the outputs are expected to be consistent. (Image source:\nLaine & Aila (2017)\n)\nSajjadi et al. (2016)\nproposed an unsupervised learning loss to minimize the difference between two passes through the network with stochastic transformations (e.g. dropout, random max-pooling) for the same data point. The label is not explicitly used, so the loss can be applied to unlabeled dataset.\nLaine & Aila (2017)\nlater coined the name,\nΠ-Model\n, for such a setup.\n$$\n\\mathcal{L}_u^\\Pi = \\sum_{\\mathbf{x} \\in \\mathcal{D}} \\text{MSE}(f_\\theta(\\mathbf{x}), f'_\\theta(\\mathbf{x}))\n$$\nwhere $f’$ is the same neural network with different stochastic augmentation or dropout masks applied. This loss utilizes the entire dataset.\nTemporal ensembling\n#\nOverview of Temporal Ensembling. The per-sample EMA label prediction is the learning target. (Image source:\nLaine & Aila (2017)\n)\nΠ-model requests the network to run two passes per sample, doubling the computation cost. To reduce the cost,\nTemporal Ensembling\n(\nLaine & Aila 2017\n) maintains an exponential moving average (EMA) of the model prediction in time per training sample $\\tilde{\\mathbf{z}}_i$ as the learning target, which is only evaluated and updated once per epoch. Because the ensemble output $\\tilde{\\mathbf{z}}_i$ is initialized to $\\mathbf{0}$, it is normalized by $(1-\\alpha^t)$ to correct this startup bias. Adam optimizer has such\nbias correction\nterms for the same reason.\n$$\n\\tilde{\\mathbf{z}}^{(t)}_i = \\frac{\\alpha \\tilde{\\mathbf{z}}^{(t-1)}_i + (1-\\alpha) \\mathbf{z}_i}{1-\\alpha^t}\n$$\nwhere $\\tilde{\\mathbf{z}}^{(t)}$ is the ensemble prediction at epoch $t$ and $\\mathbf{z}_i$ is the model prediction in the current round. Note that since $\\tilde{\\mathbf{z}}^{(0)} = \\mathbf{0}$, with correction, $\\tilde{\\mathbf{z}}^{(1)}$ is simply equivalent to $\\mathbf{z}_i$ at epoch 1.\nMean teachers\n#\nOverview of the Mean Teacher framework. (Image source:\nTarvaninen & Valpola, 2017\n)\nTemporal Ensembling keeps track of an EMA of label predictions for each training sample as a learning target. However, this label prediction only changes\nevery epoch\n, making the approach clumsy when the training dataset is large.\nMean Teacher\n(\nTarvaninen & Valpola, 2017\n) is proposed to overcome the slowness of target update by tracking the moving average of model weights instead of model outputs. Let’s call the original model with weights $\\theta$ as the\nstudent\nmodel and the model with moving averaged weights $\\theta’$ across consecutive student models as the\nmean teacher\n: $\\theta’ \\gets \\beta \\theta’ + (1-\\beta)\\theta$\nThe consistency regularization loss is the distance between predictions by the student and teacher and the student-teacher gap should be minimized. The mean teacher is expected to provide more accurate predictions than the student. It got confirmed in the empirical experiments, as shown in\nClassification error on SVHN of Mean Teacher and the Π Model. The mean teacher (in orange) has better performance than the student model (in blue). (Image source:\nTarvaninen & Valpola, 2017\n)\nAccording to their ablation studies,\nInput augmentation (e.g. random flips of input images, Gaussian noise) or student model dropout is necessary for good performance. Dropout is not needed on the teacher model.\nThe performance is sensitive to the EMA decay hyperparameter $\\beta$. A good strategy is to use a small $\\beta=0.99$ during the ramp up stage and a larger $\\beta=0.999$ in the later stage when the student model improvement slows down.\nThey found that MSE as the consistency cost function performs better than other cost functions like KL divergence.\nNoisy samples as learning targets\n#\nSeveral recent consistency training methods learn to minimize prediction difference between the original unlabeled sample and its corresponding augmented version. It is quite similar to the Π-model but the consistency regularization loss is\nonly\napplied to the unlabeled data.\nConsistency training with noisy samples.\nAdversarial Training (\nGoodfellow et al. 2014\n) applies adversarial noise onto the input and trains the model to be robust to such adversarial attack. The setup works in supervised learning,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{adv}(\\mathbf{x}^l, \\theta) &= D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &\\approx \\epsilon \\frac{g}{\\|g\\|_2} \\approx \\epsilon\\text{sign}(g)\\quad\\text{where }g = \\nabla_{r} D[y, p_\\theta(y\\mid \\mathbf{x}^l + r)]\n\\end{aligned}\n$$\nwhere $q(y \\mid \\mathbf{x}^l)$ is the true distribution, approximated by one-hot encoding of the ground truth label, $y$. $p_\\theta(y \\mid \\mathbf{x}^l)$ is the model prediction. $D[.,.]$ is a distance function measuring the divergence between two distributions.\nVirtual Adversarial Training\n(\nVAT\n;\nMiyato et al. 2018\n) extends the idea to work in semi-supervised learning. Because $q(y \\mid \\mathbf{x}^l)$ is unknown, VAT replaces it with the current model prediction for the original input with the current weights $\\hat{\\theta}$.  Note that $\\hat{\\theta}$ is a fixed copy of model weights, so there is no gradient update on $\\hat{\\theta}$.\n$$\n\\begin{aligned}\n\\mathcal{L}_u^\\text{VAT}(\\mathbf{x}, \\theta) &= D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r_\\text{vadv})] \\\\\nr_\\text{vadv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r)]\n\\end{aligned}\n$$\nThe VAT loss applies to both labeled and unlabeled samples. It is a negative smoothness measure of the current model’s prediction manifold at each data point. The optimization of such loss motivates the manifold to be smoother.\nInterpolation Consistency Training\n(\nICT\n;\nVerma et al. 2019\n) enhances the dataset by adding more interpolations of data points and expects the model prediction to be consistent with interpolations of the corresponding labels. MixUp (\nZheng et al. 2018\n) operation mixes two images via a simple weighted sum and combines it with label smoothing. Following the idea of MixUp, ICT expects the prediction model to produce a label on a mixup sample to match the interpolation of predictions of corresponding inputs:\n$$\n\\begin{aligned}\n\\text{mixup}_\\lambda (\\mathbf{x}_i, \\mathbf{x}_j) &= \\lambda \\mathbf{x}_i + (1-\\lambda)\\mathbf{x}_j \\\\\np(\\text{mixup}_\\lambda (y \\mid \\mathbf{x}_i, \\mathbf{x}_j)) &\\approx \\lambda p(y \\mid \\mathbf{x}_i) + (1-\\lambda) p(y \\mid \\mathbf{x}_j)\n\\end{aligned}\n$$\nwhere $\\theta’$ is a moving average of $\\theta$, which is a\nmean teacher\n.\nOverview of Interpolation Consistency Training. MixUp is applied to produce more interpolated samples with interpolated labels as learning targets. (Image source:\nVerma et al. 2019\n)\nBecause the probability of two randomly selected unlabeled samples belonging to different classes is high (e.g. There are 1000 object classes in ImageNet), the interpolation by applying a mixup between two random unlabeled samples is likely to happen around the decision boundary. According to the low-density separation\nassumptions\n, the decision boundary tends to locate in the low density regions.\n$$\n\\mathcal{L}^\\text{ICT}_{u} = \\mathbb{E}_{\\mathbf{u}_i, \\mathbf{u}_j \\sim \\mathcal{U}} \\mathbb{E}_{\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)} D[p_\\theta(y \\mid \\text{mixup}_\\lambda (\\mathbf{u}_i, \\mathbf{u}_j)), \\text{mixup}_\\lambda(p_{\\theta’}(y \\mid \\mathbf{u}_i), p_{\\theta'}(y \\mid \\mathbf{u}_j)]\n$$\nwhere $\\theta’$ is a moving average of $\\theta$.\nSimilar to VAT,\nUnsupervised Data Augmentation\n(\nUDA\n;\nXie et al. 2020\n) learns to predict the same output for an unlabeled example and the augmented one. UDA especially focuses on studying how the\n“quality”\nof noise can impact the semi-supervised learning performance with consistency training. It is crucial to use advanced data augmentation methods for producing meaningful and effective noisy samples. Good data augmentation should produce valid (i.e. does not change the label) and diverse noise, and carry targeted inductive biases.\nFor images, UDA adopts RandAugment (\nCubuk et al. 2019\n) which uniformly samples augmentation operations available in\nPIL\n, no learning or optimization, so it is much cheaper than AutoAugment.\nComparison of various semi-supervised learning methods on CIFAR-10 classification. Fully supervised Wide-ResNet-28-2 and PyramidNet+ShakeDrop have an error rate of **5.4** and **2.7** respectively when trained on 50,000 examples without RandAugment. (Image source:\nXie et al. 2020\n)\nFor language, UDA combines back-translation and TF-IDF based word replacement. Back-translation preserves the high-level meaning but may not retain certain words, while TF-IDF based word replacement drops uninformative words with low TF-IDF scores. In the experiments on language tasks, they found UDA to be complementary to transfer learning and representation learning; For example, BERT fine-tuned (i.e. $\\text{BERT}_\\text{FINETUNE}$ in Fig. 8.) on in-domain unlabeled data can further improve the performance.\nComparison of UDA with different initialization configurations on various text classification tasks. (Image source:\nXie et al. 2020\n)\nWhen calculating $\\mathcal{L}_u$, UDA found two training techniques to help improve the results.\nLow confidence masking\n: Mask out examples with low prediction confidence if lower than a threshold $\\tau$.\nSharpening prediction distribution\n: Use a low temperature $T$ in softmax to sharpen the predicted probability distribution.\nIn-domain data filtration\n: In order to extract more in-domain data from a large out-of-domain dataset, they trained a classifier to predict in-domain labels and then retain samples with high confidence predictions as in-domain candidates.\n$$\n\\begin{aligned}\n&\\mathcal{L}_u^\\text{UDA} = \\mathbb{1}[\\max_{y'} p_{\\hat{\\theta}}(y'\\mid \\mathbf{x}) > \\tau ] \\cdot D[p^\\text{(sharp)}_{\\hat{\\theta}}(y \\mid \\mathbf{x}; T), p_\\theta(y \\mid \\bar{\\mathbf{x}})] \\\\\n&\\text{where } p_{\\hat{\\theta}}^\\text{(sharp)}(y \\mid \\mathbf{x}; T) = \\frac{\\exp(z^{(y)} / T)}{ \\sum_{y'} \\exp(z^{(y')} / T) }\n\\end{aligned}\n$$\nwhere $\\hat{\\theta}$ is a fixed copy of model weights, same as in VAT, so no gradient update, and $\\bar{\\mathbf{x}}$ is the augmented data point. $\\tau$ is the prediction confidence threshold and $T$ is the distribution sharpening temperature.\nPseudo Labeling\n#\nPseudo Labeling\n(\nLee 2013\n) assigns fake labels to unlabeled samples based on the maximum softmax probabilities predicted by the current model and then trains the model on both labeled and unlabeled samples simultaneously in a pure supervised setup.\nWhy could pseudo labels work? Pseudo label is in effect equivalent to\nEntropy Regularization\n(\nGrandvalet & Bengio 2004\n), which minimizes the conditional entropy of class probabilities for unlabeled data to favor low density separation between classes. In other words, the predicted class probabilities is in fact a measure of class overlap, minimizing the entropy is equivalent to reduced class overlap and thus low density separation.\nt-SNE visualization of outputs on MNIST test set by models training (a) without and (b) with pseudo labeling on 60000 unlabeled samples, in addition to 600 labeled data. Pseudo labeling leads to better segregation in the learned embedding space.  (Image source:\nLee 2013\n)\nTraining with pseudo labeling naturally comes as an iterative process. We refer to the model that produces pseudo labels as teacher and the model that learns with pseudo labels as student.\nLabel propagation\n#\nLabel Propagation\n(\nIscen et al. 2019\n) is an idea to construct a similarity graph among samples based on feature embedding. Then the pseudo labels are “diffused” from known samples to unlabeled ones where the propagation weights are proportional to pairwise similarity scores in the graph. Conceptually it is similar to a k-NN classifier and both suffer from the problem of not scaling up well with a large dataset.\nIllustration of how Label Propagation works. (Image source:\nIscen et al. 2019\n)\nSelf-Training\n#\nSelf-Training\nis not a new concept (\nScudder 1965\n,\nNigram & Ghani CIKM 2000\n). It is an iterative algorithm, alternating between the following two steps until every unlabeled sample has a label assigned:\nInitially it builds a classifier on labeled data.\nThen it uses this classifier to predict labels for the unlabeled data and converts the most confident ones into labeled samples.\nXie et al. (2020)\napplied self-training in deep learning and achieved great results. On the ImageNet classification task, they first trained an EfficientNet (\nTan & Le 2019\n) model as teacher to generate pseudo labels for 300M unlabeled images and then trained a larger EfficientNet as student to learn with both true labeled and pseudo labeled images. One critical element in their setup is to have\nnoise\nduring student model training but have no noise for the teacher to produce pseudo labels. Thus their method is called\nNoisy Student\n. They applied stochastic depth (\nHuang et al. 2016\n), dropout and RandAugment to noise the student. Noise is important for the student to perform better than the teacher. The added noise has a compound effect to encourage the model’s decision making frontier to be smooth, on both labeled and unlabeled data.\nA few other important technical configs in noisy student self-training are:\nThe student model should be sufficiently large (i.e. larger than the teacher) to fit more data.\nNoisy student should be paired with data balancing, especially important to balance the number of pseudo labeled images in each class.\nSoft pseudo labels work better than hard ones.\nNoisy student also improves adversarial robustness against an FGSM (Fast Gradient Sign Attack = The attack uses the gradient of the loss w.r.t the input data and adjusts the input data to maximize the loss) attack though the model is not optimized for adversarial robustness.\nSentAugment, proposed by\nDu et al. (2020)\n, aims to solve the problem when there is not enough in-domain unlabeled data for self-training in the language domain. It relies on sentence embedding to find unlabeled in-domain samples from a large corpus and uses the retrieved sentences for self-training.\nReducing confirmation bias\n#\nConfirmation bias is a problem with incorrect pseudo labels provided by an imperfect teacher model. Overfitting to wrong labels may not give us a better student model.\nTo reduce confirmation bias,\nArazo et al. (2019)\nproposed  two techniques. One is to adopt MixUp with soft labels. Given two samples, $(\\mathbf{x}_i, \\mathbf{x}_j)$ and their corresponding true or pseudo labels $(y_i, y_j)$, the interpolated label equation can be translated to a cross entropy loss with softmax outputs:\n$$\n\\begin{aligned}\n&\\bar{\\mathbf{x}} = \\lambda \\mathbf{x}_i + (1-\\lambda) \\mathbf{x}_j \\\\\n&\\bar{y} = \\lambda y_i + (1-\\lambda) y_j \\Leftrightarrow\n\\mathcal{L} = \\lambda [y_i^\\top \\log f_\\theta(\\bar{\\mathbf{x}})] + (1-\\lambda) [y_j^\\top \\log f_\\theta(\\bar{\\mathbf{x}})]\n\\end{aligned}\n$$\nMixup is insufficient if there are too few labeled samples. They further set a minimum number of labeled samples in every mini batch by oversampling the labeled samples. This works better than upweighting labeled samples, because it leads to more frequent updates rather than few updates of larger magnitude which could be less stable. Like consistency regularization, data augmentation and dropout are also important for pseudo labeling to work well.\nMeta Pseudo Labels\n(\nPham et al. 2021\n) adapts the teacher model constantly with the feedback of how well the student performs on the labeled dataset. The teacher and the student are trained in parallel, where the teacher learns to generate better pseudo labels and the student learns from the pseudo labels.\nLet the teacher and student model weights be $\\theta_T$ and $\\theta_S$, respectively. The student model’s loss on the labeled samples is defined as a function $\\theta^\\text{PL}_S(.)$ of $\\theta_T$ and we would like to minimize this loss by optimizing the teacher model accordingly.\n$$\n\\begin{aligned}\n\\min_{\\theta_T} &\\mathcal{L}_s(\\theta^\\text{PL}_S(\\theta_T)) = \\min_{\\theta_T} \\mathbb{E}_{(\\mathbf{x}^l, y) \\in \\mathcal{X}} \\text{CE}[y, f_{\\theta_S}(\\mathbf{x}^l)]  \\\\\n\\text{where } &\\theta^\\text{PL}_S(\\theta_T)\n= \\arg\\min_{\\theta_S} \\mathcal{L}_u (\\theta_T, \\theta_S)\n= \\arg\\min_{\\theta_S} \\mathbb{E}_{\\mathbf{u} \\sim \\mathcal{U}} \\text{CE}[(f_{\\theta_T}(\\mathbf{u}), f_{\\theta_S}(\\mathbf{u}))]\n\\end{aligned}\n$$\nHowever, it is not trivial to optimize the above equation. Borrowing the idea of\nMAML\n, it approximates the multi-step $\\arg\\min_{\\theta_S}$ with the one-step gradient update of $\\theta_S$,\n$$\n\\begin{aligned}\n\\theta^\\text{PL}_S(\\theta_T) &\\approx \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\\\\n\\min_{\\theta_T} \\mathcal{L}_s (\\theta^\\text{PL}_S(\\theta_T)) &\\approx \\min_{\\theta_T} \\mathcal{L}_s \\big( \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\big)\n\\end{aligned}\n$$\nWith soft pseudo labels, the above objective is differentiable. But if using hard pseudo labels, it is not differentiable and thus we need to use RL, e.g. REINFORCE.\nThe optimization procedure is alternative between training two models:\nStudent model update\n: Given a batch of unlabeled samples $\\{ \\mathbf{u} \\}$, we generate pseudo labels by $f_{\\theta_T}(\\mathbf{u})$ and optimize $\\theta_S$ with one step SGD: $\\theta’_S = \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)}$.\nTeacher model update\n: Given a batch of labeled samples $\\{(\\mathbf{x}^l, y)\\}$, we reuse the student’s update to optimize $\\theta_T$: $\\theta’_T = \\theta_T  - \\eta_T \\cdot \\nabla_{\\theta_T} \\mathcal{L}_s ( \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)} )$. In addition, the UDA objective is applied to the teacher model to incorporate consistency regularization.\nComparison of Meta Pseudo Labels with other semi- or self-supervised learning methods on image classification tasks. (Image source:\nPham et al. 2021\n)\nPseudo Labeling with Consistency Regularization\n#\nIt is possible to combine the above two approaches together, running semi-supervised learning with both pseudo labeling and consistency training.\nMixMatch\n#\nMixMatch\n(\nBerthelot et al. 2019\n), as a holistic approach to semi-supervised learning, utilizes unlabeled data by merging the following techniques:\nConsistency regularization\n: Encourage the model to output the same predictions on perturbed unlabeled samples.\nEntropy minimization\n: Encourage the model to output confident predictions on unlabeled data.\nMixUp\naugmentation: Encourage the model to have linear behaviour between samples.\nGiven a batch of labeled data $\\mathcal{X}$ and unlabeled data $\\mathcal{U}$, we create augmented versions of them via $\\text{MixMatch}(.)$, $\\bar{\\mathcal{X}}$ and $\\bar{\\mathcal{U}}$, containing augmented samples and guessed labels for unlabeled examples.\n$$\n\\begin{aligned}\n\\bar{\\mathcal{X}}, \\bar{\\mathcal{U}} &= \\text{MixMatch}(\\mathcal{X}, \\mathcal{U}, T, K, \\alpha) \\\\\n\\mathcal{L}^\\text{MM}_s &= \\frac{1}{\\vert \\bar{\\mathcal{X}} \\vert} \\sum_{(\\bar{\\mathbf{x}}^l, y)\\in \\bar{\\mathcal{X}}} D[y, p_\\theta(y \\mid \\bar{\\mathbf{x}}^l)] \\\\\n\\mathcal{L}^\\text{MM}_u &= \\frac{1}{L\\vert \\bar{\\mathcal{U}} \\vert} \\sum_{(\\bar{\\mathbf{u}}, \\hat{y})\\in \\bar{\\mathcal{U}}} \\| \\hat{y} - p_\\theta(y \\mid \\bar{\\mathbf{u}}) \\|^2_2 \\\\\n\\end{aligned}\n$$\nwhere $T$ is the sharpening temperature to reduce the guessed label overlap; $K$ is the number of augmentations generated per unlabeled example; $\\alpha$ is the parameter in MixUp.\nFor each $\\mathbf{u}$, MixMatch generates $K$ augmentations, $\\bar{\\mathbf{u}}^{(k)} = \\text{Augment}(\\mathbf{u})$ for $k=1, \\dots, K$ and the pseudo label is guessed based on the average: $\\hat{y} = \\frac{1}{K} \\sum_{k=1}^K p_\\theta(y \\mid \\bar{\\mathbf{u}}^{(k)})$.\nThe process of \"label guessing\" in MixMatch: averaging $K$ augmentations, correcting the predicted marginal distribution and finally sharpening the distribution. (Image source:\nBerthelot et al. 2019\n)\nAccording to their ablation studies, it is critical to have MixUp especially on the unlabeled data. Removing temperature sharpening on the pseudo label distribution hurts the performance quite a lot. Average over multiple augmentations for label guessing is also necessary.\nReMixMatch\n(\nBerthelot et al. 2020\n) improves MixMatch by introducing two new mechanisms:\nIllustration of two improvements introduced in ReMixMatch over MixMatch. (Image source:\nBerthelot et al. 2020\n)\nDistribution alignment.\nIt encourages the marginal distribution $p(y)$ to be close to the marginal distribution of the ground truth labels. Let $p(y)$ be the class distribution in the true labels and $\\tilde{p}(\\hat{y})$ be a running average of the predicted class distribution among the unlabeled data. The model prediction on an unlabeled sample $p_\\theta(y \\vert \\mathbf{u})$ is normalized to be $\\text{Normalize}\\big( \\frac{p_\\theta(y \\vert \\mathbf{u}) p(y)}{\\tilde{p}(\\hat{y})} \\big)$ to match the true marginal distribution.\nNote that entropy minimization is not a useful objective if the marginal distribution is not uniform.\nI do feel the assumption that the class distributions on the labeled and unlabeled data should match is too strong and not necessarily to be true in the real-world setting.\nAugmentation anchoring\n. Given an unlabeled sample, it first generates an “anchor” version with weak augmentation and then averages $K$ strongly augmented versions using CTAugment (Control Theory Augment). CTAugment only samples augmentations that keep the model predictions within the network tolerance.\nThe ReMixMatch loss is a combination of several terms,\na supervised loss with data augmentation and MixUp applied;\nan unsupervised loss with data augmentation and MixUp applied, using pseudo labels as targets;\na CE loss on a single heavily-augmented unlabeled image without MixUp;\na\nrotation\nloss as in self-supervised learning.\nDivideMix\n#\nDivideMix\n(\nJunnan Li et al. 2020\n) combines semi-supervised learning with Learning with noisy labels (LNL). It models the per-sample loss distribution via a\nGMM\nto dynamically divide the training data into a labeled set with clean examples and an unlabeled set with noisy ones. Following the idea in\nArazo et al. 2019\n, they fit a two-component GMM on the per-sample cross entropy loss $\\ell_i = y_i^\\top \\log f_\\theta(\\mathbf{x}_i)$. Clean samples are expected to get lower loss faster than noisy samples. The component with smaller mean is the cluster corresponding to clean labels and let’s denote it as $c$. If the GMM posterior probability $w_i = p_\\text{GMM}(c \\mid \\ell_i)$ (i.e. the probability of the sampling belonging to the clean sample set) is larger than the threshold $\\tau$, this sample is considered as a clean sample and otherwise a noisy one.\nThe data clustering step is named\nco-divide\n. To avoid confirmation bias, DivideMix simultaneously trains two diverged networks where each network uses the dataset division from the other network; e.g. thinking about how Double Q Learning works.\nDivideMix trains two networks independently to reduce confirmation bias. They run co-divide, co-refinement, and co-guessing together. (Image source:\nJunnan Li et al. 2020\n)\nCompared to MixMatch, DivideMix has an additional\nco-divide\nstage for handling noisy samples, as well as the following improvements during training:\nLabel co-refinement\n: It linearly combines the ground-truth label $y_i$ with the network’s prediction $\\hat{y}_i$, which is averaged across multiple augmentations of $\\mathbf{x}_i$, guided by the clean set probability $w_i$ produced by the other network.\nLabel co-guessing\n: It averages the predictions from two models for unlabelled data samples.\nThe algorithm of DivideMix. (Image source:\nJunnan Li et al. 2020\n)\nFixMatch\n#\nFixMatch\n(\nSohn et al. 2020\n) generates pseudo labels on unlabeled samples with weak augmentation and only keeps predictions with high confidence. Here both weak augmentation and high confidence filtering help produce high-quality trustworthy pseudo label targets. Then FixMatch learns to predict these pseudo labels given a heavily-augmented sample.\nIllustration of how FixMatch works. (Image source:\nSohn et al. 2020\n)\n$$\n\\begin{aligned}\n\\mathcal{L}_s &= \\frac{1}{B} \\sum^B_{b=1} \\text{CE}[y_b, p_\\theta(y \\mid \\mathcal{A}_\\text{weak}(\\mathbf{x}_b))] \\\\\n\\mathcal{L}_u &= \\frac{1}{\\mu B} \\sum_{b=1}^{\\mu B} \\mathbb{1}[\\max(\\hat{y}_b) \\geq \\tau]\\;\\text{CE}(\\hat{y}_b, p_\\theta(y \\mid \\mathcal{A}_\\text{strong}(\\mathbf{u}_b)))\n\\end{aligned}\n$$\nwhere $\\hat{y}_b$ is the pseudo label for an unlabeled example; $\\mu$ is a hyperparameter that determines the relative sizes of $\\mathcal{X}$ and $\\mathcal{U}$.\nWeak augmentation $\\mathcal{A}_\\text{weak}(.)$: A standard flip-and-shift augmentation\nStrong augmentation $\\mathcal{A}_\\text{strong}(.)$ : AutoAugment, Cutout, RandAugment, CTAugment\nPerformance of FixMatch and several other semi-supervised learning methods on image classification tasks. (Image source:\nSohn et al. 2020\n)\nAccording to the ablation studies of FixMatch,\nSharpening the predicted distribution with a temperature parameter $T$ does not have a significant impact when the threshold $\\tau$ is used.\nCutout and CTAugment as part of strong augmentations are necessary for good performance.\nWhen the weak augmentation for label guessing is replaced with strong augmentation, the model diverges early in training. If discarding weak augmentation completely, the model overfit the guessed labels.\nUsing weak instead of strong augmentation for pseudo label prediction leads to unstable performance. Strong data augmentation is critical.\nCombined with Powerful Pre-Training\n#\nIt is a common paradigm, especially in language tasks, to first pre-train a task-agnostic model on a large unsupervised data corpus via self-supervised learning and then fine-tune it on the downstream task with a small labeled dataset. Research has shown that we can obtain extra gain if combining semi-supervised learning with pretraining.\nZoph et al. (2020)\nstudied to what degree\nself-training\ncan work better than pre-training. Their experiment setup was to use ImageNet for pre-training or self-training to improve COCO. Note that when using ImageNet for self-training, it discards labels and only uses ImageNet samples as unlabeled data points.\nHe et al. (2018)\nhas demonstrated that ImageNet classification pre-training does not work well if the downstream task is very different, such as object detection.\nThe effect of (a) data augment (from weak to strong) and (b) the labeled dataset size on the object detection performance. In the legend: `Rand Init` refers to a model initialized w/ random weights; `ImageNet` is initialized with a pre-trained checkpoint at 84.5% top-1 ImageNet accuracy; `ImageNet++` is initialized with a checkpoint with a higher accuracy 86.9%. (Image source:\nZoph et al. 2020\n)\nTheir experiments demonstrated a series of interesting findings:\nThe effectiveness of pre-training diminishes with more labeled samples available for the downstream task. Pre-training is helpful in the low-data regimes (20%) but neutral or harmful in the high-data regime.\nSelf-training helps in high data/strong augmentation regimes, even when pre-training hurts.\nSelf-training can bring in additive improvement on top of pre-training, even using the same data source.\nSelf-supervised pre-training (e.g. via SimCLR) hurts the performance in a high data regime, similar to how supervised pre-training does.\nJoint-training supervised and self-supervised objectives help resolve the mismatch between the pre-training and downstream tasks. Pre-training, joint-training and self-training are all additive.\nNoisy labels or un-targeted labeling (i.e. pre-training labels are not aligned with downstream task labels) is worse than targeted pseudo labeling.\nSelf-training is computationally more expensive than fine-tuning on a pre-trained model.\nChen et al. (2020)\nproposed a three-step procedure to merge the benefits of self-supervised pretraining, supervised fine-tuning and self-training together:\nUnsupervised or self-supervised pretrain a big model.\nSupervised fine-tune it on a few labeled examples. It is important to use a big (deep and wide) neural network.\nBigger models yield better performance with fewer labeled samples.\nDistillation with unlabeled examples by adopting pseudo labels in self-training.\nIt is possible to distill the knowledge from a large model into a small one because the task-specific use does not require extra capacity of the learned representation.\nThe distillation loss is formatted as the following, where the teacher network is fixed with weights $\\hat{\\theta}_T$.\n$$\n     \\mathcal{L}_\\text{distill} = - (1-\\alpha) \\underbrace{\\sum_{(\\mathbf{x}^l_i, y_i) \\in \\mathcal{X}} \\big[ \\log p_{\\theta_S}(y_i \\mid \\mathbf{x}^l_i) \\big]}_\\text{Supervised loss} - \\alpha \\underbrace{\\sum_{\\mathbf{u}_i \\in \\mathcal{U}} \\Big[ \\sum_{i=1}^L p_{\\hat{\\theta}_T}(y^{(i)} \\mid \\mathbf{u}_i; T) \\log p_{\\theta_S}(y^{(i)} \\mid \\mathbf{u}_i; T) \\Big]}_\\text{Distillation loss using unlabeled data}\n     $$\nA semi-supervised learning framework leverages unlabeled data corpus by (Left) task-agnostic unsupervised pretraining and (Right) task-specific self-training and distillation. (Image source:\nChen et al. 2020\n)\nThey experimented on the ImageNet classification task. The self-supervised pre-training uses SimCLRv2, a directly improved version of\nSimCLR\n. Observations in their empirical studies confirmed several learnings, aligned with\nZoph et al. 2020\n:\nBigger models are more label-efficient;\nBigger/deeper project heads in SimCLR improve representation learning;\nDistillation using unlabeled data improves semi-supervised learning.\nComparison of performance by SimCLRv2 + semi-supervised distillation on ImageNet classification. (Image source:\nChen et al. 2020\n)\n💡 Quick summary of common themes among recent semi-supervised learning methods, many aiming to reduce confirmation bias:\nApply valid and diverse noise to samples by advanced data augmentation methods.\nWhen dealing with images, MixUp is an effective augmentation. Mixup could work on language too, resulting in a small incremental improvement (\nGuo et al. 2019\n).\nSet a threshold and discard pseudo labels with low confidence.\nSet a minimum number of labeled samples per mini-batch.\nSharpen the pseudo label distribution to reduce the class overlap.\nCitation\n#\nCited as:\nWeng, Lilian. (Dec 2021). Learning with not enough data part 1: semi-supervised learning. Lil’Log. https://lilianweng.github.io/posts/2021-12-05-semi-supervised/.\nOr\n@article{weng2021semi,\n  title   = \"Learning with not Enough Data Part 1: Semi-Supervised Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Dec\",\n  url     = \"https://lilianweng.github.io/posts/2021-12-05-semi-supervised/\"\n}\nReferences\n#\n[1] Ouali, Hudelot & Tami.\n“An Overview of Deep Semi-Supervised Learning”\narXiv preprint arXiv:2006.05278 (2020).\n[2] Sajjadi, Javanmardi & Tasdizen\n“Regularization With Stochastic Transformations and Perturbations for Deep Semi-Supervised Learning.”\narXiv preprint arXiv:1606.04586 (2016).\n[3] Pham et al.\n“Meta Pseudo Labels.”\nCVPR 2021.\n[4] Laine & Aila.\n“Temporal Ensembling for Semi-Supervised Learning”\nICLR 2017.\n[5] Tarvaninen & Valpola.\n“Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results.”\nNeuriPS 2017\n[6] Xie et al.\n“Unsupervised Data Augmentation for Consistency Training.”\nNeuriPS 2020.\n[7] Miyato et al.\n“Virtual Adversarial Training: A Regularization Method for Supervised and Semi-Supervised Learning.”\nIEEE transactions on pattern analysis and machine intelligence 41.8 (2018).\n[8] Verma et al.\n“Interpolation consistency training for semi-supervised learning.”\nIJCAI 2019\n[9] Lee.\n“Pseudo-label: The simple and efficient semi-supervised learning method for deep neural networks.”\nICML 2013 Workshop: Challenges in Representation Learning.\n[10] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019.\n[11] Xie et al.\n“Self-training with Noisy Student improves ImageNet classification”\nCVPR 2020.\n[12] Jingfei Du et al.\n“Self-training Improves Pre-training for Natural Language Understanding.”\n2020\n[13] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019\n[14] Arazo et al.\n“Pseudo-labeling and confirmation bias in deep semi-supervised learning.”\nIJCNN 2020.\n[15] Berthelot et al.\n“MixMatch: A holistic approach to semi-supervised learning.”\nNeuriPS 2019\n[16] Berthelot et al.\n“ReMixMatch: Semi-supervised learning with distribution alignment and augmentation anchoring.”\nICLR 2020\n[17] Sohn et al.\n“FixMatch: Simplifying semi-supervised learning with consistency and confidence.”\nCVPR 2020\n[18] Junnan Li et al.\n“DivideMix: Learning with Noisy Labels as Semi-supervised Learning.”\n2020 [\ncode\n]\n[19] Zoph et al.\n“Rethinking pre-training and self-training.”\n2020.\n[20] Chen et al.\n“Big Self-Supervised Models are Strong Semi-Supervised Learners”\n2020",
            "metadata": {
              "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
              "description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "keywords": "data, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "og:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "twitter:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "article:section": "posts",
              "article:published_time": "2021-12-05T00:00:00+00:00",
              "article:modified_time": "2021-12-05T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/76583c4985bd/code/body-000.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "bytes": 77905,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-22f8744911da963ff507.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "bytes": 83063,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-2431b04e51e95d44cbfc.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "bytes": 147122,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-3704ca968b8b036dd979.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "bytes": 449224,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-264593afb504dba40862.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "bytes": 270328,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-fe1f57c36a0c6b35ff30.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "bytes": 299310,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-686784e7314725fbdcc3.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "bytes": 375554,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-abc3c1e68e088b944f70.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "bytes": 278212,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-20f5ad7f538bcfcaa51f.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "bytes": 3492681,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-09be84ee222f7edd8341.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "bytes": 340862,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-41918aaaac4a38312f21.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "bytes": 373018,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-151ce877219f628d821e.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "bytes": 130110,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-52dcd8696c072fec5989.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "bytes": 519536,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-60ae1da08ae38b4e5477.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "bytes": 124124,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-1f3e79d5973995850e17.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "bytes": 548196,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-b8bdf2d20d1fcc25c810.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "bytes": 218342,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-015dfefe2091cea2d5d5.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "bytes": 306334,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-de572b70c4267a43c66a.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "bytes": 470728,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-cf42d45d1104e492f130.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "bytes": 176722,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-452ce3c3d7e9a8712c06.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "bytes": 411449,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-9d2b0d8db4abe7b366db.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "pre-training LMs",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.05278",
                "label": "this survey",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/66939/what-is-the-manifold-assumption-in-semi-supervised-learning",
                "label": "a helpful link",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02242",
                "label": "Laine & Aila (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04586",
                "label": "Sajjadi et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/232741/why-is-it-important-to-include-a-bias-correction-term-for-the-adam-optimizer-for",
                "label": "bias correction",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01780",
                "label": "Tarvaninen & Valpola, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6572",
                "label": "Goodfellow et al. 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03976",
                "label": "Miyato et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1903.03825",
                "label": "Verma et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zheng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al. 2019",
                "type": "a"
              },
              {
                "href": "https://pillow.readthedocs.io/en/stable/",
                "label": "PIL",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.664.3543&rep=rep1&type=pdf",
                "label": "Lee 2013",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2004/hash/96f2b50b5d3613adf9c27049b2a888c7-Abstract.html",
                "label": "Grandvalet & Bengio 2004",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04717",
                "label": "Iscen et al. 2019",
                "type": "a"
              },
              {
                "href": "https://ieeexplore.ieee.org/document/1053799",
                "label": "Scudder 1965",
                "type": "a"
              },
              {
                "href": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "label": "Nigram & Ghani CIKM 2000",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.04252",
                "label": "Xie et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.11946",
                "label": "Tan & Le 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09382",
                "label": "Huang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.02194",
                "label": "Du et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.02983",
                "label": "Arazo et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10580",
                "label": "Pham et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.02249",
                "label": "Berthelot et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.09785",
                "label": "Berthelot et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.07394",
                "label": "Junnan Li et al. 2020",
                "type": "a"
              },
              {
                "href": "https://scikit-learn.org/stable/modules/mixture.html",
                "label": "GMM",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11238",
                "label": "Arazo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.07685",
                "label": "Sohn et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.06882",
                "label": "Zoph et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "He et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10029",
                "label": "Chen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.08941",
                "label": "Guo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/LiJunnan1992/DivideMix",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:21Z",
            "source_url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.05278",
                "bytes": 3172260,
                "reused": false,
                "local_path": "papers/repair/85bc9fdf7b6d2f5c5ff6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02242",
                "bytes": 322144,
                "reused": false,
                "local_path": "papers/repair/1366267456ae3965f8c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04586",
                "bytes": 282460,
                "reused": false,
                "local_path": "papers/repair/dfcdfea8469d7c081d06.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01780",
                "bytes": 863822,
                "reused": false,
                "local_path": "papers/repair/f5e8782daef1aa339f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6572",
                "bytes": 1036360,
                "reused": false,
                "local_path": "papers/repair/1b6f12d7db56a03ce596.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03976",
                "bytes": 8496008,
                "reused": false,
                "local_path": "papers/repair/7c610a3bc37a3c724c6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.03825",
                "bytes": 2774709,
                "reused": false,
                "local_path": "papers/repair/c0ed786bf3a3169d24a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": false,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": false,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": false,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04717",
                "bytes": 626230,
                "reused": false,
                "local_path": "papers/repair/ae6e8a0596cf6995095d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "bytes": 230483,
                "reused": false,
                "local_path": "papers/repair/aa557a37f131c5edaca1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.04252",
                "bytes": 2801395,
                "reused": false,
                "local_path": "papers/repair/2d5071bca517ed21302d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.11946",
                "bytes": 933600,
                "reused": false,
                "local_path": "papers/repair/b9c9141c18b68865cdc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09382",
                "bytes": 989025,
                "reused": false,
                "local_path": "papers/repair/531ae1708a14ac8b81dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.02194",
                "bytes": 2525939,
                "reused": false,
                "local_path": "papers/repair/46cf1aae6a3b935b22db.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.02983",
                "bytes": 904317,
                "reused": false,
                "local_path": "papers/repair/4e39b8b3af735acbdef2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10580",
                "bytes": 1245388,
                "reused": false,
                "local_path": "papers/repair/19c860b2949c2d91d5ec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": false,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.02249",
                "bytes": 520905,
                "reused": false,
                "local_path": "papers/repair/c84670ad345d150685e0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.09785",
                "bytes": 420212,
                "reused": false,
                "local_path": "papers/repair/e1bda50022ee2a740e73.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.07394",
                "bytes": 771769,
                "reused": false,
                "local_path": "papers/repair/a688eaa44d9b3d4d3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11238",
                "bytes": 3862031,
                "reused": false,
                "local_path": "papers/repair/4f8506d9f9d2559e3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.07685",
                "bytes": 770166,
                "reused": false,
                "local_path": "papers/repair/f068f1c17b46bc3eed3a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.06882",
                "bytes": 1655938,
                "reused": false,
                "local_path": "papers/repair/d7e01a0318a00ae28138.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": false,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10029",
                "bytes": 823706,
                "reused": false,
                "local_path": "papers/repair/558bd6a836d462b86d7a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.08941",
                "bytes": 345640,
                "reused": true,
                "local_path": "papers/repair/646a76cd251b8253359a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 39098,
            "expected_body_images": 20,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/76583c4985bd/pages/source.html",
            "local_html": "attachments/76583c4985bd/pages/article.html",
            "body_base_path": "attachments/76583c4985bd/pages/",
            "body_markdown_path": "attachments/76583c4985bd/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
          "status": "partial",
          "article_id": "607baf97b999",
          "local_path": "series-follow/1600/repair/98f025266fe083b5aa56.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
              "bytes": 929637,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/5e717a51b0a5329fa972.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
              "bytes": 268193,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/bcfb5637b30440671005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
              "bytes": 183059,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7365015a0a10cc69acd8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
              "bytes": 473871,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9d994d94aa3f953655fe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
              "bytes": 244780,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4b7c5a8a25f1aef4e33a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
              "bytes": 269806,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7ad146452781a398f651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
              "bytes": 1588495,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2208e66f87d45609e14a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
              "bytes": 516917,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e495e282eb1d3f3e9144.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
              "bytes": 51037,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8a0f9752f056eb917bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
              "bytes": 272909,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/b96d2353529c40b14aef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
              "bytes": 100122,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e2ee524fbebc06b6e190.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
              "bytes": 227696,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/5d14984c36bf66c73897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
              "bytes": 87898,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/08c8fd1e0c80108aa470.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
              "bytes": 415583,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c58896fcdd52fc06c2a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
              "bytes": 253294,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7970b3c999effb6f02b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
              "bytes": 88113,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/85fc2d78dbd4ba853f15.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
              "bytes": 282592,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dd77dfe447995839038a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
              "bytes": 384564,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3be7c9763f11993ba7a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
              "bytes": 76634,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e529afcc9a2bd0fb2fae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
              "bytes": 180008,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8045a59ac9bcdcc697fc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
              "bytes": 258219,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c0273e122159d4c19386.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
              "bytes": 88004,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8bf9b1628b286eb863de.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
              "bytes": 138525,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/76b71f8459361bdc98c5.png"
            }
          ],
          "article": {
            "id": "607baf97b999",
            "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "bytes": 929637,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5e717a51b0a5329fa972.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "bytes": 268193,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-bcfb5637b30440671005.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "bytes": 183059,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7365015a0a10cc69acd8.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "bytes": 473871,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-9d994d94aa3f953655fe.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "bytes": 244780,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-4b7c5a8a25f1aef4e33a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "bytes": 269806,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7ad146452781a398f651.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "bytes": 1588495,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-2208e66f87d45609e14a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "bytes": 516917,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e495e282eb1d3f3e9144.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "bytes": 51037,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8a0f9752f056eb917bbf.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "bytes": 272909,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-b96d2353529c40b14aef.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "bytes": 100122,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e2ee524fbebc06b6e190.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "bytes": 227696,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5d14984c36bf66c73897.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "bytes": 87898,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-08c8fd1e0c80108aa470.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "bytes": 415583,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c58896fcdd52fc06c2a0.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "bytes": 253294,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7970b3c999effb6f02b6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "bytes": 88113,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-85fc2d78dbd4ba853f15.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "bytes": 282592,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-dd77dfe447995839038a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "bytes": 384564,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-3be7c9763f11993ba7a6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "bytes": 76634,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e529afcc9a2bd0fb2fae.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "bytes": 180008,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8045a59ac9bcdcc697fc.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "bytes": 258219,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c0273e122159d4c19386.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "bytes": 88004,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8bf9b1628b286eb863de.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "bytes": 138525,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-76b71f8459361bdc98c5.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "src": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/607baf97b999/videos/repair-l5einDQ-Ttc.mp4",
                "bytes": 19398754,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "139.221000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-02-14: add\nULMFiT\nand\nGPT-2\n.]\n[Updated on 2020-02-29: add\nALBERT\n.]\n[Updated on 2020-10-25: add\nRoBERTa\n.]\n[Updated on 2020-12-13: add\nT5\n.]\n[Updated on 2020-12-30: add\nGPT-3\n.]\n[Updated on 2021-11-13: add\nXLNet\n,\nBART\nand\nELECTRA\n; Also updated the\nSummary\nsection.]\nI guess they are Elmo & Bert? (Image source:\nhere\n)\nWe have seen amazing progress in NLP in 2018. Large-scale pre-trained language modes like\nOpenAI GPT\nand\nBERT\nhave achieved great performance on a variety of language tasks using generic model architectures. The idea is similar to how ImageNet classification pre-training helps many vision tasks (*). Even better than vision classification pre-training, this simple and powerful approach in NLP does not require labeled data for pre-training, allowing us to experiment with increased training scale, up to our very limit.\n(*) He et al. (2018)\nfound\nthat pre-training might not be necessary for image segmentation task.\nIn my previous NLP\npost on word embedding\n, the introduced embeddings are not context-specific — they are learned based on word concurrency but not sequential context. So in two sentences, “\nI am eating an apple\n” and “\nI have an Apple phone\n”, two “apple” words refer to very different things but they would still share the same word embedding vector.\nDespite this, early adoption of word embeddings in problem-solving is to use them as additional features for an existing task-specific model and in a way the improvement is bounded.\nIn this post, we will discuss how various approaches were proposed to make embeddings dependent on context, and to make them easier and cheaper to be applied to downstream tasks in general form.\nCoVe\n#\nCoVe\n(\nMcCann et al. 2017\n), short for\nContextual Word Vectors\n, is a type of word embeddings learned by an encoder in an\nattentional seq-to-seq\nmachine translation model.\nDifferent from traditional word embeddings introduced\nhere\n, CoVe word representations are functions of the entire input sentence.\nNMT Recap\n#\nHere the Neural Machine Translation (\nNMT\n) model is composed of a standard, two-layer, bidirectional LSTM encoder and an attentional two-layer unidirectional LSTM decoder. It is pre-trained on the English-German translation task. The encoder learns and optimizes the embedding vectors of English words in order to translate them to German. With the intuition that the encoder should capture high-level semantic and syntactic meanings before transforming words into another language, the encoder output is used to provide contextualized word embeddings for various downstream language tasks.\nThe NMT base model used in CoVe.\nA sequence of $n$ words in source language (English): $x = [x_1, \\dots, x_n]$.\nA sequence of $m$ words in target language (German): $y = [y_1, \\dots, y_m]$.\nThe\nGloVe\nvectors of source words: $\\text{GloVe}(x)$.\nRandomly initialized embedding vectors of target words: $z = [z_1, \\dots, z_m]$.\nThe biLSTM encoder outputs a sequence of hidden states: $h = [h_1, \\dots, h_n] = \\text{biLSTM}(\\text{GloVe}(x))$ and $h_t = [\\overrightarrow{h}_t; \\overleftarrow{h}_t]$ where the forward LSTM computes $\\overrightarrow{h}_t = \\text{LSTM}(x_t, \\overrightarrow{h}_{t-1})$ and the backward computation gives us $\\overleftarrow{h}_t = \\text{LSTM}(x_t, \\overleftarrow{h}_{t-1})$.\nThe attentional decoder outputs a distribution over words: $p(y_t \\mid H, y_1, \\dots, y_{t-1})$ where $H$ is a stack of hidden states $\\{h\\}$ along the time dimension:\n$$\n\\begin{aligned}\n\\text{decoder hidden state: } s_t &= \\text{LSTM}([z_{t-1}; \\tilde{h}_{t-1}], s_{t-1}) \\\\\n\\text{attention weights: } \\alpha_t &= \\text{softmax}(H(W_1 s_t + b_1)) \\\\\n\\text{context-adjusted hidden state: } \\tilde{h}_t &= \\tanh(W_2[H^\\top\\alpha_t;s_t] + b_2) \\\\\n\\text{decoder output: } p(y_t\\mid H, y_1, \\dots, y_{t-1}) &= \\text{softmax}(W_\\text{out} \\tilde{h}_t + b_\\text{out})\n\\end{aligned}\n$$\nUse CoVe in Downstream Tasks\n#\nThe hidden states of NMT encoder are defined as\ncontext vectors\nfor other language tasks:\n$$\n\\text{CoVe}(x) = \\text{biLSTM}(\\text{GloVe}(x))\n$$\nThe paper proposed to use the concatenation of GloVe and CoVe for question-answering and classification tasks. GloVe learns from the ratios of global word co-occurrences, so it has no sentence context, while CoVe is generated by processing text sequences is able to capture the contextual information.\n$$\nv = [\\text{GloVe}(x); \\text{CoVe}(x)]\n$$\nGiven a downstream task, we first generate the concatenation of GloVe + CoVe vectors of input words and then feed them into the task-specific models as additional features.\nThe CoVe embeddings are generated by an encoder trained for machine translation task. The encoder can be plugged into any downstream task-specific model. (Image source:\noriginal paper\n)\nSummary\n: The limitation of CoVe is obvious: (1) pre-training is bounded by available datasets on the supervised translation task; (2) the contribution of CoVe to the final performance is constrained by the task-specific model architecture.\nIn the following sections, we will see that ELMo overcomes issue (1) by unsupervised pre-training and OpenAI GPT & BERT further overcome both problems by unsupervised pre-training + using generative model architecture for different downstream tasks.\nELMo\n#\nELMo\n, short for\nEmbeddings from Language Model\n(\nPeters, et al, 2018\n) learns contextualized word representation by pre-training a language model in an\nunsupervised\nway.\nBidirectional Language Model\n#\nThe bidirectional Language Model (\nbiLM\n) is the foundation for ELMo. While the input is a sequence of $n$ tokens, $(x_1, \\dots, x_n)$, the language model learns to predict the probability of next token given the history.\nIn the forward pass, the history contains words before the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_1, \\dots, x_{i-1})\n$$\nIn the backward pass, the history contains words after the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_{i+1}, \\dots, x_n)\n$$\nThe predictions in both directions are modeled by multi-layer LSTMs with hidden states $\\overrightarrow{\\mathbf{h}}_{i,\\ell}$ and $\\overleftarrow{\\mathbf{h}}_{i,\\ell}$ for input token $x_i$ at the layer level $\\ell=1,\\dots,L$.\nThe final layer’s hidden state $\\mathbf{h}_{i,L} = [\\overrightarrow{\\mathbf{h}}_{i,L}; \\overleftarrow{\\mathbf{h}}_{i,L}]$ is used to output the probabilities over tokens after softmax normalization. They share the embedding layer and the softmax layer, parameterized by $\\Theta_e$ and $\\Theta_s$ respectively.\nThe biLSTM base model of ELMo. (Image source: recreated based on the figure in [\"Neural Networks, Types, and Functional Programming\"](http://colah.github.io/posts/2015-09-NN-Types-FP/) by Christopher Olah.)\nThe model is trained to minimize the negative log likelihood (= maximize the log likelihood for true words) in both directions:\n$$\n\\begin{aligned}\n\\mathcal{L} = - \\sum_{i=1}^n \\Big( \n\\log p(x_i \\mid x_1, \\dots, x_{i-1}; \\Theta_e, \\overrightarrow{\\Theta}_\\text{LSTM}, \\Theta_s) + \\\\\n\\log p(x_i \\mid x_{i+1}, \\dots, x_n; \\Theta_e, \\overleftarrow{\\Theta}_\\text{LSTM}, \\Theta_s) \\Big)\n\\end{aligned}\n$$\nELMo Representations\n#\nOn top of a $L$-layer biLM, ELMo stacks all the hidden states across layers together by learning a task-specific linear combination. The hidden state representation for the token $x_i$ contains $2L+1$ vectors:\n$$\nR_i = \\{ \\mathbf{h}_{i,\\ell} \\mid \\ell = 0, \\dots, L \\}\n$$\nwhere $\\mathbf{h}_{0, \\ell}$ is the embedding layer output and $\\mathbf{h}_{i, \\ell} = [\\overrightarrow{\\mathbf{h}}_{i,\\ell}; \\overleftarrow{\\mathbf{h}}_{i,\\ell}]$.\nThe weights, $\\mathbf{s}^\\text{task}$, in the linear combination are learned for each end task and normalized by softmax. The scaling factor $\\gamma^\\text{task}$ is used to correct the misalignment between the distribution of biLM hidden states and the distribution of task specific representations.\n$$\nv_i = f(R_i; \\Theta^\\text{task}) = \\gamma^\\text{task} \\sum_{\\ell=0}^L s^\\text{task}_i \\mathbf{h}_{i,\\ell}\n$$\nTo evaluate what kind of information is captured by hidden states across different layers, ELMo is applied on semantic-intensive and syntax-intensive tasks respectively using representations in different layers of biLM:\nSemantic task\n: The\nword sense disambiguation (WSD)\ntask emphasizes the meaning of a word given a context. The biLM top layer is better at this task than the first layer.\nSyntax task\n: The\npart-of-speech\n(POS) tagging\ntask aims to infer the grammatical role of a word in one sentence. A higher accuracy can be achieved by using the biLM first layer than the top layer.\nThe comparison study indicates that syntactic information is better represented at lower layers while semantic information is captured by higher layers. Because different layers tend to carry different type of information,\nstacking them together helps\n.\nUse ELMo in Downstream Tasks\n#\nSimilar to how\nCoVe\ncan help different downstream tasks, ELMo embedding vectors are included in the input or lower levels of task-specific models. Moreover, for some tasks (i.e.,\nSNLI\nand\nSQuAD\n, but not\nSRL\n), adding them into the output level helps too.\nThe improvements brought up by ELMo are largest for tasks with a small supervised dataset. With ELMo, we can also achieve similar performance with much less labeled data.\nSummary\n: The language model pre-training is unsupervised and theoretically the pre-training can be scaled up as much as possible since the unlabeled text corpora are abundant. However, it still has the dependency on task-customized models and thus the improvement is only incremental, while searching for a good model architecture for every task remains non-trivial.\nCross-View Training\n#\nIn ELMo the unsupervised pre-training and task-specific learning happen for two independent models in two separate training stages.\nCross-View Training\n(abbr.\nCVT\n;\nClark et al., 2018\n) combines them into one unified semi-supervised learning procedure where the representation of a biLSTM encoder is improved by both supervised learning with labeled data and unsupervised learning with unlabeled data on auxiliary tasks.\nModel Architecture\n#\nThe model consists of a two-layer bidirectional LSTM encoder and a primary prediction module. During training, the model is fed with labeled and unlabeled data batches alternatively.\nOn\nlabeled examples\n, all the model parameters are updated by standard supervised learning. The loss is the standard cross entropy.\nOn\nunlabeled examples\n, the primary prediction module still can produce a “soft” target, even though we cannot know exactly how accurate they are. In a couple of auxiliary tasks, the predictor only sees and processes a restricted view of the input, such as only using encoder hidden state representation in one direction. The auxiliary task outputs are expected to match the primary prediction target for a full view of input.\nIn this way, the encoder is forced to distill the knowledge of the full context into partial representation. At this stage, the biLSTM encoder is backpropagated but the primary prediction module is\nfixed\n. The loss is to minimize the distance between auxiliary and primary predictions.\nThe overview of semi-supervised language model cross-view training. (Image source:\noriginal paper\n)\nMulti-Task Learning\n#\nWhen training for multiple tasks simultaneously, CVT adds several extra primary prediction models for additional tasks. They all share the same sentence representation encoder.\nDuring supervised training, once one task is randomly selected, parameters in its corresponding predictor and the representation encoder are updated.\nWith unlabeled data samples, the encoder is optimized jointly across all the tasks by minimizing the differences between auxiliary outputs and primary prediction for every task.\nThe multi-task learning encourages better generality of representation and in the meantime produces a nice side-product: all-tasks-labeled examples from unlabeled data. They are precious data labels considering that cross-task labels are useful but fairly rare.\nUse CVT in Downstream Tasks\n#\nTheoretically the primary prediction module can take any form, generic or task-specific design. The examples presented in the CVT paper include both cases.\nIn sequential tagging tasks (classification for every token) like\nNER\nor\nPOS\ntagging, the predictor module contains two fully connected layers and a softmax layer on the output to produce a probability distribution over class labels.\nFor each token $\\mathbf{x}_i$, we take the corresponding hidden states in two layers, $\\mathbf{h}_1^{(i)}$ and $\\mathbf{h}_2^{(i)}$:\n$$\n\\begin{aligned}\np_\\theta(y_i \\mid \\mathbf{x}_i) \n&= \\text{NN}(\\mathbf{h}^{(i)}) \\\\\n&= \\text{NN}([\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) \\\\\n&= \\text{softmax} \\big( \\mathbf{W}\\cdot\\text{ReLU}(\\mathbf{W'}\\cdot[\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) + \\mathbf{b} \\big)\n\\end{aligned}\n$$\nThe auxiliary tasks are only fed with forward or backward LSTM state in the first layer. Because they only observe partial context, either on the left or right, they have to learn like a language model, trying to predict the next token given the context. The\nfwd\nand\nbwd\nauxiliary tasks only take one direction. The\nfuture\nand\npast\ntasks take one step further in forward and backward direction, respectively.\n$$\n\\begin{aligned}\np_\\theta^\\text{fwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{fwd}(\\overrightarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{bwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{bwd}(\\overleftarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{future}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{future}(\\overrightarrow{\\mathbf{h}}^{(i-1)}) \\\\\np_\\theta^\\text{past}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{past}(\\overleftarrow{\\mathbf{h}}^{(i+1)})\n\\end{aligned}\n$$\nThe sequential tagging task depends on four auxiliary prediction models, their inputs only involving hidden states in one direction: forward, backward, future and past. (Image source:\noriginal paper\n)\nNote that if the primary prediction module has dropout, the dropout layer works as usual when training with labeled data, but it is not applied when generating “soft” target for auxiliary tasks during training with unlabeled data.\nIn the machine translation task, the primary prediction module is replaced with a standard unidirectional LSTM decoder with attention. There are two auxiliary tasks: (1) apply dropout on the attention weight vector by randomly zeroing out some values; (2) predict the future word in the target sequence. The primary prediction for auxiliary tasks to match is the best predicted target sequence produced by running the fixed primary decoder on the input sequence with\nbeam search\n.\nULMFiT\n#\nThe idea of using generative pretrained LM + task-specific fine-tuning was first explored in ULMFiT (\nHoward & Ruder, 2018\n), directly motivated by the success of using ImageNet pre-training for computer vision tasks. The base model is\nAWD-LSTM\n.\nULMFiT follows three steps to achieve good transfer learning results on downstream language classification tasks:\nGeneral LM pre-training\n: on Wikipedia text.\nTarget task LM fine-tuning\n: ULMFiT proposed two training techniques for stabilizing the fine-tuning process. See below.\nDiscriminative fine-tuning\nis motivated by the fact that different layers of LM capture different types of information (see\ndiscussion\nabove). ULMFiT proposed to tune each layer with different learning rates, $\\{\\eta^1, \\dots, \\eta^\\ell, \\dots, \\eta^L\\}$, where $\\eta$ is the base learning rate for the first layer, $\\eta^\\ell$ is for the $\\ell$-th layer and there are $L$ layers in total.\nSlanted triangular learning rates (STLR)\nrefer to a special learning rate scheduling that first linearly increases the learning rate and then linearly decays it. The increase stage is short so that the model can converge to a parameter space suitable for the task fast, while the decay period is long allowing for better fine-tuning.\nTarget task classifier fine-tuning\n: The pretrained LM is augmented with two standard feed-forward layers and a softmax normalization at the end to predict a target label distribution.\nConcat pooling\nextracts max-polling and mean-pooling over the history of hidden states and concatenates them with the final hidden state.\nGradual unfreezing\nhelps to avoid catastrophic forgetting by gradually unfreezing the model layers starting from the last one. First the last layer is unfrozen and fine-tuned for one epoch. Then the next lower layer is unfrozen. This process is repeated until all the layers are tuned.\nThree training stages of ULMFiT. (Image source:\noriginal paper\n)\nGPT\n#\nFollowing the similar idea of ELMo, OpenAI\nGPT\n, short for\nGenerative Pre-training Transformer\n(\nRadford et al., 2018\n), expands the unsupervised language model to a much larger scale by training on a giant collection of free text corpora. Despite of the similarity, GPT has two major differences from ELMo.\nThe model architectures are different: ELMo uses a shallow concatenation of independently trained left-to-right and right-to-left multi-layer LSTMs, while GPT is a multi-layer transformer decoder.\nThe use of contextualized embeddings in downstream tasks are different: ELMo feeds embeddings into models customized for specific tasks as additional features, while GPT fine-tunes the same base model for all end tasks.\nTransformer Decoder as Language Model\n#\nCompared to the\noriginal transformer\narchitecture, the\ntransformer decoder\nmodel discards the encoder part, so there is only one single input sentence rather than two separate source and target sequences.\nThis model applies multiple transformer blocks over the embeddings of input sequences. Each block contains a masked\nmulti-headed self-attention\nlayer and a\npointwise feed-forward\nlayer. The final output produces a distribution over target tokens after softmax normalization.\nThe transformer decoder model architecture in OpenAI GPT.\nThe loss is the negative log-likelihood, same as\nELMo\n, but without backward computation. Let’s say, the context window of the size $k$ is located before the target word and the loss would look like:\n$$\n\\mathcal{L}_\\text{LM} = -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1})\n$$\nByte Pair Encoding\n#\nByte Pair Encoding\n(\nBPE\n) is used to encode the input sequences. BPE was originally proposed as a data compression algorithm in 1990s and then was adopted to solve the open-vocabulary issue in machine translation, as we can easily run into rare and unknown words when translating into a new language. Motivated by the intuition that rare and unknown words can often be decomposed into multiple subwords, BPE finds the best word segmentation by iteratively and greedily merging frequent pairs of characters.\nSupervised Fine-Tuning\n#\nThe most substantial upgrade that OpenAI GPT proposed is to get rid of the task-specific model and use the pre-trained language model directly!\nLet’s take classification as an example. Say, in the labeled dataset, each input has $n$ tokens, $\\mathbf{x} = (x_1, \\dots, x_n)$, and one label $y$. GPT first processes the input sequence $\\mathbf{x}$ through the pre-trained transformer decoder and the last layer output for the last token $x_n$ is $\\mathbf{h}_L^{(n)}$. Then with only one new trainable weight matrix $\\mathbf{W}_y$, it can predict a distribution over class labels.\n$$\nP(y\\mid x_1, \\dots, x_n) = \\text{softmax}(\\mathbf{h}_L^{(n)}\\mathbf{W}_y)\n$$\nThe loss is to minimize the negative log-likelihood for true labels. In addition, adding the LM loss as an auxiliary loss is found to be beneficial, because:\n(1) it helps accelerate convergence during training and\n(2) it is expected to improve the generalization of the supervised model.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{cls} &= \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log P(y\\mid x_1, \\dots, x_n) = \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log \\text{softmax}(\\mathbf{h}_L^{(n)}(\\mathbf{x})\\mathbf{W}_y) \\\\\n\\mathcal{L}_\\text{LM} &= -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1}) \\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\lambda \\mathcal{L}_\\text{LM}\n\\end{aligned}\n$$\nWith similar designs, no customized model structure is needed for other end tasks (see Fig. 7). If the task input contains multiple sentences, a special delimiter token (\n$\n) is added between each pair of sentences. The embedding for this delimiter token is a new parameter we need to learn, but it should be pretty minimal.\nFor the sentence similarity task, because the ordering does not matter, both orderings are included. For the multiple choice task, the context is paired with every answer candidate.\nTraining objects in slightly modified GPT transformer models for downstream tasks. (Image source:\noriginal paper\n)\nSummary\n: It is super neat and encouraging to see that such a general framework is capable to beat SOTA on most language tasks at that time (June 2018). At the first stage, generative pre-training of a language model can absorb as much free text as possible. Then at the second stage, the model is fine-tuned on specific tasks with a small labeled dataset and a minimal set of new parameters to learn.\nOne limitation of GPT is its uni-directional nature — the model is only trained to predict the future left-to-right context.\nBERT\n#\nBERT\n, short for\nBidirectional Encoder Representations from Transformers\n(\nDevlin, et al., 2019\n) is a direct descendant to\nGPT\n: train a large language model on free text and then fine-tune on specific tasks without customized network architectures.\nCompared to GPT, the largest difference and improvement of BERT is to make training\nbi-directional\n. The model learns to predict both context on the left and right. The paper according to the ablation study claimed that:\n“bidirectional nature of our model is the single most important new contribution”\nPre-training Tasks\n#\nThe model architecture of BERT is a multi-layer bidirectional Transformer encoder.\nRecap of Transformer Encoder model architecture. (Image source:\nTransformer paper\n)\nTo encourage the bi-directional prediction and sentence-level understanding, BERT is trained with two tasks instead of the basic language task (that is, to predict the next token given context).\n*\nTask 1: Mask language model (MLM)\nFrom\nWikipedia\n: “A cloze test (also cloze deletion test) is an exercise, test, or assessment consisting of a portion of language with certain items, words, or signs removed (cloze text), where the participant is asked to replace the missing language item. … The exercise was first described by W.L. Taylor in 1953.”\nIt is unsurprising to believe that a representation that learns the context around a word rather than just after the word is able to better capture its meaning, both syntactically and semantically. BERT encourages the model to do so by training on the\n“mask language model” task\n:\nRandomly mask 15% of tokens in each sequence. Because if we only replace masked tokens with a special placeholder\n[MASK]\n, the special token would never be encountered during fine-tuning. Hence, BERT employed several heuristic tricks:\n(a) with 80% probability, replace the chosen words with\n[MASK]\n;\n(b) with 10% probability, replace with a random word;\n(c) with 10% probability, keep it the same.\nThe model only predicts the missing words, but it has no information on which words have been replaced or which words should be predicted. The output size is only 15% of the input size.\nTask 2: Next sentence prediction\nMotivated by the fact that many downstream tasks involve the understanding of relationships between sentences (i.e.,\nQA\n,\nNLI\n), BERT added another auxiliary task on training a\nbinary classifier\nfor telling whether one sentence is the next sentence of the other:\nSample sentence pairs (A, B) so that:\n(a) 50% of the time, B follows A;\n(b) 50% of the time, B does not follow A.\nThe model processes both sentences and output a binary label indicating whether B is the next sentence of A.\nThe training data for both auxiliary tasks above can be trivially generated from any monolingual corpus. Hence the scale of training is unbounded. The training loss is the sum of the mean masked LM likelihood and mean next sentence prediction likelihood.\nComparison of BERT, OpenAI GPT and ELMo model architectures. (Image source:\noriginal paper\n)\nInput Embedding\n#\nThe input embedding is the sum of three parts:\nWordPiece tokenization embeddings\n: The\nWordPiece\nmodel\nwas originally proposed for Japanese or Korean segmentation problem. Instead of using naturally split English word, they can be further divided into smaller sub-word units so that it is more effective to handle rare or unknown words. Please read\nlinked\npapers\nfor the optimal way to split words if interested.\nSegment embeddings\n: If the input contains two sentences, they have sentence A embeddings and sentence B embeddings respectively and they are separated by a special character\n[SEP]\n; Only sentence A embeddings are used if the input only contains one sentence.\nPosition embeddings\n: Positional embeddings are learned rather than hard-coded.\nBERT input representation. (Image source:\noriginal paper\n)\nNote that the first token is always forced to be\n[CLS]\n— a placeholder that will be used later for prediction in downstream tasks.\nUse BERT in Downstream Tasks\n#\nBERT fine-tuning requires only a few new parameters added, just like OpenAI GPT.\nFor classification tasks, we get the prediction by taking the final hidden state of the special first token\n[CLS]\n, $\\mathbf{h}^\\text{[CLS]}_L$, and multiplying it with a small weight matrix, $\\text{softmax}(\\mathbf{h}^\\text{[CLS]}_L \\mathbf{W}_\\text{cls})$.\nFor\nQA\ntasks like SQuAD, we need to predict the text span in the given paragraph for an given question. BERT predicts two probability distributions of every token, being the start and the end of the text span. Only two new small matrices, $\\mathbf{W}_\\text{s}$ and $\\mathbf{W}_\\text{e}$, are newly learned during fine-tuning and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{s})$ and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{e})$ define two probability distributions.\nOverall the add-on part for end task fine-tuning is very minimal — one or two weight matrices to convert the Transform hidden states to an interpretable format. Check the paper for implementation details for other cases.\nTraining objects in slightly modified BERT models for downstream tasks.  (Image source:\noriginal paper\n)\nA summary table compares differences between fine-tuning of\nOpenAI GPT\nand BERT.\n|              |\nOpenAI GPT\n|\nBERT\n|\n| Special char |\n[SEP]\nand\n[CLS]\nare only introduced at fine-tuning stage. |\n[SEP]\nand\n[CLS]\nand sentence A/B embeddings are learned at the pre-training stage. |\n| Training process | 1M steps, batch size 32k words. | 1M steps, batch size 128k words. |\n| Fine-tuning  | lr = 5e-5 for all fine-tuning tasks. | Use task-specific lr for fine-tuning. |\nALBERT\n#\nALBERT\n(\nLan, et al. 2019\n), short for\nA Lite BERT\n, is a light-weighted version of\nBERT\nmodel. An ALBERT model can be trained 1.7x faster with 18x fewer parameters, compared to a BERT model of similar configuration. ALBERT incorporates three changes as follows: the first two help reduce parameters and memory consumption and hence speed up the training speed, while the third one proposes a more chanllenging training task to replace the next sentence prediction (NSP) objective.\nFactorized Embedding Parameterization\n#\nIn BERT, the WordPiece tokenization embedding size $E$ is configured to be the same as the hidden state size $H$. That is saying, if we want to increase the model size (larger $H$), we need to learn a larger tokenization embedding too, which is expensive because it depends on the vocabulary size ($V$).\nConceptually, because the tokenization embedding is expected to learn\ncontext-independent\nrepresentation and the hidden states are\ncontext-dependent\n, it makes sense to separate the size of the hidden layers from the size of vocabulary embedding. Using factorized embedding parameterization, the large vocabulary embedding matrix of size $V \\times H$ is decomposed into two small matrices of size $V \\times E$ and $E \\times H$. Given $H \\gt E$ or even $H \\gg E$, factorization can result in significant parameter reduction.\nCross-layer Parameter Sharing\n#\nParameter sharing across layers can happen in many ways: (a) only share feed-forward part; (b) only share attention parameters; or (c) share all the parameters. This technique reduces the number of parameters by a ton and does not damage the performance too much.\nSentence-Order Prediction (SOP)\n#\nInterestingly, the\nnext sentence prediction (NSP)\ntask of BERT turned out to be too easy. ALBERT instead adopted a sentence-order prediction (SOP)\nself-supervised\nloss,\nPositive sample: two consecutive segments from the same document.\nNegative sample: same as above, but the segment order is switched.\nFor the NSP task, the model can make reasonable predictions if it is able to detect topics when A and B are from different contexts. In comparison, SOP is harder as it requires the model to fully understand the coherence and ordering between segments.\nGPT-2\n#\nThe\nOpenAI\nGPT-2\nlanguage model is a direct successor to\nGPT\n. GPT-2 has 1.5B parameters, 10x more than the original GPT, and it achieves SOTA results on 7 out of 8 tested language modeling datasets in a\nzero-shot transfer setting\nwithout any task-specific fine-tuning. The pre-training dataset contains 8 million Web pages collected by crawling qualified outbound links from\nReddit\n. Large improvements by OpenAI GPT-2 are specially noticeable on small datasets and datasets used for measuring\nlong-term dependency\n.\nZero-Shot Transfer\n#\nThe pre-training task for GPT-2 is solely language modeling. All the downstream language tasks are framed as predicting conditional probabilities and there is no task-specific fine-tuning.\nText generation is straightforward using LM.\nMachine translation task, for example, English to Chinese, is induced by conditioning LM on pairs of “English sentence = Chinese sentence” and “the target English sentence =” at the end.\nFor example, the conditional probability to predict might look like:\nP(? | I like green apples. = 我喜欢绿苹果。 A cat meows at him. = 一只猫对他喵。It is raining cats and dogs. =\")\nQA task is formatted similar to translation with pairs of questions and answers in the context.\nSummarization task is induced by adding\nTL;DR:\nafter the articles in the context.\nBPE on Byte Sequences\n#\nSame as the original GPT, GPT-2 uses\nBPE\nbut on\nUTF-8\nbyte sequences. Each byte can represent 256 different values in 8 bits, while UTF-8 can use up to 4 bytes for one character, supporting up to $2^{31}$ characters in total. Therefore, with byte sequence representation we only need a vocabulary of size 256 and do not need to worry about pre-processing, tokenization, etc. Despite of the benefit, current byte-level LMs still have non-negligible performance gap with the SOTA word-level LMs.\nBPE merges frequently co-occurred byte pairs in a greedy manner. To prevent it from generating multiple versions of common words (i.e.\ndog.\n,\ndog!\nand\ndog?\nfor the word\ndog\n), GPT-2 prevents BPE from merging characters across categories (thus\ndog\nwould not be merged with punctuations like\n.\n,\n!\nand\n?\n). This tricks help increase the quality of the final byte segmentation.\nUsing the byte sequence representation, GPT-2 is able to assign a probability to any Unicode string, regardless of any pre-processing steps.\nModel Modifications\n#\nCompared to GPT, other than having many more transformer layers and parameters, GPT-2 incorporates only a few architecture modifications:\nLayer normalization\nwas moved to the input of each sub-block, similar to a residual unit of type\n“building block”\n(differently from the original type\n“bottleneck”\n, it has batch normalization applied before weight layers).\nAn additional layer normalization was added after the final self-attention block.\nA modified initialization was constructed as a function of the model depth.\nThe weights of residual layers were initially scaled by a factor of $1/ \\sqrt{N}$ where N is the number of residual layers.\nUse larger vocabulary size and context size.\nRoBERTa\n#\nRoBERTa\n(short for\nR\nobustly\no\nptimized\nBERT\na\npproach;\nLiu, et al. 2019\n) refers to a new receipt for training BERT to achieve better results, as they found that the original BERT model is significantly undertrained. The receipt contains the following learnings:\nTrain for longer with bigger batch size.\nRemove the\nnext sentence prediction (NSP)\ntask.\nUse longer sequences in training data format. The paper found that using individual sentences as inputs hurts downstream performance. Instead we should use multiple sentences sampled contiguously to form longer segments.\nChange the masking pattern dynamically. The original BERT applies masking once during the data preprocessing stage, resulting in a static mask across training epochs. RoBERTa applies masks in 10 different ways across 40 epochs.\nRoBERTa also added a new dataset\nCommonCrawl News\nand further confirmed that pretraining with\nmore data helps\nimprove the performance on downstream tasks. It was trained with the\nBPE on byte sequences\n, same as in\nGPT-2\n. They also found that choices of hyperparameters have a big impact on the model performance.\nT5\n#\nThe language model\nT5\nis short for\n“Text-to-Text Transfer Transformer”\n(\nRaffel et al., 2020\n). The encoder-decoder implementation follows the\noriginal Transformer\narchitecture: tokens → embedding → encoder → decoder → output. T5 adopts the framework “Natural Language Decathlon” (\nMcCann et al., 2018\n), where many common NLP tasks are translated into question-answering over a context. Instead of an explicit QA format, T5 uses short task prefixes to distinguish task intentions and separately fine-tunes the model on every individual task. The text-to-text framework enables easier transfer learning evaluation with the same model on a diverse set of tasks.\nA diagram of T5 task evaluation. The text-to-text framework casts every task into a generic form: feeding input text to predict some target text. (Image source:\nRaffel et al., 2020\n)\nThe model is trained on Web corpus extracted from Apr 2019 with various filters applied. The model is fine-tuned for each downstream task separately via “adapter layers” (add an extra layer for training) or “gradual unfreezing” (see\nULMFiT\n). Both fine-tuning approaches only update partial parameters while keeping the majority of the model parameters unchanged. T5-11B achieved SOTA results on many NLP tasks.\nAs the authors mentioned in the paper “…our goal is not to propose new methods but instead to provide a comprehensive perspective on where the field stands”, the T5 long paper described a lot of training setup and evaluation processes in detail, a good read for people who are interested in training a LM from scratch.\nGPT-3\n#\nGPT-3\n(\nBrown et al., 2020\n) has the same architecture as\nGPT-2\nbut contains 175B parameters, 10x larger than GPT-2 (1.5B). In addition, GPT-3 uses alternating dense and locally banded sparse attention patterns, same as in\nsparse transformer\n. In order to fit such a huge model across multiple GPUs, GPT-3 is trained with partitions along both width and depth dimension. The training data is a filtered version of Common Crawl mixed with a few other high-quality curated datasets. To avoid the contamination that downstream tasks might appear in the training data, the authors attempted to remove all the overlaps with all the studied benchmark dataset from the training dataset. Unfortunately the filtering process is not perfect due to a bug.\nTraining datasets for GPT-3. Note that the occurrence of each dataset during training is not proportional to the dataset size.  (Table source:\nBrown et al., 2020\n)\nFor all the downstream evaluation, GPT-3 is tested in the few-shot setting without any gradient-based fine-tuning. Here the few-shot examples are provided as part of the prompt. GPT-3 achieves strong performance on many NLP datasets, comparable with fine-tuned BERT models.\nThe evaluation performance increases with the model size and the number of examples. (Image source:\nBrown et al., 2020\n)\nXLNet\n#\nThe\nAutoregressive (AR)\nmodel such as GPT and\nautoencoder (AE)\nmodel such as BERT are two most common ways for language modeling. However, each has their own disadvantages: AR does not learn the bidirectional context, which is needed by downstream tasks like reading comprehension and AE assumes masked positions are independent given all other unmasked tokens which oversimplifies the long context dependency.\nXLNet\n(\nYang et al. 2019\n) generalizes the AE method to incorporate the benefits of AR. XLNet proposed the\npermutation language modeling\nobjective. For a text sequence, it samples a factorization order $\\mathbf{z}$ and decomposes the likelihood $p_\\theta(\\mathbf{x})$ according to this factorization order,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{XLNet} \n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\sum_{t=1}^T \\log p_\\theta (X_{z_t} = x \\mid \\mathbf{x}_{\\mathbf{z}_{<{t}}})\\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) } \\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) } \\Big]\n\\end{aligned}\n$$\nwhere $\\mathcal{Z}_T$ is a set of all possible permutation of length $T$;  $z_t$ and $\\mathbf{z}_{<t}$  denote the $t$-th element and the first $t-1$ elements of a permutation $\\mathbf{z} \\in \\mathcal{Z}_T$.\nNote that the naive representation of the hidden state of the context, $h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}})$ in red, does not depend on which position the model tries to predict, as the permutation breaks the default ordering. Therefore, XLNet re-parameterized it to a function of the target position too, $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ in blue.\nHowever,  two different requirements on  $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ lead to a two-stream self-attention design to accommodate:\nWhen predicting $x_{z_t}$, it should only encode the position $z_t$ but not the content $x_{z_t}$; otherwise it is trivial. This is wrapped into the “query representation”  $g_{z_t} = g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ does not encode $x_{z_t}$.\nWhen predicting $x_j$ where $j > t$, it should encode the content $x_{z_t}$ as well to provide the full context. This is the “content representation” $h_{z_t} = h_\\theta(\\mathbf{x}_{\\leq t})$.\nThe illustration of two-stream self-attention mechanism in XLNet. (Image source:\nYang et al. 2019\n)\nConceptually, the two streams of representations are updated as follows,\n$$\n\\begin{aligned}\ng_{z_t}^{(m)} &\\gets \\text{Attention}(Q = g^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{red}{\\mathbf{z}_{<{t}}}}; \\theta) &\\text{(query stream: use }z_t\\text{ but cannot see }x_{z_t}\\text{)}\\\\\nh_{z_t}^{(m)} &\\gets \\text{Attention}(Q = h^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{blue}{\\mathbf{z}_{\\leq t}}}; \\theta) &\\text{(content stream: use both }x_{z_t}\\text{ and }x_{z_t}\\text{)}\\\\\n\\end{aligned}\n$$\nGiven the difficulty of optimization in permutation language modeling, XLNet is set to only predict the last chunk of tokens in a factorization order.\nThe name in XLNet actually comes from\nTransformer-XL\n. It incorporates the design of Transformer-XL to extend the attention span by reusing hidden states from previous segments.\nComparison of model performance of XLNet with a couple other language models on GLUE, all single-task, no ensembles. (Image source:\nYang et al. 2019\n)\nBART\n#\nBART\n(\nLewis et al., 2019\n) is a denoising autoencoder to recover the original text from a randomly corrupted version. It combines\nB\nidirectional and\nA\nuto\nR\negressive\nT\nransformer: precisely, jointly training BERT-like bidirectional encoder and GPT-like autoregressive decoder together. The loss is simply just to minimize the negative log-likelihood.\nA schematic comparison of BART with BERT and GPT. (Image source:\nLewis et al., 2019\n)\nThey experimented with a variety of noising transformations, including token masking, token deletion, text infilling (i.e. A randomly sampled text span, which may contain multiple tokens, is replaced with a\n[MASK]\ntoken), sentence permutation, documentation rotation (i.e. A document is rotated to begin with a random token.). The best noising approach they discovered is text infilling and sentence shuffling.\nComparison of different language modeling pre-training objectives. (Image source:\nLewis et al., 2019\n)\nLearnings from their experiments:\nThe performance of pre-training methods varies significantly across downstream tasks.\nToken masking is crucial, as the performance is poor when only sentence permutation or documentation rotation is applied.\nLeft-to-right pre-training improves generation.\nBidirectional encoders are crucial for SQuAD.\nThe pre-training objective is not the only important factor. Architectural improvements such as relative-position embeddings or segment-level recurrence matter too.\nAutoregressive language models perform best on ELI5.\nBART achieves the most consistently strong performance.\nELECTRA\n#\nMost current pre-training large language models demand a lot of computation resources, raising concerns about their cost and accessibility.\nELECTRA\n(“Efficiently Learning an Encoder that Classifies Token Replacements Accurately”;\nClark et al. 2020\n) aims to improve the\npre-training efficiency\n, which frames the language modeling as a discrimination task instead of generation task.\nIllustration of ELECTRA model architecture. (Image source:\nClark et al. 2020\n)\nELECTRA proposes a new pretraining task, called “Replaced Token Detection” (RTD). Let’s randomly sample $k$ positions to be masked. Each selected token in the original text is replaced by a plausible alternative predicted by a small language model, known as the generator $G$. The discriminator $D$ predicts whether each token is original or replaced.\n$$\n\\begin{aligned}\n\\boldsymbol{m} &= [m_1, \\dots, m_k] \\text{ where } m_i \\sim \\text{unif}\\{1, n\\}\\text{ for } i=1, \\dots, k \\\\\n\\boldsymbol{x}^\\text{masked} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\texttt{[MASK]}) \\\\\n\\boldsymbol{x}^\\text{corrupt} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\tilde{\\boldsymbol{x}}) \\text{ where } \\tilde{x}_t \\sim p_G(x_i \\mid \\boldsymbol{x}^\\text{masked}) \\text{ for } i \\in \\boldsymbol{m} \\\\\n\\end{aligned}\n$$\nThe loss for the generator is the negative log-likelihood just as in other language models. The loss for the discriminator is the cross-entropy. Note that the generator is not adversarially trained to fool the discriminator but simply to optimize the NLL, since their experiments show negative results.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{MLM}(\\mathbf{x}, \\theta_G) &= \\mathbb{E}\\Big(\\sum_{i \\in \\boldsymbol{m}} -\\log p_G (x_i \\mid \\boldsymbol{x}^\\text{masked} )\\Big) \\\\\n\\mathcal{L}_\\text{Disc}(\\mathbf{x}, \\theta_D) &= \\mathbb{E}\\Big( - \\mathbb{1}[x^\\text{corrupt}_t = x_t] \\log D(\\boldsymbol{x}^\\text{corrupt}, t) - \\mathbb{1}[x^\\text{corrupt}_t \\neq x_t] \\log (1 - \\log D(\\boldsymbol{x}^\\text{corrupt}, t))  \\Big)\n\\end{aligned}\n$$\nThey found it more beneficial to only share the embeddings between generator & discriminator while using a small generator (1/4 to 1/2 the discriminator size), rather than sharing all the weights (i.e. two models have to be the same size then). In addition, joint training of the generator and discriminator works better than two-stage training of each alternatively.\nAfter pretraining the generator is discarded and only the ELECTRA discriminator is fine-tuned further for downstream tasks. The following table shows ELECTRA’s performance on the GLUE dev set.\nComparison of ELECTRA with other language models on the GLUE dev set. (Image source:\nClark et al. 2020\n)\nSummary\n#\nBase model\nPretraining Tasks\nCoVe\nseq2seq NMT model\nsupervised learning using translation dataset.\nELMo\ntwo-layer biLSTM\nnext token prediction\nCVT\ntwo-layer biLSTM\nsemi-supervised learning using both labeled and unlabeled datasets\nULMFiT\nAWD-LSTM\nautoregressive pretraining on Wikitext-103\nGPT\nTransformer decoder\nnext token prediction\nBERT\nTransformer encoder\nmask language model + next sentence prediction\nALBERT\nsame as BERT but light-weighted\nmask language model + sentence order prediction\nGPT-2\nTransformer decoder\nnext token prediction\nRoBERTa\nsame as BERT\nmask language model (dynamic masking)\nT5\nTransformer encoder + decoder\npre-trained on a multi-task mixture of unsupervised and supervised tasks and for which each task is converted into a text-to-text format.\nGPT-3\nTransformer decoder\nnext token prediction\nXLNet\nsame as BERT\npermutation language modeling\nBART\nBERT encoder + GPT decoder\nreconstruct text from a noised version\nELECTRA\nsame as BERT\nreplace token detection\nMetric: Perplexity\n#\nPerplexity is often used as an intrinsic evaluation metric for gauging how well a language model can capture the real word distribution conditioned on the context.\nA\nperplexity\nof a discrete proability distribution $p$ is defined as the exponentiation of the entropy:\n$$\n2^{H(p)} = 2^{-\\sum_x p(x) \\log_2 p(x)}\n$$\nGiven a sentence with $N$ words, $s = (w_1, \\dots, w_N)$, the entropy looks as follows, simply assuming that each word has the same frequency, $\\frac{1}{N}$:\n$$\nH(s) = -\\sum_{i=1}^N P(w_i) \\log_2  p(w_i)  = -\\sum_{i=1}^N \\frac{1}{N} \\log_2  p(w_i)\n$$\nThe perplexity for the sentence becomes:\n$$\n\\begin{aligned}\n2^{H(s)} &= 2^{-\\frac{1}{N} \\sum_{i=1}^N \\log_2  p(w_i)}\n= (2^{\\sum_{i=1}^N \\log_2  p(w_i)})^{-\\frac{1}{N}}\n= (p(w_1) \\dots p(w_N))^{-\\frac{1}{N}}\n\\end{aligned}\n$$\nA good language model should predict high word probabilities. Therefore, the smaller perplexity the better.\nCommon Tasks and Datasets\n#\nQuestion-Answering\nSQuAD\n(Stanford Question Answering Dataset): A reading comprehension dataset, consisting of questions posed on a set of Wikipedia articles, where the answer to every question is a span of text.\nRACE\n(ReAding Comprehension from Examinations): A large-scale reading comprehension dataset with more than 28,000 passages and nearly 100,000 questions. The dataset is collected from English examinations in China, which are designed for middle school and high school students.\nSee\nmore QA datasets in a later post\n.\nCommonsense Reasoning\nStory Cloze Test\n: A commonsense reasoning framework for evaluating story understanding and generation. The test requires a system to choose the correct ending to multi-sentence stories from two options.\nSWAG\n(Situations With Adversarial Generations): multiple choices; contains 113k sentence-pair completion examples that evaluate grounded common-sense inference\nNatural Language Inference (NLI)\n: also known as\nText Entailment\n, an exercise to discern in logic whether one sentence can be inferred from another.\nRTE\n(Recognizing Textual Entailment): A set of datasets initiated by text entailment challenges.\nSNLI\n(Stanford Natural Language Inference): A collection of 570k human-written English sentence pairs manually labeled for balanced classification with the labels\nentailment\n,\ncontradiction\n, and\nneutral\n.\nMNLI\n(Multi-Genre NLI): Similar to SNLI, but with a more diverse variety of text styles and topics, collected from transcribed speech, popular fiction, and government reports.\nQNLI\n(Question NLI): Converted from SQuAD dataset to be a binary classification task over pairs of (question, sentence).\nSciTail\n: An entailment dataset created from multiple-choice science exams and web sentences.\nNamed Entity Recognition (NER)\n: labels sequences of words in a text which are the names of things, such as person and company names, or gene and protein names\nCoNLL 2003 NER task\n: consists of newswire from the Reuters, concentrating on four types of named entities: persons, locations, organizations and names of miscellaneous entities.\nOntoNotes 5.0\n: This corpus contains text in English, Arabic and Chinese, tagged with four different entity types (PER, LOC, ORG, MISC).\nReuters Corpus\n: A large collection of Reuters News stories.\nFine-Grained NER (FGN)\nSentiment Analysis\nSST\n(Stanford Sentiment Treebank)\nIMDb\n: A large dataset of movie reviews with binary sentiment classification labels.\nSemantic Role Labeling (SRL)\n: models the predicate-argument structure of a sentence, and is often described as answering “Who did what to whom”.\nCoNLL-2004 & CoNLL-2005\nSentence similarity\n: also known as\nparaphrase detection\nMRPC\n(MicRosoft Paraphrase Corpus): It contains pairs of sentences extracted from news sources on the web, with annotations indicating whether each pair is semantically equivalent.\nQQP\n(Quora Question Pairs)\nSTS Benchmark: Semantic Textual Similarity\nSentence Acceptability\n: a task to annotate sentences for grammatical acceptability.\nCoLA\n(Corpus of Linguistic Acceptability): a binary single-sentence classification task.\nText Chunking\n: To divide a text in syntactically correlated parts of words.\nCoNLL-2000\nPart-of-Speech (POS) Tagging\n: tag parts of speech to each token, such as noun, verb, adjective, etc.\nthe Wall Street Journal portion of the Penn Treebank (Marcus et al., 1993).\nMachine Translation\n:  See\nStandard NLP\npage.\nWMT 2015 English-Czech data (Large)\nWMT 2014 English-German data (Medium)\nIWSLT 2015 English-Vietnamese data (Small)\nCoreference Resolution\n: cluster mentions in text that refer to the same underlying real world entities.\nCoNLL-2012\nLong-range Dependency\nLAMBADA\n(LAnguage Modeling Broadened to Account for Discourse Aspects): A collection of narrative passages extracted from the BookCorpus and the task is to predict the last word, which require at least 50 tokens of context for a human to successfully predict.\nChildren’s Book Test\n: is built from books that are freely available in\nProject Gutenberg\n. The task is to predict the missing word among 10 candidates.\nMulti-task benchmark\nGLUE multi-task benchmark:\nhttps://gluebenchmark.com\ndecaNLP benmark:\nhttps://decanlp.com\nUnsupervised pretraining dataset\nBooks corpus\n: The corpus contains “over 7,000 unique unpublished books from a variety of genres including Adventure, Fantasy, and Romance.”\n1B Word Language Model Benchmark\nEnglish Wikipedia\n: ~2500M words\nCited as:\n@article{weng2019LM,\n  title   = \"Generalized Language Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-01-31-lm/\"\n}\nReference\n#\n[1] Bryan McCann, et al.\n“Learned in translation: Contextualized word vectors.”\nNIPS. 2017.\n[2] Kevin Clark et al.\n“Semi-Supervised Sequence Modeling with Cross-View Training.”\nEMNLP 2018.\n[3] Matthew E. Peters, et al.\n“Deep contextualized word representations.”\nNAACL-HLT 2017.\n[4] OpenAI Blog\n“Improving Language Understanding with Unsupervised Learning”\n, June 11, 2018.\n[5] OpenAI Blog\n“Better Language Models and Their Implications.”\nFeb 14, 2019.\n[6] Jeremy Howard and Sebastian Ruder.\n“Universal language model fine-tuning for text classification.”\nACL 2018.\n[7] Alec Radford et al.\n“Improving Language Understanding by Generative Pre-Training”\n. OpenAI Blog, June 11, 2018.\n[8] Jacob Devlin, et al.\n“BERT: Pre-training of deep bidirectional transformers for language understanding.”\narXiv:1810.04805 (2018).\n[9] Mike Schuster, and Kaisuke Nakajima.\n“Japanese and Korean voice search.”\nICASSP. 2012.\n[10] Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation\n[11] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[12] Peter J. Liu, et al.\n“Generating wikipedia by summarizing long sequences.”\nICLR 2018.\n[13] Sebastian Ruder.\n“10 Exciting Ideas of 2018 in NLP”\nDec 2018.\n[14] Alec Radford, et al.\n“Language Models are Unsupervised Multitask Learners.”\n. 2019.\n[15] Rico Sennrich, et al.\n“Neural machine translation of rare words with subword units.”\narXiv preprint arXiv:1508.07909. 2015.\n[16] Zhenzhong Lan, et al.\n“ALBERT: A Lite BERT for Self-supervised Learning of Language Representations.”\narXiv Preprint arXiv:1909.11942 (2019).\n[17] Yinhan Liu, et al.\n“RoBERTa: A Robustly Optimized BERT Pretraining Approach.”\narXiv Preprint arXiv:1907.11692 (2019).\n[18] Tom B Brown, et al.\n“Language Models are Few-Shot Learners”\nNeuriPS 2020.\n[19] Zhilin Yang et al.\n“XLNet: Generalized Autoregressive Pretraining for Language Understanding.”\nNeuriPS 2019.\n[20] Mike Lewis et al.\n“BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension.”\nACL 2020.\n[21] Kevin Clark et al.\n“ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators.”\nICLR 2020.\n[22] Colin Raffel, et al.\n“Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer”\nJMLR 2020.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:17Z",
            "title": "Generalized Language Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/607baf97b999/code/body-000.txt",
                "chars": 214,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": true,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.00107",
                "bytes": 446263,
                "reused": true,
                "local_path": "papers/repair/e2c0a99965fb6abdde60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05365",
                "bytes": 425880,
                "reused": true,
                "local_path": "papers/repair/c4dc3d740cad43df1dd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.08370",
                "bytes": 811545,
                "reused": true,
                "local_path": "papers/repair/459221e6be389ff8d946.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.06146",
                "bytes": 979417,
                "reused": true,
                "local_path": "papers/repair/f99f602eebf2965d0ed0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02182",
                "bytes": 185413,
                "reused": true,
                "local_path": "papers/repair/f2555bb43fcea5781c7c.pdf"
              },
              {
                "status": "http_403",
                "url": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "retried_at": "2026-10-20T18:10:14Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.10198",
                "bytes": 1134703,
                "reused": true,
                "local_path": "papers/repair/fe35dee079dad5528221.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.07909",
                "bytes": 193216,
                "reused": true,
                "local_path": "papers/repair/a5d0ca76205630ec8110.pdf"
              },
              {
                "status": "ok",
                "url": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "bytes": 144257,
                "reused": true,
                "local_path": "papers/repair/0eab031e51f81c92fda2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.08144.pdf",
                "bytes": 1688289,
                "reused": true,
                "local_path": "papers/repair/29316aab6d109d3a9ea6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11942",
                "bytes": 419105,
                "reused": true,
                "local_path": "papers/repair/9c6f91591bd290ea5163.pdf"
              },
              {
                "status": "download_error",
                "url": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "reason": "ConnectionError: HTTPSConnectionPool(host='d4mucfpksywv.cloudfront.net', port=443): Max retries exceeded with url: /better-language-models/language_models_are_unsupervised_multitask_learners.pdf (C",
                "retried_at": "2026-10-20T22:25:42Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1607.06450",
                "bytes": 612446,
                "reused": true,
                "local_path": "papers/repair/52a2360d9b658baa64ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.05027",
                "bytes": 1166414,
                "reused": true,
                "local_path": "papers/repair/780d6bd86240bf248474.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385",
                "bytes": 819383,
                "reused": true,
                "local_path": "papers/repair/523013cf51110acbfe60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.11692",
                "bytes": 209675,
                "reused": true,
                "local_path": "papers/repair/8acd467c11db68744d3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.08730",
                "bytes": 1187133,
                "reused": true,
                "local_path": "papers/repair/e2a98f1a611cef094a63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.08237",
                "bytes": 761790,
                "reused": true,
                "local_path": "papers/repair/e1dc08bfcdc2d830fa23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10555",
                "bytes": 497999,
                "reused": true,
                "local_path": "papers/repair/95df7a9ffe51e8dc3c44.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53020,
            "expected_body_images": 23,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_403",
            "raw_html": "attachments/607baf97b999/pages/source.html",
            "local_html": "attachments/607baf97b999/pages/article.html",
            "body_base_path": "attachments/607baf97b999/pages/",
            "body_markdown_path": "attachments/607baf97b999/pages/article.md",
            "links": [
              {
                "href": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/language-unsupervised/",
                "label": "OpenAI GPT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "found",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "post on word embedding",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.00107",
                "label": "McCann et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attentional seq-to-seq",
                "type": "a"
              },
              {
                "href": "https://github.com/THUNLP-MT/MT-Reading-List",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05365",
                "label": "Peters, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Part-of-speech_tagging",
                "label": "part-of-speech",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.08370",
                "label": "Clark et al., 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beam_search",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.06146",
                "label": "Howard & Ruder, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02182",
                "label": "AWD-LSTM",
                "type": "a"
              },
              {
                "href": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "label": "Radford et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "original transformer",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.10198",
                "label": "transformer decoder",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.07909",
                "label": "BPE",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Wikipedia",
                "type": "a"
              },
              {
                "href": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "label": "WordPiece",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1609.08144.pdf",
                "label": "model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11942",
                "label": "Lan, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/better-language-models/",
                "label": "OpenAI",
                "type": "a"
              },
              {
                "href": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "label": "GPT-2",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/",
                "label": "Reddit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/UTF-8",
                "label": "UTF-8",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1607.06450",
                "label": "Layer normalization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.05027",
                "label": "“building block”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.03385",
                "label": "“bottleneck”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.11692",
                "label": "Liu, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/2016/10/news-dataset-available/",
                "label": "CommonCrawl News",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "Raffel et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.08730",
                "label": "McCann et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "sparse transformer",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2020/hash/1457c0d6bfcb4967418bfb8ac142f64a-Abstract.html",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.08237",
                "label": "Yang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "Lewis et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10555",
                "label": "Clark et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Perplexity",
                "label": "perplexity",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "more QA datasets in a later post",
                "type": "a"
              },
              {
                "href": "http://cs.rochester.edu/nlp/rocstories/",
                "label": "Story Cloze Test",
                "type": "a"
              },
              {
                "href": "https://rowanzellers.com/swag/",
                "label": "SWAG",
                "type": "a"
              },
              {
                "href": "https://aclweb.org/aclwiki/Textual_Entailment_Resource_Pool",
                "label": "RTE",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://www.nyu.edu/projects/bowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/tasks",
                "label": "QNLI",
                "type": "a"
              },
              {
                "href": "http://data.allenai.org/scitail/",
                "label": "SciTail",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2003/",
                "label": "CoNLL 2003 NER task",
                "type": "a"
              },
              {
                "href": "https://catalog.ldc.upenn.edu/LDC2013T19",
                "label": "OntoNotes 5.0",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/reuters/reuters.html",
                "label": "Reuters Corpus",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/sentiment/index.html",
                "label": "SST",
                "type": "a"
              },
              {
                "href": "http://ai.stanford.edu/~amaas/data/sentiment/",
                "label": "IMDb",
                "type": "a"
              },
              {
                "href": "http://www.lsi.upc.edu/~srlconll/",
                "label": "CoNLL-2004 & CoNLL-2005",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/download/details.aspx?id=52398",
                "label": "MRPC",
                "type": "a"
              },
              {
                "href": "https://data.quora.com/First-Quora-Dataset-Release-Question-Pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://nyu-mll.github.io/CoLA/",
                "label": "CoLA",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2000/chunking/",
                "label": "CoNLL-2000",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/nmt/",
                "label": "Standard NLP",
                "type": "a"
              },
              {
                "href": "http://conll.cemantix.org/2012/data.html",
                "label": "CoNLL-2012",
                "type": "a"
              },
              {
                "href": "http://clic.cimec.unitn.it/lambada/",
                "label": "LAMBADA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "Children’s Book Test",
                "type": "a"
              },
              {
                "href": "https://www.gutenberg.org/",
                "label": "Project Gutenberg",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/",
                "label": "https://gluebenchmark.com",
                "type": "a"
              },
              {
                "href": "https://decanlp.com/",
                "label": "https://decanlp.com",
                "type": "a"
              },
              {
                "href": "https://googlebooks.byu.edu/",
                "label": "Books corpus",
                "type": "a"
              },
              {
                "href": "http://www.statmt.org/lm-benchmark/",
                "label": "1B Word Language Model Benchmark",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wikipedia:Database_download",
                "label": "English Wikipedia",
                "type": "a"
              },
              {
                "href": "http://ruder.io/10-exciting-ideas-of-2018-in-nlp/",
                "label": "“10 Exciting Ideas of 2018 in NLP”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
          "status": "partial",
          "article_id": "bf0a610ccb4a",
          "local_path": "series-follow/1600/repair/61967ef293614fa66635.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
              "bytes": 513885,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f359d38ab20e9cdac179.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
              "bytes": 1270278,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8d6f8ad7272758de8c53.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
              "bytes": 768852,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7c81aafa4666fddd3762.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
              "bytes": 2642257,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c64df87fedc22e7713a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
              "bytes": 249192,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d72676a1e2d7d681665b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
              "bytes": 737673,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/284f09a3dc26a2be2be6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "bytes": 1162740,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/574c20fa1107bf61368d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
              "bytes": 566411,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/817ed503b242a7831692.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
              "bytes": 103291,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/26dfcda8fac62755a0e6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
              "bytes": 225014,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a7ef42a592f8d64c0933.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
              "bytes": 267029,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/38455ea040ea0eae9625.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
              "bytes": 163908,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2f0fc009f289b69c8d79.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
              "bytes": 1281590,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e3a5248959b284127268.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
              "bytes": 1411892,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/316474d8ca427819890a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
              "bytes": 218384,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7dd458cefc09c96c4325.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
              "bytes": 135102,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/70000ddd170ac7e5840b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
              "bytes": 2011971,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ae4b346db197ccab2cfe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
              "bytes": 157839,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1da73a82998c80ae17c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
              "bytes": 1115258,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/976ef652676b26b5a203.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
              "bytes": 1886891,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f8bf05d0018c01caf352.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
              "bytes": 2352713,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dee16f2c447f7c91e79e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
              "bytes": 917157,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7de401f88063093a58d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
              "bytes": 391776,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ce13a8280e64dce3dbf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
              "bytes": 1753636,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c37fd073afd7cb9698fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
              "bytes": 1839222,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e113f6beb0962c59d170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
              "bytes": 164404,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c9ea48204e2765c959ab.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
              "bytes": 388169,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/139471e0d9b6eef5fde9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
              "bytes": 350225,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/211c4ab593d56ae944a3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Self-Supervised Representation Learning",
            "keywords": "自监督,表示学习,预训练",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "publish_date": "2019-11",
            "corpus_stage": "预训练/SFT",
            "notes": "自监督表示学习综述",
            "id": "bf0a610ccb4a",
            "collected_at": "2026-10-02T14:13:29",
            "title": "Self-Supervised Representation Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-01-09: add a new section on\nContrastive Predictive Coding\n].\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n[Updated on 2020-07-08: add a\n“Bisimulation”\nsection on DeepMDP and DBC.]\n[Updated on 2020-09-12: add\nMoCo V2\nand\nBYOL\nin the “Momentum Contrast” section.]\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on\n“Contrastive Representation Learning”\n]\nGiven a task and enough labels, supervised learning can solve it really well. Good performance usually requires a decent amount of labels, but collecting manual labels is expensive (i.e. ImageNet) and hard to be scaled up. Considering the amount of unlabelled data (e.g. free text, all the images on the Internet) is substantially more than a limited number of human curated labelled datasets, it is kinda wasteful not to use them. However, unsupervised learning is not easy and usually works much less efficiently than supervised learning.\nWhat if we can get labels for free for unlabelled data and train unsupervised dataset in a supervised manner? We can achieve this by framing a supervised learning task in a special form to predict only a subset of information using the rest. In this way, all the information needed, both inputs and labels, has been provided. This is known as\nself-supervised learning\n.\nThis idea has been widely used in language modeling. The default task for a language model is to predict the next word given the past sequence.\nBERT\nadds two other auxiliary tasks and both rely on self-generated labels.\nA great summary of how self-supervised learning tasks can be constructed (Image source:\nLeCun’s talk\n)\nHere\nis a nicely curated list of papers in self-supervised learning. Please check it out if you are interested in reading more in depth.\nNote that this post does not focus on either NLP /\nlanguage modeling\nor\ngenerative modeling\n.\nWhy Self-Supervised Learning?\n#\nSelf-supervised learning empowers us to exploit a variety of labels that come with the data for free. The motivation is quite straightforward. Producing a dataset with clean labels is expensive but unlabeled data is being generated all the time. To make use of this much larger amount of unlabeled data, one way is to set the learning objectives properly so as to get supervision from the data itself.\nThe\nself-supervised task\n, also known as\npretext task\n, guides us to a supervised loss function. However, we usually don’t care about the final performance of this invented task. Rather we are interested in the learned intermediate representation with the expectation that this representation can carry good semantic or structural meanings and can be beneficial to a variety of practical downstream tasks.\nFor example, we might rotate images at random and train a model to predict how each input image is rotated. The rotation prediction task is made-up, so the actual accuracy is unimportant, like how we treat auxiliary tasks. But we expect the model to learn high-quality latent variables for real-world tasks, such as constructing an object recognition classifier with very few labeled samples.\nBroadly speaking, all the generative models can be considered as self-supervised, but with different goals: Generative models focus on creating diverse and realistic images, while self-supervised representation learning care about producing good features generally helpful for many tasks. Generative modeling is not the focus of this post, but feel free to check my\nprevious posts\n.\nImages-Based\n#\nMany ideas have been proposed for self-supervised representation learning on images. A common workflow is to train a model on one or multiple pretext tasks with unlabelled images and then use one intermediate feature layer of this model to feed a multinomial logistic regression classifier on ImageNet classification. The final classification accuracy quantifies how good the learned representation is.\nRecently, some researchers proposed to train supervised learning on labelled data and self-supervised pretext tasks on unlabelled data simultaneously with shared weights, like in\nZhai et al, 2019\nand\nSun et al, 2019\n.\nDistortion\n#\nWe expect small distortion on an image does not modify its original semantic meaning or geometric forms. Slightly distorted images are considered the same as original and thus the learned features are expected to be invariant to distortion.\nExemplar-CNN\n(\nDosovitskiy et al., 2015\n) create surrogate training datasets with unlabeled image patches:\nSample $N$ patches of size 32 × 32 pixels from different images at varying positions and scales, only from regions containing considerable gradients as those areas cover edges and tend to contain objects or parts of objects. They are\n“exemplary”\npatches.\nEach patch is distorted by applying a variety of random transformations (i.e., translation, rotation, scaling, etc.). All the resulting distorted patches are considered to belong to the\nsame surrogate class\n.\nThe pretext task is to discriminate between a set of surrogate classes. We can arbitrarily create as many surrogate classes as we want.\nThe original patch of a cute deer is in the top left corner. Random transformations are applied, resulting in a variety of distorted patches. All of them should be classified into the same class in the pretext task. (Image source:\nDosovitskiy et al., 2015\n)\nRotation\nof an entire image (\nGidaris et al. 2018\nis another interesting and cheap way to modify an input image while the semantic content stays unchanged. Each input image is first rotated by a multiple of $90^\\circ$ at random, corresponding to $[0^\\circ, 90^\\circ, 180^\\circ, 270^\\circ]$. The model is trained to predict which rotation has been applied, thus a 4-class classification problem.\nIn order to identify the same image with different rotations, the model has to learn to recognize high level object parts, such as heads, noses, and eyes, and the relative positions of these parts, rather than local patterns. This pretext task drives the model to learn semantic concepts of objects in this way.\nIllustration of self-supervised learning by rotating the entire input images. The model learns to predict which rotation is applied. (Image source:\nGidaris et al. 2018\n)\nPatches\n#\nThe second category of self-supervised learning tasks extract multiple patches from one image and ask the model to predict the relationship between these patches.\nDoersch et al. (2015)\nformulates the pretext task as predicting the\nrelative position\nbetween two random patches from one image. A model needs to understand the spatial context of objects in order to tell the relative position between parts.\nThe training patches are sampled in the following way:\nRandomly sample the first patch without any reference to image content.\nConsidering that the first patch is placed in the middle of a 3x3 grid, and the second patch is sampled from its 8 neighboring locations around it.\nTo avoid the model only catching low-level trivial signals, such as connecting a straight line across boundary or matching local patterns, additional noise is introduced by:\nAdd gaps between patches\nSmall jitters\nRandomly downsample some patches to as little as 100 total pixels, and then upsampling it, to build robustness to pixelation.\nShift green and magenta toward gray or randomly drop 2 of 3 color channels (See\n“chromatic aberration”\nbelow)\nThe model is trained to predict which one of 8 neighboring locations the second patch is selected from, a classification problem over 8 classes.\nIllustration of self-supervised learning by predicting the relative position of two random patches. (Image source:\nDoersch et al., 2015\n)\nOther than trivial signals like boundary patterns or textures continuing, another interesting and a bit surprising trivial solution was found, called\n“chromatic aberration”\n. It is triggered by different focal lengths of lights at different wavelengths passing through the lens. In the process, there might exist small offsets between color channels. Hence, the model can learn to tell the relative position by simply comparing how green and magenta are separated differently in two patches. This is a trivial solution and has nothing to do with the image content. Pre-processing images by shifting green and magenta toward gray or randomly dropping 2 of 3 color channels can avoid this trivial solution.\nIllustration of how chromatic aberration happens. (Image source:\nwikipedia\n)\nSince we have already set up a 3x3 grid in each image in the above task, why not use all of 9 patches rather than only 2 to make the task more difficult? Following this idea,\nNoroozi & Favaro (2016)\ndesigned a\njigsaw puzzle\ngame as pretext task: The model is trained to place 9 shuffled patches back to the original locations.\nA convolutional network processes each patch independently with shared weights and outputs a probability vector per patch index out of a predefined set of permutations. To control the difficulty of jigsaw puzzles, the paper proposed to shuffle patches according to a predefined permutation set and configured the model to predict a probability vector over all the indices in the set.\nBecause how the input patches are shuffled does not alter the correct order to predict. A potential improvement to speed up training is to use permutation-invariant graph convolutional network (GCN) so that we don’t have to shuffle the same set of patches multiple times, same idea as in this\npaper\n.\nIllustration of self-supervised learning by solving jigsaw puzzle. (Image source:\nNoroozi & Favaro, 2016\n)\nAnother idea is to consider “feature” or “visual primitives” as a scalar-value attribute that can be summed up over multiple patches and compared across different patches. Then the relationship between patches can be defined by\ncounting features\nand simple arithmetic (\nNoroozi, et al, 2017\n).\nThe paper considers two transformations:\nScaling\n:  If an image is scaled up by 2x, the number of visual primitives should stay the same.\nTiling\n: If an image is tiled into a 2x2 grid, the number of visual primitives is expected to be the sum, 4 times the original feature counts.\nThe model learns a feature encoder $\\phi(.)$ using the above feature counting relationship. Given an input image $\\mathbf{x} \\in \\mathbb{R}^{m \\times n \\times 3}$, considering two types of transformation operators:\nDownsampling operator, $D: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: downsample by a factor of 2\nTiling operator $T_i: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: extract the $i$-th tile from a 2x2 grid of the image.\nWe expect to learn:\n$$\n\\phi(\\mathbf{x}) = \\phi(D \\circ \\mathbf{x}) = \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\n$$\nThus the MSE loss is: $\\mathcal{L}_\\text{feat} = |\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2$. To avoid trivial solution $\\phi(\\mathbf{x}) = \\mathbf{0}, \\forall{\\mathbf{x}}$, another loss term is added to encourage the difference between features of two different images: $\\mathcal{L}_\\text{diff} = \\max(0, c -|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2)$, where $\\mathbf{y}$ is another input image different from $\\mathbf{x}$ and $c$ is a scalar constant. The final loss is:\n$$\n\\mathcal{L} \n= \\mathcal{L}_\\text{feat} + \\mathcal{L}_\\text{diff} \n= \\|\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2 + \\max(0, M -\\|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2)\n$$\nSelf-supervised representation learning by counting features. (Image source:\nNoroozi, et al, 2017\n)\nColorization\n#\nColorization\ncan be used as a powerful self-supervised task: a model is trained to color a grayscale input image; precisely the task is to map this image to a distribution over quantized color value outputs (\nZhang et al. 2016\n).\nThe model outputs colors in the the\nCIE L\na\nb* color space\n. The L\na\nb* color is designed to approximate human vision, while, in contrast, RGB or CMYK models the color output of physical devices.\nL* component matches human perception of lightness; L* = 0 is black and L* = 100 indicates white.\na* component represents green (negative) / magenta (positive) value.\nb* component models blue (negative) /yellow (positive) value.\nDue to the multimodal nature of the colorization problem, cross-entropy loss of predicted probability distribution over binned color values works better than L2 loss of the raw color values. The a\nb\ncolor space is quantized with bucket size 10.\nTo balance between common colors (usually low a\nb\nvalues, of common backgrounds like clouds, walls, and dirt) and rare colors (which are likely associated with key objects in the image), the loss function is rebalanced with a weighting term that boosts the loss of infrequent color buckets. This is just like why we need both\ntf and idf\nfor scoring words in information retrieval model. The weighting term is constructed as: (1-λ) * Gaussian-kernel-smoothed empirical probability distribution + λ * a uniform distribution, where both distributions are over the quantized a\nb\ncolor space.\nGenerative Modeling\n#\nThe pretext task in generative modeling is to reconstruct the original input while learning meaningful latent representation.\nThe\ndenoising autoencoder\n(\nVincent, et al, 2008\n) learns to recover an image from a version that is partially corrupted or has random noise. The design is inspired by the fact that humans can easily recognize objects in pictures even with noise, indicating that key visual features can be extracted and separated from noise. See my\nold post\n.\nThe\ncontext encoder\n(\nPathak, et al., 2016\n) is trained to fill in a missing piece in the image. Let $\\hat{M}$ be a binary mask, 0 for dropped pixels and 1 for remaining input pixels. The model is trained with a combination of the reconstruction (L2) loss and the adversarial loss. The removed regions defined by the mask could be of any shape.\n$$\n\\begin{aligned}\n\\mathcal{L}(\\mathbf{x}) &= \\mathcal{L}_\\text{recon}(\\mathbf{x}) + \\mathcal{L}_\\text{adv}(\\mathbf{x})\\\\\n\\mathcal{L}_\\text{recon}(\\mathbf{x}) &= \\|(1 - \\hat{M}) \\odot (\\mathbf{x} - F(\\hat{M} \\odot \\mathbf{x})) \\|_2^2 \\\\\n\\mathcal{L}_\\text{adv}(\\mathbf{x}) &= \\max_D \\mathbb{E}_{\\mathbf{x}} [\\log D(\\mathbf{x}) + \\log(1 - D(F(\\hat{M} \\odot \\mathbf{x})))]\n\\end{aligned}\n$$\nwhere $F(.)$ is the full pipeline of reconstructing the input image with missing regions via impainting, including both encoder and decoder portions in $D(.)$ is the discriminator model jointly trained, like in\nGAN\n.\nIllustration of context encoder. (Image source:\nPathak, et al., 2016\n)\nWhen applying a mask on an image, the context encoder removes information of all the color channels in partial regions. How about only hiding a subset of channels? The\nsplit-brain autoencoder\n(\nZhang et al., 2017\n) does this by predicting a subset of color channels from the rest of channels. Let the data tensor $\\mathbf{x} \\in \\mathbb{R}^{h \\times w \\times \\vert C \\vert }$ with $C$ color channels be the input for the $l$-th layer of the network. It is split into two disjoint parts, $\\mathbf{x}_1 \\in \\mathbb{R}^{h \\times w \\times \\vert C_1 \\vert}$ and $\\mathbf{x}_2 \\in \\mathbb{R}^{h \\times w \\times \\vert C_2 \\vert}$, where $C_1 , C_2 \\subseteq C$. Then two sub-networks are trained to do two complementary predictions: one network $f_1$ predicts $\\mathbf{x}_2$ from $\\mathbf{x}_1$ and the other network $f_1$ predicts $\\mathbf{x}_1$ from $\\mathbf{x}_2$. The loss is either L1 loss or cross entropy if color values are quantized.\nThe split can happen once on the RGB-D or L\na\nb* colorspace, or happen even in every layer of a CNN network in which the number of channels can be arbitrary.\nIllustration of split-brain autoencoder. (Image source:\nZhang et al., 2017\n)\nThe generative adversarial networks (GANs) are able to learn to map from simple latent variables to arbitrarily complex data distributions. Studies have shown that the latent space of such generative models captures semantic variation in the data; e.g. when training GAN models on human faces, some latent variables are associated with facial expression, glasses, gender, etc  (\nRadford et al., 2016\n).\nBidirectional GANs\n(\nDonahue, et al, 2017\n) introduces an additional encoder $E(.)$ to learn the mappings from the input to the latent variable $\\mathbf{z}$. The discriminator $D(.)$ predicts in the joint space of the input data and latent representation, $(\\mathbf{x}, \\mathbf{z})$, to tell apart the generated pair $(\\mathbf{x}, E(\\mathbf{x}))$ from the real one $(G(\\mathbf{z}), \\mathbf{z})$. The model is trained to optimize the objective: $\\min_{G, E} \\max_D V(D, E, G)$, where the generator $G$ and the encoder $E$ learn to generate data and latent variables that are realistic enough to confuse the discriminator and at the same time the discriminator $D$ tries to differentiate real and generated data.\n$$\nV(D, E, G) = \\mathbb{E}_{\\mathbf{x} \\sim p_\\mathbf{x}} [ \\underbrace{\\mathbb{E}_{\\mathbf{z} \\sim p_E(.\\vert\\mathbf{x})}[\\log D(\\mathbf{x}, \\mathbf{z})]}_{\\log D(\\text{real})} ] + \\mathbb{E}_{\\mathbf{z} \\sim p_\\mathbf{z}} [ \\underbrace{\\mathbb{E}_{\\mathbf{x} \\sim p_G(.\\vert\\mathbf{z})}[\\log 1 - D(\\mathbf{x}, \\mathbf{z})]}_{\\log(1- D(\\text{fake}))}) ]\n$$\nIllustration of how Bidirectional GAN works. (Image source:\nDonahue, et al, 2017\n)\nContrastive Learning\n#\nThe\nContrastive Predictive Coding (CPC)\n(\nvan den Oord, et al. 2018\n) is an approach for unsupervised learning from high-dimensional data by translating a generative modeling problem to a classification problem. The\ncontrastive loss\nor\nInfoNCE loss\nin CPC, inspired by\nNoise Contrastive Estimation (NCE)\n, uses cross-entropy loss to measure how well the model can classify the “future” representation amongst a set of unrelated “negative” samples. Such design is partially motivated by the fact that the unimodal loss like MSE has no enough capacity but learning a full generative model could be too expensive.\nIllustration of applying Contrastive Predictive Coding on the audio input. (Image source:\nvan den Oord, et al. 2018\n)\nCPC uses an encoder to compress the input data $z_t = g_\\text{enc}(x_t)$ and an\nautoregressive\ndecoder to learn the high-level context that is potentially shared across future predictions, $c_t = g_\\text{ar}(z_{\\leq t})$. The end-to-end training relies on the NCE-inspired contrastive loss.\nWhile predicting future information, CPC is optimized to maximize the the mutual information between input $x$ and context vector $c$:\n$$\nI(x; c) = \\sum_{x, c} p(x, c) \\log\\frac{p(x, c)}{p(x)p(c)} = \\sum_{x, c} p(x, c)\\log\\frac{p(x|c)}{p(x)}\n$$\nRather than modeling the future observations $p_k(x_{t+k} \\vert c_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $x_{t+k}$ and $c_t$:\n$$\nf_k(x_{t+k}, c_t) = \\exp(z_{t+k}^\\top W_k c_t) \\propto \\frac{p(x_{t+k}|c_t)}{p(x_{t+k})}\n$$\nwhere $f_k$ can be unnormalized and a linear transformation $W_k^\\top c_t$ is used for the prediction with a different $W_k$ matrix for every step $k$.\nGiven a set of $N$ random samples $X = \\{x_1, \\dots, x_N\\}$ containing only one positive sample $x_t \\sim p(x_{t+k} \\vert c_t)$ and $N-1$ negative samples $x_{i \\neq t} \\sim p(x_{t+k})$, the cross-entropy loss for classifying the positive sample (where $\\frac{f_k}{\\sum f_k}$ is the prediction) correctly is:\n$$\n\\mathcal{L}_N = - \\mathbb{E}_X \\Big[\\log \\frac{f_k(x_{t+k}, c_t)}{\\sum_{i=1}^N f_k (x_i, c_t)}\\Big]\n$$\nIllustration of applying Contrastive Predictive Coding on images. (Image source:\nvan den Oord, et al. 2018\n)\nWhen using CPC on images (\nHenaff, et al. 2019\n), the predictor network should only access a masked feature set to avoid a trivial prediction. Precisely:\nEach input image is divided into a set of overlapped patches and each patch is encoded by a resnet encoder, resulting in compressed feature vector $z_{i,j}$.\nA masked conv net makes prediction with a mask such that the receptive field of a given output neuron can only see things above it in the image. Otherwise, the prediction problem would be trivial. The prediction can be made in both directions (top-down and bottom-up).\nThe prediction is made for $z_{i+k, j}$ from context $c_{i,j}$: $\\hat{z}_{i+k, j} = W_k c_{i,j}$.\nA contrastive loss quantifies this prediction with a goal to correctly identify the target among a set of negative representation $\\{z_l\\}$ sampled from other patches in the same image and other images in the same batch:\n$$\n\\mathcal{L}_\\text{CPC} \n= -\\sum_{i,j,k} \\log p(z_{i+k, j} \\vert \\hat{z}_{i+k, j}, \\{z_l\\}) \n= -\\sum_{i,j,k} \\log \\frac{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j})}{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j}) + \\sum_l \\exp(\\hat{z}_{i+k, j}^\\top z_l)}\n$$\nFor more content on contrastive learning, check out the post on\n“Contrastive Representation Learning”\n.\nVideo-Based\n#\nA video contains a sequence of semantically related frames. Nearby frames are close in time and more correlated than frames further away. The order of frames describes certain rules of reasonings and physical logics; such as that object motion should be smooth and gravity is pointing down.\nA common workflow is to train a model on one or multiple pretext tasks with unlabelled videos and then feed one intermediate feature layer of this model to fine-tune a simple model on downstream tasks of action classification, segmentation or object tracking.\nTracking\n#\nThe movement of an object is traced by a sequence of video frames. The difference between how the same object is captured on the screen in close frames is usually not big, commonly triggered by small motion of the object or the camera. Therefore any visual representation learned for the same object across close frames should be close in the latent feature space. Motivated by this idea,\nWang & Gupta, 2015\nproposed a way of unsupervised learning of visual representation by\ntracking moving objects\nin videos.\nPrecisely patches with motion are tracked over a small time window (e.g. 30 frames). The first patch $\\mathbf{x}$ and the last patch $\\mathbf{x}^+$ are selected and used as training data points. If we train the model directly to minimize the difference between feature vectors of two patches, the model may only learn to map everything to the same value. To avoid such a trivial solution, same as\nabove\n, a random third patch $\\mathbf{x}^-$ is added. The model learns the representation by enforcing the distance between two tracked patches to be closer than the distance between the first patch and a random one in the feature space, $D(\\mathbf{x}, \\mathbf{x}^-)) > D(\\mathbf{x}, \\mathbf{x}^+)$, where $D(.)$ is the cosine distance,\n$$\nD(\\mathbf{x}_1, \\mathbf{x}_2) = 1 - \\frac{f(\\mathbf{x}_1) f(\\mathbf{x}_2)}{\\|f(\\mathbf{x}_1)\\| \\|f(\\mathbf{x}_2\\|)}\n$$\nThe loss function is:\n$$\n\\mathcal{L}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) \n= \\max\\big(0, D(\\mathbf{x}, \\mathbf{x}^+) - D(\\mathbf{x}, \\mathbf{x}^-) + M\\big) + \\text{weight decay regularization term}\n$$\nwhere $M$ is a scalar constant controlling for the minimum gap between two distances; $M=0.5$ in the paper. The loss enforces $D(\\mathbf{x}, \\mathbf{x}^-) >= D(\\mathbf{x}, \\mathbf{x}^+) + M$ at the optimal case.\nThis form of loss function is also known as\ntriplet loss\nin the face recognition task, in which the dataset contains images of multiple people from multiple camera angles. Let $\\mathbf{x}^a$ be an anchor image of a specific person, $\\mathbf{x}^p$ be a positive image of this same person from a different angle and $\\mathbf{x}^n$ be a negative image of a different person. In the embedding space, $\\mathbf{x}^a$ should be closer to $\\mathbf{x}^p$ than $\\mathbf{x}^n$:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}^a, \\mathbf{x}^p, \\mathbf{x}^n) = \\max(0, \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^p) \\|_2^2 -  \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^n) \\|_2^2 + M)\n$$\nA slightly different form of the triplet loss, named\nn-pair loss\nis also commonly used for learning observation embedding in robotics tasks. See a\nlater section\nfor more related content.\nOverview of learning representation by tracking objects in videos. (a) Identify moving patches in short traces; (b) Feed two related patched and one random patch into a conv network with shared weights. (c) The loss function enforces the distance between related patches to be closer than the distance between random patches. (Image source:\nWang & Gupta, 2015\n)\nRelevant patches are tracked and extracted through a two-step unsupervised\noptical flow\napproach:\nObtain\nSURF\ninterest points and use\nIDT\nto obtain motion of each SURF point.\nGiven the trajectories of SURF interest points, classify these points as moving if the flow magnitude is more than 0.5 pixels.\nDuring training, given a pair of correlated patches $\\mathbf{x}$ and $\\mathbf{x}^+$, $K$ random patches $\\{\\mathbf{x}^-\\}$ are sampled in this same batch to form $K$ training triplets. After a couple of epochs,\nhard negative mining\nis applied to make the training harder and more efficient, that is, to search for random patches that maximize the loss and use them to do gradient updates.\nFrame Sequence\n#\nVideo frames are naturally positioned in chronological order. Researchers have proposed several self-supervised tasks, motivated by the expectation that good representation should learn the\ncorrect sequence\nof frames.\nOne idea is to\nvalidate frame order\n(\nMisra, et al 2016\n). The pretext task is to determine whether a sequence of frames from a video is placed in the correct temporal order (“temporal valid”). The model needs to track and reason about small motion of an object across frames to complete such a task.\nThe training frames are sampled from high-motion windows. Every time 5 frames are sampled $(f_a, f_b, f_c, f_d, f_e)$ and the timestamps are in order $a < b < c < d < e$. Out of 5 frames, one positive tuple $(f_b, f_c, f_d)$ and two negative tuples, $(f_b, f_a, f_d)$ and $(f_b, f_e, f_d)$ are created. The parameter $\\tau_\\max = \\vert b-d \\vert$ controls the difficulty of positive training instances (i.e. higher → harder) and the parameter $\\tau_\\min = \\min(\\vert a-b \\vert, \\vert d-e \\vert)$ controls the difficulty of negatives (i.e. lower → harder).\nThe pretext task of video frame order validation is shown to improve the performance on the downstream task of action recognition when used as a pretraining step.\nOverview of learning representation by validating the order of video frames. (a) the data sample process; (b) the model is a triplet siamese network, where all input frames have shared weights. (Image source:\nMisra, et al 2016\n)\nThe task in\nO3N\n(Odd-One-Out Network;\nFernando et al. 2017\n) is based on video frame sequence validation too. One step further from above, the task is to\npick the incorrect sequence\nfrom multiple video clips.\nGiven $N+1$ input video clips, one of them has frames shuffled, thus in the wrong order, and the rest $N$ of them remain in the correct temporal order. O3N learns to predict the location of the odd video clip. In their experiments, there are 6 input clips and each contain 6 frames.\nThe\narrow of time\nin a video contains very informative messages, on both low-level physics (e.g. gravity pulls objects down to the ground; smoke rises up; water flows downward.) and high-level event reasoning (e.g. fish swim forward; you can break an egg but cannot revert it.). Thus another idea is inspired by this to learn latent representation by predicting the arrow of time (AoT) — whether video playing forwards or backwards (\nWei et al., 2018\n).\nA classifier should capture both low-level physics and high-level semantics in order to predict the arrow of time. The proposed\nT-CAM\n(Temporal Class-Activation-Map) network accepts $T$ groups, each containing a number of frames of optical flow. The conv layer outputs from each group are concatenated and fed into binary logistic regression for predicting the arrow of time.\nOverview of learning representation by predicting the arrow of time. (a) Conv features of multiple groups of frame sequences are concatenated. (b) The top level contains 3 conv layers and average pooling. (Image source:\nWei et al, 2018\n)\nInterestingly, there exist a couple of artificial cues in the dataset. If not handled properly, they could lead to a trivial classifier without relying on the actual video content:\nDue to the video compression, the black framing might not be completely black but instead may contain certain information on the chronological order. Hence black framing should be removed in the experiments.\nLarge camera motion, like vertical translation or zoom-in/out, also provides strong signals for the arrow of time but independent of content. The processing stage should stabilize the camera motion.\nThe AoT pretext task is shown to improve the performance on action classification downstream task when used as a pretraining step. Note that fine-tuning is still needed.\nVideo Colorization\n#\nVondrick et al. (2018)\nproposed\nvideo colorization\nas a self-supervised learning problem, resulting in a rich representation that can be used for video segmentation and unlabelled visual region tracking,\nwithout extra fine-tuning\n.\nUnlike the image-based\ncolorization\n, here the task is to copy colors from a normal reference frame in color to another target frame in grayscale by leveraging the natural temporal coherency of colors across video frames (thus these two frames shouldn’t be too far apart in time). In order to copy colors consistently, the model is designed to learn to keep track of correlated pixels in different frames.\nVideo colorization by copying colors from a reference frame to target frames in grayscale.  (Image source:\nVondrick et al. 2018\n)\nThe idea is quite simple and smart. Let $c_i$ be the true color of the $i-th$ pixel in the reference frame and $c_j$ be the color of $j$-th pixel in the target frame. The predicted color of $j$-th color in the target $\\hat{c}_j$ is a weighted sum of colors of all the pixels in reference, where the weighting term measures the similarity:\n$$\n\\hat{c}_j = \\sum_i A_{ij} c_i \\text{ where } A_{ij} = \\frac{\\exp(f_i f_j)}{\\sum_{i'} \\exp(f_{i'} f_j)}\n$$\nwhere $f$ are learned embeddings for corresponding pixels; $i’$ indexes all the pixels in the reference frame. The weighting term implements an attention-based pointing mechanism, similar to\nmatching network\nand\npointer network\n. As the full similarity matrix could be really large, both frames are downsampled. The categorical cross-entropy loss between $c_j$ and $\\hat{c}_j$ is used with quantized colors, just like in\nZhang et al. 2016\n.\nBased on how the reference frame are marked, the model can be used to complete several color-based downstream tasks such as tracking segmentation or human pose in time. No fine-tuning is needed. See\nUse video colorization to track object segmentation and human pose in time. (Image source:\nVondrick et al. (2018)\n)\nA couple common observations:\nCombining multiple pretext tasks improves performance;\nDeeper networks improve the quality of representation;\nSupervised learning baselines still beat all of them by far.\nControl-Based\n#\nWhen running a RL policy in the real world, such as controlling a physical robot on visual inputs, it is non-trivial to properly track states, obtain reward signals or determine whether a goal is achieved for real. The visual data has a lot of noise that is irrelevant to the true state and thus the equivalence of states cannot be inferred from pixel-level comparison. Self-supervised representation learning has shown great potential in learning useful state embedding that can be used directly as input to a control policy.\nAll the cases discussed in this section are in robotic learning, mainly for state representation from multiple camera views and goal representation.\nMulti-View Metric Learning\n#\nThe concept of metric learning has been mentioned multiple times in the\nprevious\nsections\n. A common setting is: Given a triple of samples, (\nanchor\n$s_a$,\npositive\nsample $s_p$,\nnegative\nsample $s_n$), the learned representation embedding $\\phi(s)$ fulfills that $s_a$ stays close to $s_p$ but far away from $s_n$ in the latent space.\nGrasp2Vec\n(\nJang & Devin et al., 2018\n) aims to learn an object-centric vision representation in the robot grasping task from free, unlabelled grasping activities. By object-centric, it means that, irrespective of how the environment or the robot looks like, if two images contain similar items, they should be mapped to similar representation; otherwise the embeddings should be far apart.\nA conceptual illustration of how grasp2vec learns an object-centric state embedding. (Image source:\nJang & Devin et al., 2018\n)\nThe grasping system can tell whether it moves an object but cannot tell which object it is. Cameras are set up to take images of the entire scene and the grasped object. During early training, the grasp robot is executed to grasp any object $o$ at random, producing a triple of images, $(s_\\text{pre}, s_\\text{post}, o)$:\n$o$ is an image of the grasped object held up to the camera;\n$s_\\text{pre}$ is an image of the scene\nbefore\ngrasping, with the object $o$ in the tray;\n$s_\\text{post}$ is an image of the same scene\nafter\ngrasping, without the object $o$ in the tray.\nTo learn object-centric representation, we expect the difference between embeddings of $s_\\text{pre}$ and $s_\\text{post}$ to capture the removed object $o$. The idea is quite interesting and similar to relationships that have been observed in\nword embedding\n,\ne.g.\ndistance(“king”, “queen”) ≈ distance(“man”, “woman”).\nLet $\\phi_s$ and $\\phi_o$ be the embedding functions for the scene and the object respectively. The model learns the representation by minimizing the distance between $\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})$ and $\\phi_o(o)$ using\nn-pair loss\n:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{grasp2vec} &= \\text{NPair}(\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post}), \\phi_o(o)) + \\text{NPair}(\\phi_o(o), \\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})) \\\\\n\\text{where }\\text{NPair}(a, p) &= \\sum_{i<{B}} -\\log\\frac{\\exp(a_i^\\top p_j)}{\\sum_{j<{B}, i\\neq j}\\exp(a_i^\\top p_j)} + \\lambda (\\|a_i\\|_2^2 + \\|p_i\\|_2^2)\n\\end{aligned}\n$$\nwhere $B$ refers to a batch of (anchor, positive) sample pairs.\nWhen framing representation learning as metric learning,\nn-pair loss\nis a common choice. Rather than processing explicit a triple of (anchor, positive, negative) samples, the n-pairs loss treats all other positive instances in one mini-batch across pairs as negatives.\nThe embedding function $\\phi_o$ works great for presenting a goal $g$ with an image. The reward function that quantifies how close the actually grasped object $o$ is close to the goal is defined as $r = \\phi_o(g) \\cdot \\phi_o(o)$. Note that computing rewards only relies on the learned latent space and doesn’t involve ground truth positions, so it can be used for training on real robots.\nLocalization results of grasp2vec embedding. The heatmap of localizing a goal object in a pre-grasping scene is defined as $\\phi\\_o(o)^\\top \\phi\\_{s, \\text{spatial}} (s\\_\\text{pre})$, where $\\phi\\_{s, \\text{spatial}}$ is the output of the last resnet block after ReLU. The fourth column is a failure case and the last three columns take real images as goals. (Image source:\nJang & Devin et al., 2018\n)\nOther than the embedding-similarity-based reward function, there are a few other tricks for training the RL policy in the grasp2vec framework:\nPosthoc labeling\n: Augment the dataset by labeling a randomly grasped object as a correct goal, like HER (Hindsight Experience Replay;\nAndrychowicz, et al., 2017\n).\nAuxiliary goal augmentation\n: Augment the replay buffer even further by relabeling transitions with unachieved goals; precisely, in each iteration, two goals are sampled $(g, g’)$ and both are used to add new transitions into replay buffer.\nTCN\n(\nTime-Contrastive Networks\n;\nSermanet, et al. 2018\n) learn from multi-camera view videos with the intuition that different viewpoints at the same timestep of the same scene should share the same embedding (like in\nFaceNet\n) while embedding should vary in time, even of the same camera viewpoint. Therefore embedding captures the semantic meaning of the underlying state rather than visual similarity. The TCN embedding is trained with\ntriplet loss\n.\nThe training data is collected by taking videos of the same scene simultaneously but from different angles. All the videos are unlabelled.\nAn illustration of time-contrastive approach for learning state embedding. The blue frames selected from two camera views at the same timestep are anchor and positive samples, while the red frame at a different timestep is the negative sample.\nTCN embedding extracts visual features that are invariant to camera configurations. It can be used to construct a reward function for imitation learning based on the euclidean distance between the demo video and the observations in the latent space.\nA further improvement over TCN is to learn embedding over multiple frames jointly rather than a single frame, resulting in\nmfTCN\n(\nMulti-frame\nTime-Contrastive Networks\n;\nDwibedi et al., 2019\n). Given a set of videos from several synchronized camera viewpoints, $v_1, v_2, \\dots, v_k$, the frame at time $t$ and the previous $n-1$ frames selected with stride $s$ in each video are aggregated and mapped into one embedding vector, resulting in a lookback window of size $(n−1) \\times s + 1$. Each frame first goes through a CNN to extract low-level features and then we use 3D temporal convolutions to aggregate frames in time. The model is trained with\nn-pairs loss\n.\nThe sampling process for training mfTCN. (Image source:\nDwibedi et al., 2019\n)\nThe training data is sampled as follows:\nFirst we construct two pairs of video clips. Each pair contains two clips from different camera views but with synchronized timesteps. These two sets of videos should be far apart in time.\nSample a fixed number of frames from each video clip in the same pair simultaneously with the same stride.\nFrames with the same timesteps are trained as positive samples in the n-pair loss, while frames across pairs are negative samples.\nmfTCN embedding can capture the position and velocity of objects in the scene (e.g. in cartpole) and can also be used as inputs for policy.\nAutonomous Goal Generation\n#\nRIG\n(\nReinforcement learning with\nImagined Goals\n;\nNair et al., 2018\n) described a way to train a goal-conditioned policy with unsupervised representation learning. A policy learns from self-supervised practice by first imagining “fake” goals and then trying to achieve them.\nThe workflow of RIG. (Image source:\nNair et al., 2018\n)\nThe task is to control a robot arm to push a small puck on a table to a desired position. The desired position, or the goal, is present in an image. During training, it learns latent embedding of both state $s$ and goal $g$ through $\\beta$-VAE encoder and the control policy operates entirely in the latent space.\nLet’s say a\n$\\beta$-VAE\nhas an encoder $q_\\phi$ mapping input states to latent variable $z$ which is modeled by a Gaussian distribution and a decoder $p_\\psi$ mapping $z$ back to the states. The state encoder in RIG is set to be the mean of $\\beta$-VAE encoder.\n$$\n\\begin{aligned}\nz &\\sim q_\\phi(z \\vert s) = \\mathcal{N}(z; \\mu_\\phi(s), \\sigma^2_\\phi(s)) \\\\\n\\mathcal{L}_{\\beta\\text{-VAE}} &= - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s)} [\\log p_\\psi (s \\vert z)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s) \\| p_\\psi(s)) \\\\\ne(s) &\\triangleq \\mu_\\phi(s)\n\\end{aligned}\n$$\nThe reward is the Euclidean distance between state and goal embedding vectors: $r(s, g) = -|e(s) - e(g)|$. Similar to\ngrasp2vec\n, RIG applies data augmentation as well by latent goal relabeling: precisely half of the goals are generated from the prior at random and the other half are selected using HER. Also same as grasp2vec, rewards do not depend on any ground truth states but only the learned state encoding, so it can be used for training on real robots.\nThe algorithm of RIG. (Image source:\nNair et al., 2018\n)\nThe problem with RIG is a lack of object variations in the imagined goal pictures. If $\\beta$-VAE is only trained with a black puck, it would not be able to create a goal with other objects like blocks of different shapes and colors. A follow-up improvement replaces $\\beta$-VAE with a\nCC-VAE\n(Context-Conditioned VAE;\nNair, et al., 2019\n), inspired by\nCVAE\n(Conditional VAE;\nSohn, Lee & Yan, 2015\n), for goal generation.\nThe workflow of context-conditioned RIG. (Image source:\nNair, et al., 2019\n).\nA CVAE conditions on a context variable $c$. It trains an encoder $q_\\phi(z \\vert s, c)$ and a decoder $p_\\psi (s \\vert z, c)$ and note that both have access to $c$. The CVAE loss penalizes information passing from the input state $s$ through an information bottleneck but allows for\nunrestricted\ninformation flow from $c$ to both encoder and decoder.\n$$\n\\mathcal{L}_\\text{CVAE} = - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s,c)} [\\log p_\\psi (s \\vert z, c)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s, c) \\| p_\\psi(s))\n$$\nTo create plausible goals, CC-VAE conditions on a starting state $s_0$ so that the generated goal presents a consistent type of object as in $s_0$. This goal consistency is necessary; e.g. if the current scene contains a red puck but the goal has a blue block, it would confuse the policy.\nOther than the state encoder $e(s) \\triangleq \\mu_\\phi(s)$, CC-VAE trains a second convolutional encoder $e_0(.)$ to translate the starting state $s_0$ into a compact context representation $c = e_0(s_0)$. Two encoders, $e(.)$ and $e_0(.)$, are intentionally different without shared weights, as they are expected to encode different factors of image variation. In addition to the loss function of CVAE, CC-VAE adds an extra term to learn to reconstruct $c$ back to $s_0$, $\\hat{s}_0 = d_0(c)$.\n$$\n\\mathcal{L}_\\text{CC-VAE} = \\mathcal{L}_\\text{CVAE} + \\log p(s_0\\vert c)\n$$\nExamples of imagined goals generated by CVAE that conditions on the context image (the first row), while VAE fails to capture the object consistency. (Image source:\nNair, et al., 2019\n).\nBisimulation\n#\nTask-agnostic representation (e.g. a model that intends to represent all the dynamics in the system) may distract the RL algorithms as irrelevant information is also presented. For example, if we just train an auto-encoder to reconstruct the input image, there is no guarantee that the entire learned representation will be useful for RL. Therefore, we need to move away from reconstruction-based representation learning if we only want to learn information relevant to control, as irrelevant details are still important for reconstruction.\nRepresentation learning for control based on bisimulation does not depend on reconstruction, but aims to group states based on their behavioral similarity in MDP.\nBisimulation\n(\nGivan et al. 2003\n) refers to an equivalence relation between two states with similar long-term behavior.\nBisimulation metrics\nquantify such relation so that we can aggregate states to compress a high-dimensional state space into a smaller one for more efficient computation. The\nbisimulation distance\nbetween two states corresponds to how behaviorally different these two states are.\nGiven a\nMDP\n$\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, \\mathcal{P}, \\mathcal{R}, \\gamma \\rangle$ and a bisimulation relation $B$, two states that are equal under relation $B$ (i.e. $s_i B s_j$) should have the same immediate reward for all actions and the same transition probabilities over the next bisimilar states:\n$$\n\\begin{aligned}\n\\mathcal{R}(s_i, a) &= \\mathcal{R}(s_j, a) \\; \\forall a \\in \\mathcal{A} \\\\\n\\mathcal{P}(G \\vert s_i, a) &= \\mathcal{P}(G \\vert s_j, a) \\; \\forall a \\in \\mathcal{A} \\; \\forall G \\in \\mathcal{S}_B\n\\end{aligned}\n$$\nwhere $\\mathcal{S}_B$ is a partition of the state space under the relation $B$.\nNote that $=$ is always a bisimulation relation. The most interesting one is the maximal bisimulation relation $\\sim$, which defines a partition $\\mathcal{S}_\\sim$ with\nfewest\ngroups of states.\nDeepMDP learns a latent space model by minimizing two losses on a reward model and a dynamics model. (Image source:\nGelada, et al. 2019\n)\nWith a goal similar to bisimulation metric,\nDeepMDP\n(\nGelada, et al. 2019\n) simplifies high-dimensional observations in RL tasks and learns a latent space model via minimizing two losses:\nprediction of rewards and\nprediction of the distribution over next latent states.\n$$\n\\begin{aligned}\n\\mathcal{L}_{\\bar{\\mathcal{R}}}(s, a) = \\vert \\mathcal{R}(s, a) - \\bar{\\mathcal{R}}(\\phi(s), a) \\vert \\\\\n\\mathcal{L}_{\\bar{\\mathcal{P}}}(s, a) = D(\\phi \\mathcal{P}(s, a), \\bar{\\mathcal{P}}(. \\vert \\phi(s), a))\n\\end{aligned}\n$$\nwhere $\\phi(s)$ is the embedding of state $s$; symbols with bar are functions (reward function $R$ and transition function $P$) in the same MDP but running in the latent low-dimensional observation space. Here the embedding representation $\\phi$ can be connected to bisimulation metrics, as the bisimulation distance is proved to be upper-bounded by the L2 distance in the latent space.\nThe function $D$ quantifies the distance between two probability distributions and should be chosen carefully. DeepMDP focuses on\nWasserstein-1\nmetric (also known as\n“earth-mover distance”\n). The Wasserstein-1 distance between distributions $P$ and $Q$ on a metric space $(M, d)$ (i.e., $d: M \\times M \\to \\mathbb{R}$) is:\n$$\nW_d (P, Q) = \\inf_{\\lambda \\in \\Pi(P, Q)} \\int_{M \\times M} d(x, y) \\lambda(x, y) \\; \\mathrm{d}x \\mathrm{d}y\n$$\nwhere $\\Pi(P, Q)$ is the set of all\ncouplings\nof $P$ and $Q$. $d(x, y)$ defines the cost of moving a particle from point $x$ to point $y$.\nThe Wasserstein metric has a dual form according to the Monge-Kantorovich duality:\n$$\nW_d (P, Q) = \\sup_{f \\in \\mathcal{F}_d} \\vert \\mathbb{E}_{x \\sim P} f(x) - \\mathbb{E}_{y \\sim Q} f(y) \\vert\n$$\nwhere $\\mathcal{F}_d$ is the set of 1-Lipschitz functions under the metric $d$ - $\\mathcal{F}_d = \\{ f: \\vert f(x) - f(y) \\vert \\leq d(x, y) \\}$.\nDeepMDP generalizes the model to the Norm Maximum Mean Discrepancy (Norm-\nMMD\n) metrics to improve the tightness of the bounds of its deep value function and, at the same time, to save computation (Wasserstein is expensive computationally). In their experiments, they found the model architecture of the transition prediction model can have a big impact on the performance. Adding these DeepMDP losses as auxiliary losses when training model-free RL agents leads to good improvement on most of the Atari games.\nDeep Bisimulatioin for Control\n(short for\nDBC\n;\nZhang et al. 2020\n) learns the latent representation of observations that are good for control in RL tasks, without domain knowledge or pixel-level reconstruction.\nThe Deep Bisimulation for Control algorithm learns a bisimulation metric representation via learning a reward model and a dynamics model. The model architecture is a siamese network. (Image source:\nZhang et al. 2020\n)\nSimilar to DeepMDP, DBC models the dynamics by learning a reward model and a transition model. Both models operate in the latent space, $\\phi(s)$. The optimization of embedding $\\phi$ depends on one important conclusion from\nFerns, et al. 2004\n(Theorem 4.5) and\nFerns, et al 2011\n(Theorem 2.6):\nGiven $c \\in (0, 1)$ a discounting factor, $\\pi$ a policy that is being improved continuously, and $M$ the space of bounded\npseudometric\non the state space $\\mathcal{S}$, we can define $\\mathcal{F}: M \\mapsto M$:\n$$\n\\mathcal{F}(d; \\pi)(s_i, s_j) = (1-c) \\vert \\mathcal{R}_{s_i}^\\pi - \\mathcal{R}_{s_j}^\\pi \\vert + c W_d (\\mathcal{P}_{s_i}^\\pi, \\mathcal{P}_{s_j}^\\pi)\n$$\nThen, $\\mathcal{F}$ has a unique fixed point $\\tilde{d}$ which is a $\\pi^*$-bisimulation metric and $\\tilde{d}(s_i, s_j) = 0 \\iff s_i \\sim s_j$.\n[The proof is not trivial. I may or may not add it in the future  _(:3」∠)_ …]\nGiven batches of observations pairs, the training loss for $\\phi$, $J(\\phi)$, minimizes the mean square error between the on-policy bisimulation metric and Euclidean distance in the latent space:\n$$\nJ(\\phi) = \\Big( \\|\\phi(s_i) - \\phi(s_j)\\|_1 - \\vert \\hat{\\mathcal{R}}(\\bar{\\phi}(s_i)) - \\hat{\\mathcal{R}}(\\bar{\\phi}(s_j)) \\vert - \\gamma W_2(\\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_i), \\bar{\\pi}(\\bar{\\phi}(s_i))), \\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_j), \\bar{\\pi}(\\bar{\\phi}(s_j)))) \\Big)^2\n$$\nwhere $\\bar{\\phi}(s)$ denotes $\\phi(s)$ with stop gradient and $\\bar{\\pi}$ is the mean policy output. The learned reward model $\\hat{\\mathcal{R}}$ is deterministic and the learned forward dynamics model $\\hat{\\mathcal{P}}$ outputs a Gaussian distribution.\nDBC is based on SAC but operates on the latent space:\nThe algorithm of Deep Bisimulation for Control. (Image source:\nZhang et al. 2020\n)\nCited as:\n@article{weng2019selfsup,\n  title   = \"Self-Supervised Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-11-10-self-supervised/\"\n}\nReferences\n#\n[1] Alexey Dosovitskiy, et al.\n“Discriminative unsupervised feature learning with exemplar convolutional neural networks.”\nIEEE transactions on pattern analysis and machine intelligence 38.9 (2015): 1734-1747.\n[2] Spyros Gidaris, Praveer Singh & Nikos Komodakis.\n“Unsupervised Representation Learning by Predicting Image Rotations”\nICLR 2018.\n[3] Carl Doersch, Abhinav Gupta, and Alexei A. Efros.\n“Unsupervised visual representation learning by context prediction.”\nICCV. 2015.\n[4] Mehdi Noroozi & Paolo Favaro.\n“Unsupervised learning of visual representations by solving jigsaw puzzles.”\nECCV, 2016.\n[5] Mehdi Noroozi, Hamed Pirsiavash, and Paolo Favaro.\n“Representation learning by learning to count.”\nICCV. 2017.\n[6] Richard Zhang, Phillip Isola & Alexei A. Efros.\n“Colorful image colorization.”\nECCV, 2016.\n[7] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[8] Jeff Donahue, Philipp Krähenbühl, and Trevor Darrell.\n“Adversarial feature learning.”\nICLR 2017.\n[9] Deepak Pathak, et al.\n“Context encoders: Feature learning by inpainting.”\nCVPR. 2016.\n[10] Richard Zhang, Phillip Isola, and Alexei A. Efros.\n“Split-brain autoencoders: Unsupervised learning by cross-channel prediction.”\nCVPR. 2017.\n[11] Xiaolong Wang & Abhinav Gupta.\n“Unsupervised Learning of Visual Representations using Videos.”\nICCV. 2015.\n[12] Carl Vondrick, et al.\n“Tracking Emerges by Colorizing Videos”\nECCV. 2018.\n[13] Ishan Misra, C. Lawrence Zitnick, and Martial Hebert.\n“Shuffle and learn: unsupervised learning using temporal order verification.”\nECCV. 2016.\n[14] Basura Fernando, et al.\n“Self-Supervised Video Representation Learning With Odd-One-Out Networks”\nCVPR. 2017.\n[15] Donglai Wei, et al.\n“Learning and Using the Arrow of Time”\nCVPR. 2018.\n[16] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering”\nCVPR. 2015.\n[17] Pierre Sermanet, et al.\n“Time-Contrastive Networks: Self-Supervised Learning from Video”\nCVPR. 2018.\n[18] Debidatta Dwibedi, et al.\n“Learning actionable representations from visual observations.”\nIROS. 2018.\n[19] Eric Jang & Coline Devin, et al.\n“Grasp2Vec: Learning Object Representations from Self-Supervised Grasping”\nCoRL. 2018.\n[20] Ashvin Nair, et al.\n“Visual reinforcement learning with imagined goals”\nNeuriPS. 2018.\n[21] Ashvin Nair, et al.\n“Contextual imagined goals for self-supervised robotic learning”\nCoRL. 2019.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748, 2018.\n[23] Olivier J. Henaff, et al.\n“Data-Efficient Image Recognition with Contrastive Predictive Coding”\narXiv preprint arXiv:1905.09272, 2019.\n[24] Kaiming He, et al.\n“Momentum Contrast for Unsupervised Visual Representation Learning.”\nCVPR 2020.\n[25] Zhirong Wu, et al.\n“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”\nCVPR 2018.\n[26] Ting Chen, et al.\n“A Simple Framework for Contrastive Learning of Visual Representations.”\narXiv preprint arXiv:2002.05709, 2020.\n[27] Aravind Srinivas, Michael Laskin & Pieter Abbeel\n“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”\narXiv preprint arXiv:2004.04136, 2020.\n[28] Carles Gelada, et al.\n“DeepMDP: Learning Continuous Latent Space Models for Representation Learning”\nICML 2019.\n[29] Amy Zhang, et al.\n“Learning Invariant Representations for Reinforcement Learning without Reconstruction”\narXiv preprint arXiv:2006.10742, 2020.\n[30] Xinlei Chen, et al.\n“Improved Baselines with Momentum Contrastive Learning”\narXiv preprint arXiv:2003.04297, 2020.\n[31] Jean-Bastien Grill, et al.\n“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”\narXiv preprint arXiv:2006.07733, 2020.\n[32] Abe Fetterman & Josh Albrecht.\n“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”\nUntitled blog. Aug 24, 2020.",
            "metadata": {
              "title": "Self-Supervised Representation Learning | Lil'Log",
              "description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "keywords": "representation-learning, long-read, generative-model, object-recognition, reinforcement-learning, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Self-Supervised Representation Learning",
              "og:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
              "og:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:card": "summary_large_image",
              "twitter:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:title": "Self-Supervised Representation Learning",
              "twitter:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "article:section": "posts",
              "article:published_time": "2019-11-10T00:00:00+00:00",
              "article:modified_time": "2019-11-10T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bf0a610ccb4a/code/body-000.txt",
                "chars": 244,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "bytes": 513885,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f359d38ab20e9cdac179.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "bytes": 1270278,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-8d6f8ad7272758de8c53.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "bytes": 768852,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7c81aafa4666fddd3762.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "bytes": 2642257,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c64df87fedc22e7713a8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "bytes": 249192,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-d72676a1e2d7d681665b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "bytes": 737673,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-284f09a3dc26a2be2be6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "bytes": 1162740,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-574c20fa1107bf61368d.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "bytes": 566411,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-817ed503b242a7831692.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "bytes": 103291,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-26dfcda8fac62755a0e6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "bytes": 225014,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-a7ef42a592f8d64c0933.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "bytes": 267029,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-38455ea040ea0eae9625.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "bytes": 163908,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-2f0fc009f289b69c8d79.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "bytes": 1281590,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e3a5248959b284127268.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "bytes": 1411892,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-316474d8ca427819890a.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "bytes": 218384,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7dd458cefc09c96c4325.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "bytes": 135102,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-70000ddd170ac7e5840b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "bytes": 2011971,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ae4b346db197ccab2cfe.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "bytes": 157839,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-1da73a82998c80ae17c9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "bytes": 1115258,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-976ef652676b26b5a203.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "bytes": 1886891,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f8bf05d0018c01caf352.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "bytes": 2352713,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-dee16f2c447f7c91e79e.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "bytes": 917157,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7de401f88063093a58d8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "bytes": 391776,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ce13a8280e64dce3dbf1.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "bytes": 1753636,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c37fd073afd7cb9698fa.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "bytes": 1839222,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e113f6beb0962c59d170.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "bytes": 164404,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c9ea48204e2765c959ab.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "bytes": 388169,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-139471e0d9b6eef5fde9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "bytes": 350225,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-211c4ab593d56ae944a3.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "src": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "status": "no_1080_or_720",
                "kind": "single_video",
                "error": "ERROR: [youtube] 7I0Qt7GALVk: Requested format is not available. Use --list-formats for a list of available formats\n",
                "title": "",
                "retried_at": "2026-10-20T17:59:07Z"
              }
            ],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "MoCo V2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "label": "LeCun’s talk",
                "type": "a"
              },
              {
                "href": "https://github.com/jason718/awesome-self-supervised-learning",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/tags/generative-model/",
                "label": "generative modeling",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.03670",
                "label": "Zhai et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11825",
                "label": "Sun et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1406.6909",
                "label": "Dosovitskiy et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.07728",
                "label": "Gidaris et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05192",
                "label": "Doersch et al. (2015)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Chromatic_aberration",
                "label": "“chromatic aberration”",
                "type": "a"
              },
              {
                "href": "https://upload.wikimedia.org/wikipedia/commons/a/aa/Chromatic_aberration_lens_diagram.svg",
                "label": "wikipedia",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09246",
                "label": "Noroozi & Favaro (2016)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00025",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.06734",
                "label": "Noroozi, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08511",
                "label": "Zhang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CIELAB_color_space",
                "label": "CIE L a b* color space",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "tf and idf",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "Vincent, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "old post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.07379",
                "label": "Pathak, et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.09842",
                "label": "Zhang et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "Radford et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.09782",
                "label": "Donahue, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Noise Contrastive Estimation (NCE)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.09272",
                "label": "Henaff, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.00687",
                "label": "Wang & Gupta, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "triplet loss",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6200-improved-deep-metric-learning-with-multi-class-n-pair-loss-objective",
                "label": "n-pair loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Optical_flow",
                "label": "optical flow",
                "type": "a"
              },
              {
                "href": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "label": "SURF",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/hal-00873267v2/document",
                "label": "IDT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08561",
                "label": "Misra, et al 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.06646",
                "label": "Fernando et al. 2017",
                "type": "a"
              },
              {
                "href": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "label": "Wei et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09594",
                "label": "Vondrick et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "matching network",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "pointer network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06964",
                "label": "Jang & Devin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://developers.google.com/machine-learning/crash-course/embeddings/translating-to-a-lower-dimensional-space",
                "label": "e.g.",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "label": "Andrychowicz, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.06888",
                "label": "Sermanet, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00928",
                "label": "Dwibedi et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.04742",
                "label": "Nair et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.11670",
                "label": "Nair, et al., 2019",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5775-learning-structured-output-representation-using-deep-conditional-generative-models",
                "label": "Sohn, Lee & Yan, 2015",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.61.2493&rep=rep1&type=pdf",
                "label": "Givan et al. 2003",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "MDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.02736",
                "label": "Gelada, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coupling_(probability)",
                "label": "couplings",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_embedding_of_distributions",
                "label": "MMD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10742",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1207.4114",
                "label": "Ferns, et al. 2004",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.295.2114&rep=rep1&type=pdf",
                "label": "Ferns, et al 2011",
                "type": "a"
              },
              {
                "href": "https://mathworld.wolfram.com/Pseudometric.html",
                "label": "pseudometric",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1806.09594.pdf",
                "label": "“Tracking Emerges by Colorizing Videos”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "“Momentum Contrast for Unsupervised Visual Representation Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "“A Simple Framework for Contrastive Learning of Visual Representations.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "“Improved Baselines with Momentum Contrastive Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:35Z",
            "source_url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.03670",
                "bytes": 933247,
                "reused": false,
                "local_path": "papers/repair/687ecfe304e8db4ee6a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11825",
                "bytes": 1510344,
                "reused": false,
                "local_path": "papers/repair/abe216f7fcd57c5bf090.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.6909",
                "bytes": 1208023,
                "reused": false,
                "local_path": "papers/repair/02461cd2b74a44803bcb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.07728",
                "bytes": 2524968,
                "reused": false,
                "local_path": "papers/repair/09768e0dd5ddaf3f5115.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05192",
                "bytes": 3688221,
                "reused": false,
                "local_path": "papers/repair/8660d67d6d9beb2f409e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09246",
                "bytes": 7884325,
                "reused": false,
                "local_path": "papers/repair/3fad0ba70064de418e86.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00025",
                "bytes": 915177,
                "reused": false,
                "local_path": "papers/repair/e965789a54661a85f29b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.06734",
                "bytes": 4282240,
                "reused": false,
                "local_path": "papers/repair/9041a39543be512b895f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08511",
                "bytes": 8866382,
                "reused": false,
                "local_path": "papers/repair/adde21ae45e292b51011.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": false,
                "local_path": "papers/repair/afb5d72ab0895a64362a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.07379",
                "bytes": 9914955,
                "reused": false,
                "local_path": "papers/repair/24d4451e560641d4763c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.09842",
                "bytes": 2531668,
                "reused": false,
                "local_path": "papers/repair/20050e06cbfd43bbb68b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": true,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.09782",
                "bytes": 5938452,
                "reused": false,
                "local_path": "papers/repair/407a2bae3cb6f778a5c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": true,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.09272",
                "bytes": 2411659,
                "reused": false,
                "local_path": "papers/repair/b9006248b176b4b194f1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.00687",
                "bytes": 3737012,
                "reused": false,
                "local_path": "papers/repair/3078161f1da978e0de72.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": true,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "bytes": 723370,
                "reused": false,
                "local_path": "papers/repair/780b0a793aeb990a3f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08561",
                "bytes": 2615687,
                "reused": false,
                "local_path": "papers/repair/1d251b8fc37ee017f4bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.06646",
                "bytes": 7497944,
                "reused": false,
                "local_path": "papers/repair/739b5e4d4e24134d409b.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "bytes": 1011708,
                "reused": false,
                "local_path": "papers/repair/afdd1eb32a82a2145ccc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/643dffc114da13aa653b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06964",
                "bytes": 6707774,
                "reused": false,
                "local_path": "papers/repair/fa128df9eb0f1f235ebb.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "bytes": 2040774,
                "reused": false,
                "local_path": "papers/repair/d153f5fcbc7ada7f48f2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.06888",
                "bytes": 9504974,
                "reused": false,
                "local_path": "papers/repair/2b339f780c6bfb664948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00928",
                "bytes": 1382430,
                "reused": false,
                "local_path": "papers/repair/a8b22a546f22c92d1a5c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.04742",
                "bytes": 9328088,
                "reused": false,
                "local_path": "papers/repair/509c62da689529aeb058.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.11670",
                "bytes": 2075834,
                "reused": false,
                "local_path": "papers/repair/909f08f6590adde49f8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.02736",
                "bytes": 8541253,
                "reused": false,
                "local_path": "papers/repair/04f92d456ed7ee16b0e3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10742",
                "bytes": 5605228,
                "reused": false,
                "local_path": "papers/repair/1f176920cb7853662844.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1207.4114",
                "bytes": 386038,
                "reused": false,
                "local_path": "papers/repair/b3516a025350622055b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594.pdf",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/591acb652d41fe6382d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": true,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": true,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": true,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": true,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": true,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": true,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53089,
            "expected_body_images": 28,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "no_1080_or_720",
            "raw_html": "attachments/bf0a610ccb4a/pages/source.html",
            "local_html": "attachments/bf0a610ccb4a/pages/article.html",
            "body_base_path": "attachments/bf0a610ccb4a/pages/",
            "body_markdown_path": "attachments/bf0a610ccb4a/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
          "status": "ok",
          "article_id": "c8f3f2a59bb8",
          "local_path": "series-follow/1600/repair/0322612d07df5f51284a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
              "bytes": 82669,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c8feb8e3831d6f407222.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
              "bytes": 238558,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/864616500d13b290a57d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
              "bytes": 618000,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4d1eafbd2698e4b13414.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
              "bytes": 447800,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2202dbf059680ff25f64.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
              "bytes": 331316,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/56fdc531021fd8fc266d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
              "bytes": 92328,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a3de29261702db65276c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
              "bytes": 292083,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9fbb7be242e78cf4064e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
              "bytes": 165448,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7c6e570b2b4acaea53ee.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
              "bytes": 410905,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0dc7fb2e267a076918a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
              "bytes": 160971,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/64c06b583b29bc8d849d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
              "bytes": 575598,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/24abca83dac665bdfd2c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
              "bytes": 191327,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/68a57a589ced1a8dcbeb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
              "bytes": 458778,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dec760a7d6d875b1e5f6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
              "bytes": 413067,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3b05f2c9b09900dd678c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
              "bytes": 307781,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9fe78703c0d6dd59901b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
              "bytes": 395407,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/bcffab9e56e403b12eb6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
              "bytes": 378369,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/14fc3bb2a028bd633430.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
              "bytes": 269518,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1cdb06387d4aabe19e7f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
              "bytes": 1172082,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dc3294612801cee60ee0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
              "bytes": 299081,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4ecf4ae1a9c6c75e0b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
              "bytes": 102477,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2f938fd27f3112a7668b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
              "bytes": 302804,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/476b14449fa38214486c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
              "bytes": 459618,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d417f179aa932198443f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
              "bytes": 248555,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/61290a159906f77df170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
              "bytes": 263986,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/25636cdf26fe48bc32a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
              "bytes": 127994,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1f6149bb39a134da1e75.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
              "bytes": 167429,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/75a0434d42ea9e13e5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
              "bytes": 235880,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0873d959165b59705852.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
              "bytes": 403903,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7fc9d0b8fcf86efd800b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
              "bytes": 237372,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4a85aecfe0dc34b27289.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Contrastive Representation Learning",
            "keywords": "对比学习,表示学习,自监督",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "publish_date": "2021-05",
            "corpus_stage": "预训练/SFT",
            "notes": "对比表示学习综述（SimCLR、MoCo等）",
            "id": "c8f3f2a59bb8",
            "collected_at": "2026-10-02T14:12:57",
            "title": "Contrastive Representation Learning | Lil'Log",
            "body_markdown": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in\nself-supervised learning\n.\nContrastive Training Objectives\n#\nIn early versions of loss functions for contrastive learning, only one positive and one negative sample are involved. The trend in recent training objectives is to include multiple positive and negative pairs in one batch.\nContrastive Loss\n#\nContrastive loss\n(\nChopra et al. 2005\n) is one of the earliest training objectives used for deep metric learning in a contrastive fashion.\nGiven a list of input samples $\\{ \\mathbf{x}_i \\}$, each has a corresponding label $y_i \\in \\{1, \\dots, L\\}$ among $L$ classes. We would like to learn a function $f_\\theta(.): \\mathcal{X}\\to\\mathbb{R}^d$ that encodes $x_i$ into an embedding vector such that examples from the same class have similar embeddings and samples from different classes have very different ones. Thus, contrastive loss takes a pair of inputs $(x_i, x_j)$ and minimizes the embedding distance when they are from the same class but maximizes the distance otherwise.\n$$\n\\mathcal{L}_\\text{cont}(\\mathbf{x}_i, \\mathbf{x}_j, \\theta) = \\mathbb{1}[y_i=y_j] \\| f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\|^2_2 + \\mathbb{1}[y_i\\neq y_j]\\max(0, \\epsilon - \\|f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j)\\|_2)^2\n$$\nwhere $\\epsilon$ is a hyperparameter, defining the lower bound distance between samples of different classes.\nTriplet Loss\n#\nTriplet loss\nwas originally proposed in the FaceNet (\nSchroff et al. 2015\n) paper and was used to learn face recognition of the same person at different poses and angles.\nIllustration of triplet loss given one positive and one negative per anchor. (Image source:\nSchroff et al. 2015\n)\nGiven one anchor input $\\mathbf{x}$, we select one positive sample $\\mathbf{x}^+$ and one negative $\\mathbf{x}^-$, meaning that $\\mathbf{x}^+$ and $\\mathbf{x}$ belong to the same class and $\\mathbf{x}^-$ is sampled from another different class. Triplet loss learns to minimize the distance between the anchor $\\mathbf{x}$ and positive $\\mathbf{x}^+$ and maximize the distance between the anchor $\\mathbf{x}$ and negative $\\mathbf{x}^-$ at the same time with the following equation:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) = \\sum_{\\mathbf{x} \\in \\mathcal{X}} \\max\\big( 0, \\|f(\\mathbf{x}) - f(\\mathbf{x}^+)\\|^2_2 - \\|f(\\mathbf{x}) - f(\\mathbf{x}^-)\\|^2_2 + \\epsilon \\big)\n$$\nwhere the margin parameter $\\epsilon$ is configured as the minimum offset between distances of similar vs dissimilar pairs.\nIt is crucial to select challenging $\\mathbf{x}^-$ to truly improve the model.\nLifted Structured Loss\n#\nLifted Structured Loss\n(\nSong et al. 2015\n) utilizes all the pairwise edges within one training batch for better computational efficiency.\nIllustration compares contrastive loss, triplet loss and lifted structured loss. Red and blue edges connect similar and dissimilar sample pairs respectively. (Image source:\nSong et al. 2015\n)\nLet $D_{ij} = | f(\\mathbf{x}_i) - f(\\mathbf{x}_j) |_2$, a structured loss function is defined as\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{struct} &= \\frac{1}{2\\vert \\mathcal{P} \\vert} \\sum_{(i,j) \\in \\mathcal{P}} \\max(0, \\mathcal{L}_\\text{struct}^{(ij)})^2 \\\\\n\\text{where } \\mathcal{L}_\\text{struct}^{(ij)} &= D_{ij} + \\color{red}{\\max \\big( \\max_{(i,k)\\in \\mathcal{N}} \\epsilon - D_{ik}, \\max_{(j,l)\\in \\mathcal{N}} \\epsilon - D_{jl} \\big)}\n\\end{aligned}\n$$\nwhere $\\mathcal{P}$ contains the set of positive pairs and $\\mathcal{N}$ is the set of negative pairs. Note that the dense pairwise squared distance matrix can be easily computed per training batch.\nThe\nred\npart in $\\mathcal{L}_\\text{struct}^{(ij)}$ is used for mining hard negatives. However, it is not smooth and may cause the convergence to a bad local optimum in practice. Thus, it is relaxed to be:\n$$\n\\mathcal{L}_\\text{struct}^{(ij)} = D_{ij} + \\log \\Big( \\sum_{(i,k)\\in\\mathcal{N}} \\exp(\\epsilon - D_{ik}) + \\sum_{(j,l)\\in\\mathcal{N}} \\exp(\\epsilon - D_{jl}) \\Big)\n$$\nIn the paper, they also proposed to enhance the quality of negative samples in each batch by actively incorporating difficult negative samples given a few random positive pairs.\nN-pair Loss\n#\nMulti-Class N-pair loss\n(\nSohn 2016\n) generalizes triplet loss to include comparison with multiple negative samples.\nGiven a $(N + 1)$-tuplet of training samples, $\\{ \\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-_1, \\dots, \\mathbf{x}^-_{N-1} \\}$, including one positive and $N-1$ negative ones, N-pair loss is defined as:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{N-pair}(\\mathbf{x}, \\mathbf{x}^+, \\{\\mathbf{x}^-_i\\}^{N-1}_{i=1}) \n&= \\log\\big(1 + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i) - f(\\mathbf{x})^\\top f(\\mathbf{x}^+))\\big) \\\\\n&= -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+))}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)) + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i))}\n\\end{aligned}\n$$\nIf we only sample one negative sample per class, it is equivalent to the softmax loss for multi-class classification.\nNCE\n#\nNoise Contrastive Estimation\n, short for\nNCE\n, is a method for estimating parameters of a statistical model, proposed by\nGutmann & Hyvarinen\nin 2010. The idea is to run logistic regression to tell apart the target data from noise. Read more on how NCE is used for learning word embedding\nhere\n.\nLet $\\mathbf{x}$ be the target sample $\\sim P(\\mathbf{x} \\vert C=1; \\theta) = p_\\theta(\\mathbf{x})$ and $\\tilde{\\mathbf{x}}$ be the noise sample $\\sim  P(\\tilde{\\mathbf{x}} \\vert C=0) = q(\\tilde{\\mathbf{x}})$. Note that the logistic regression models the logit (i.e. log-odds) and in this case we would like to model the logit of a sample $u$ from the target data distribution instead of the noise distribution:\n$$\n\\ell_\\theta(\\mathbf{u}) = \\log \\frac{p_\\theta(\\mathbf{u})}{q(\\mathbf{u})} = \\log p_\\theta(\\mathbf{u}) - \\log q(\\mathbf{u})\n$$\nAfter converting logits into probabilities with sigmoid $\\sigma(.)$, we can apply cross entropy loss:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{NCE} &= - \\frac{1}{N} \\sum_{i=1}^N \\big[ \\log \\sigma (\\ell_\\theta(\\mathbf{x}_i)) + \\log (1 - \\sigma (\\ell_\\theta(\\tilde{\\mathbf{x}}_i))) \\big] \\\\\n\\text{ where }\\sigma(\\ell) &= \\frac{1}{1 + \\exp(-\\ell)} = \\frac{p_\\theta}{p_\\theta + q}\n\\end{aligned}\n$$\nHere I listed the original form of NCE loss which works with only one positive and one noise sample. In many follow-up works, contrastive loss incorporating multiple negative samples is also broadly referred to as NCE.\nInfoNCE\n#\nThe\nInfoNCE loss\nin CPC (\nContrastive Predictive Coding\n;\nvan den Oord, et al. 2018\n), inspired by\nNCE\n, uses categorical cross-entropy loss to identify the positive sample amongst a set of unrelated noise samples.\nGiven a context vector $\\mathbf{c}$, the positive sample should be drawn from the conditional distribution $p(\\mathbf{x} \\vert \\mathbf{c})$, while $N-1$ negative samples are drawn from the proposal distribution $p(\\mathbf{x})$, independent from the context $\\mathbf{c}$. For brevity, let us label all the samples as $X=\\{ \\mathbf{x}_i \\}^N_{i=1}$ among which only one of them $\\mathbf{x}_\\texttt{pos}$ is a positive sample. The probability of we detecting the positive sample correctly is:\n$$\np(C=\\texttt{pos} \\vert X, \\mathbf{c}) \n= \\frac{p(x_\\texttt{pos} \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq \\texttt{pos}} p(\\mathbf{x}_i)}{\\sum_{j=1}^N \\big[ p(\\mathbf{x}_j \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq j} p(\\mathbf{x}_i) \\big]}\n= \\frac{ \\frac{p(\\mathbf{x}_\\texttt{pos}\\vert c)}{p(\\mathbf{x}_\\texttt{pos})} }{ \\sum_{j=1}^N \\frac{p(\\mathbf{x}_j\\vert \\mathbf{c})}{p(\\mathbf{x}_j)} }\n= \\frac{f(\\mathbf{x}_\\texttt{pos}, \\mathbf{c})}{ \\sum_{j=1}^N f(\\mathbf{x}_j, \\mathbf{c}) }\n$$\nwhere the scoring function is $f(\\mathbf{x}, \\mathbf{c}) \\propto \\frac{p(\\mathbf{x}\\vert\\mathbf{c})}{p(\\mathbf{x})}$.\nThe InfoNCE loss optimizes the negative log probability of classifying the positive sample correctly:\n$$\n\\mathcal{L}_\\text{InfoNCE} = - \\mathbb{E} \\Big[\\log \\frac{f(\\mathbf{x}, \\mathbf{c})}{\\sum_{\\mathbf{x}' \\in X} f(\\mathbf{x}', \\mathbf{c})} \\Big]\n$$\nThe fact that $f(x, c)$ estimates the density ratio $\\frac{p(x\\vert c)}{p(x)}$ has a connection with mutual information optimization. To maximize the the mutual information between input $x$ and context vector $c$, we have:\n$$\nI(\\mathbf{x}; \\mathbf{c}) = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c}) \\log\\frac{p(\\mathbf{x}, \\mathbf{c})}{p(\\mathbf{x})p(\\mathbf{c})} = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c})\\log\\color{blue}{\\frac{p(\\mathbf{x}|\\mathbf{c})}{p(\\mathbf{x})}}\n$$\nwhere the logarithmic term in\nblue\nis estimated by $f$.\nFor sequence prediction tasks, rather than modeling the future observations $p_k(\\mathbf{x}_{t+k} \\vert \\mathbf{c}_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $\\mathbf{x}_{t+k}$ and $\\mathbf{c}_t$:\n$$\nf_k(\\mathbf{x}_{t+k}, \\mathbf{c}_t) = \\exp(\\mathbf{z}_{t+k}^\\top \\mathbf{W}_k \\mathbf{c}_t) \\propto \\frac{p(\\mathbf{x}_{t+k}\\vert\\mathbf{c}_t)}{p(\\mathbf{x}_{t+k})}\n$$\nwhere $\\mathbf{z}_{t+k}$ is the encoded input and $\\mathbf{W}_k$ is a trainable weight matrix.\nSoft-Nearest Neighbors Loss\n#\nSoft-Nearest Neighbors Loss\n(\nSalakhutdinov & Hinton 2007\n,\nFrosst et al. 2019\n) extends it to include multiple positive samples.\nGiven a batch of samples, $\\{\\mathbf{x}_i, y_i)\\}^B_{i=1}$ where $y_i$ is the class label of $\\mathbf{x}_i$ and a function $f(.,.)$ for measuring similarity between two inputs, the soft nearest neighbor loss at temperature $\\tau$ is defined as:\n$$\n\\mathcal{L}_\\text{snn} = -\\frac{1}{B}\\sum_{i=1}^B \\log \\frac{\\sum_{i\\neq j, y_i = y_j, j=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_j) / \\tau)}{\\sum_{i\\neq k, k=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_k) /\\tau)}\n$$\nThe temperature $\\tau$ is used for tuning how concentrated the features are in the representation space. For example, when at low temperature, the loss is dominated by the small distances and widely separated representations cannot contribute much and become irrelevant.\nCommon Setup\n#\nWe can loosen the definition of “classes” and “labels” in soft nearest-neighbor loss to create positive and negative sample pairs out of unsupervised data by, for example, applying data augmentation to create noise versions of original samples.\nMost recent studies follow the following definition of contrastive learning objective to incorporate multiple positive and negative samples. According to the setup in (\nWang & Isola 2020\n), let $p_\\texttt{data}(.)$ be the data distribution over $\\mathbb{R}^n$ and $p_\\texttt{pos}(., .)$ be the distribution of positive pairs over $\\mathbb{R}^{n \\times n}$. These two distributions should satisfy:\nSymmetry: $\\forall \\mathbf{x}, \\mathbf{x}^+, p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) = p_\\texttt{pos}(\\mathbf{x}^+, \\mathbf{x})$\nMatching marginal: $\\forall \\mathbf{x}, \\int p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) d\\mathbf{x}^+ = p_\\texttt{data}(\\mathbf{x})$\nTo learn an encoder $f(\\mathbf{x})$ to learn a\nL2-normalized feature vector\n, the contrastive learning objective is:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{contrastive} \n&= \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} } \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau)}{ \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau) + \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)} \\Big] & \\\\\n&\\approx \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} }\\Big[ - f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau + \\log\\big(\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big) \\Big] & \\scriptstyle{\\text{; Assuming infinite negatives}} \\\\\n&= -\\frac{1}{\\tau}\\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}}f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + \\mathbb{E}_{ \\mathbf{x} \\sim p_\\texttt{data}} \\Big[ \\log \\mathbb{E}_{\\mathbf{x}^- \\sim p_\\texttt{data}} \\big[ \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big] \\Big] &\n\\end{aligned}\n$$\nKey Ingredients\n#\nHeavy Data Augmentation\n#\nGiven a training sample, data augmentation techniques are needed for creating noise versions of itself to feed into the loss as positive samples. Proper data augmentation setup is critical for learning good and generalizable embedding features. It introduces the non-essential variations into examples without modifying semantic meanings and thus encourages the model to learn the essential part of the representation. For example, experiments in\nSimCLR\nshowed that the composition of random cropping and random color distortion is crucial for good performance on learning visual representation of images.\nLarge Batch Size\n#\nUsing a large batch size during training is another key ingredient in the success of many contrastive learning methods (e.g.\nSimCLR\n,\nCLIP\n), especially when it relies on in-batch negatives. Only when the batch size is big enough, the loss function can cover a diverse enough collection of negative samples, challenging enough for the model to learn meaningful representation to distinguish different examples.\nHard Negative Mining\n#\nHard negative samples should have different labels from the anchor sample, but have embedding features very close to the anchor embedding. With access to ground truth labels in supervised datasets, it is easy to identify task-specific hard negatives. For example when learning sentence embedding, we can treat sentence pairs labelled as “contradiction” in NLI datasets as hard negative pairs (e.g.\nSimCSE\n, or use top incorrect candidates returned by BM25 with most keywords matched as hard negative samples (\nDPR\n;\nKarpukhin et al., 2020\n).\nHowever, it becomes tricky to do hard negative mining when we want to remain unsupervised. Increasing training batch size or\nmemory bank\nsize implicitly introduces more hard negative samples, but it leads to a heavy burden of large memory usage as a side effect.\nChuang et al. (2020)\nstudied the sampling bias in contrastive learning and proposed debiased loss. In the unsupervised setting, since we do not know the ground truth labels, we may accidentally sample false negative samples. Sampling bias can lead to significant performance drop.\nSampling bias which refers to false negative samples in contrastive learning can lead to a big performance drop. (Image source:\nChuang et al., 2020\n)\nLet us assume the probability of anchor class $c$ is uniform $\\rho(c)=\\eta^+$ and the probability of observing a different class is $\\eta^- = 1-\\eta^+$.\nThe probability of observing a positive example for $\\mathbf{x}$ is $p^+_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}=\\mathbf{h}_x)$;\nThe probability of getting a negative sample for $\\mathbf{x}$ is $p^-_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}\\neq\\mathbf{h}_x)$.\nWhen we are sampling $\\mathbf{x}^-$ , we cannot access the true $p^-_x(\\mathbf{x}^-)$ and thus $\\mathbf{x}^-$ may be sampled from the (undesired) anchor class $c$ with probability $\\eta^+$. The actual sampling data distribution becomes:\n$$\np(\\mathbf{x}') = \\eta^+ p^+_x(\\mathbf{x}') + \\eta^- p_x^-(\\mathbf{x}')\n$$\nThus we can use $p^-_x(\\mathbf{x}’) = (p(\\mathbf{x}’) - \\eta^+ p^+_x(\\mathbf{x}’))/\\eta^-$ for sampling $\\mathbf{x}^-$ to debias the loss. With $N$ samples $\\{\\mathbf{u}_i\\}^N_{i=1}$ from $p$ and $M$ samples $\\{ \\mathbf{v}_i \\}_{i=1}^M$ from $p^+_x$ , we can estimate the expectation of the second term $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ in the denominator of contrastive learning loss:\n$$\ng(\\mathbf{x}, \\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M) = \\max\\Big\\{ \\frac{1}{\\eta^-}\\Big( \\frac{1}{N}\\sum_{i=1}^N \\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}_i)) - \\frac{\\eta^+}{M}\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}_i)) \\Big), \\exp(-1/\\tau) \\Big\\}\n$$\nwhere $\\tau$ is the temperature and $\\exp(-1/\\tau)$ is the theoretical lower bound of $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$.\nThe final debiased contrastive loss looks like:\n$$\n\\mathcal{L}^{N,M}_\\text{debias}(f) = \\mathbb{E}_{\\mathbf{x},\\{\\mathbf{u}_i\\}^N_{i=1}\\sim p;\\;\\mathbf{x}^+, \\{\\mathbf{v}_i\\}_{i=1}^M\\sim p^+} \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + N g(x,\\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M)} \\Big]\n$$\nt-SNE visualization of learned representation with debiased contrastive learning. (Image source:\nChuang et al., 2020\n)\nFollowing the above annotation,\nRobinson et al. (2021)\nmodified the sampling probabilities to target at hard negatives by up-weighting the probability $p^-_x(x’)$ to be proportional to its similarity to the anchor sample. The new sampling probability $q_\\beta(x^-)$ is:\n$$\nq_\\beta(\\mathbf{x}^-) \\propto \\exp(\\beta f(\\mathbf{x})^\\top f(\\mathbf{x}^-)) \\cdot p(\\mathbf{x}^-)\n$$\nwhere $\\beta$ is a hyperparameter to tune.\nWe can estimate the second term in the denominator $\\mathbb{E}_{\\mathbf{x}^- \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ using importance sampling where both the partition functions $Z_\\beta, Z^+_\\beta$ can be estimated empirically.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\mathbf{u} \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] &= \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{q_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] = \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{1}{Z_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{u}))] \\\\\n\\mathbb{E}_{\\mathbf{v} \\sim q^+_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] &= \\mathbb{E}_{\\mathbf{v} \\sim p^+} [\\frac{q^+_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] = \\mathbb{E}_{\\mathbf{v} \\sim p} [\\frac{1}{Z^+_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{v}))]\n\\end{aligned}\n$$\nPseudo code for computing NCE loss, debiased contrastive loss, and hard negative sample objective when setting $M=1$. (Image source:\nRobinson et al., 2021\n)\nVision: Image Embedding\n#\nImage Augmentations\n#\nMost approaches for contrastive representation learning in the vision domain rely on creating a noise version of a sample by applying a sequence of data augmentation techniques. The augmentation should significantly change its visual appearance but keep the semantic meaning unchanged.\nBasic Image Augmentation\n#\nThere are many ways to modify an image while retaining its semantic meaning. We can use any one of the following augmentation or a composition of multiple operations.\nRandom cropping and then resize back to the original size.\nRandom color distortions\nRandom Gaussian blur\nRandom color jittering\nRandom horizontal flip\nRandom grayscale conversion\nMulti-crop augmentation: Use two standard resolution crops and sample a set of additional low resolution crops that cover only small parts of the image. Using low resolution crops reduces the compute cost. (\nSwAV\n)\nAnd many more …\nAugmentation Strategies\n#\nMany frameworks are designed for learning good data augmentation strategies (i.e. a composition of multiple transforms). Here are a few common ones.\nAutoAugment\n(\nCubuk, et al. 2018\n): Inspired by\nNAS\n, AutoAugment frames the problem of learning best data augmentation operations (i.e. shearing, rotation, invert, etc.) for image classification as an RL problem and looks for the combination that leads to the highest accuracy on the evaluation set.\nRandAugment (\nCubuk et al., 2019\n): RandAugment greatly reduces the search space of AutoAugment by controlling the magnitudes of different transformation operations with a single magnitude parameter.\nPBA (Population based augmentation;\nHo et al., 2019\n): PBA combined PBT (\nJaderberg et al, 2017\n) with AutoAugment, using the evolutionary algorithm to train a population of children models in parallel to evolve the best augmentation strategies.\nUDA (Unsupervised Data Augmentation;\nXie et al., 2019\n): Among a set of possible augmentation strategies, UDA selects those to minimize the KL divergence between the predicted distribution over an unlabelled example and its unlabelled augmented version.\nImage Mixture\n#\nImage mixture methods can construct new training examples from existing data points.\nMixup (\nZhang et al., 2018\n): It runs global-level mixture by creating a weighted pixel-wise combination of two existing images $I_1$ and $I_2$: $I_\\text{mixup} \\gets \\alpha I_1 + (1-\\alpha) I_2$ and $\\alpha \\in [0, 1]$.\nCutmix (\nYun et al., 2019\n): Cutmix does region-level mixture by generating a new example by combining a local region of one image with the rest of the other image. $I_\\text{cutmix} \\gets \\mathbf{M}_b \\odot I_1 + (1-\\mathbf{M}_b) \\odot I_2$, where $\\mathbf{M}_b \\in \\{0, 1\\}^I$ is a binary mask and $\\odot$ is element-wise multiplication. It is equivalent to filling the cutout (\nDeVries & Taylor 2017\n) region with the same region from another image.\nMoCHi (“Mixing of Contrastive Hard Negatives”;\nKalantidis et al. 2020\n): Given a query $\\mathbf{q}$, MoCHi maintains a queue of $K$ negative features $Q=\\{\\mathbf{n}_1, \\dots, \\mathbf{n}_K \\}$ and sorts these negative features by similarity to the query, $\\mathbf{q}^\\top \\mathbf{n}$, in descending order. The first $N$ items in the queue are considered as the hardest negatives, $Q^N$. Then synthetic hard examples can be generated by $\\mathbf{h} = \\tilde{\\mathbf{h}} / |\\tilde{\\mathbf{h}}|$ where $\\tilde{\\mathbf{h}} = \\alpha\\mathbf{n}_i + (1-\\alpha) \\mathbf{n}_j$ and $\\alpha \\in (0, 1)$. Even harder examples can be created by mixing with the query feature, $\\mathbf{h}’ = \\tilde{\\mathbf{h}’} / |\\tilde{\\mathbf{h}’}|_2$ where $\\tilde{\\mathbf{h}’} = \\beta\\mathbf{q} + (1-\\beta) \\mathbf{n}_j$ and $\\beta \\in (0, 0.5)$.\nParallel Augmentation\n#\nThis category of approaches produce two noise versions of one anchor image and aim to learn representation such that these two augmented samples share the same embedding.\nSimCLR\n#\nSimCLR\n(\nChen et al, 2020\n) proposed a simple framework for contrastive learning of visual representations. It learns representations for visual inputs by maximizing agreement between differently augmented views of the same sample via a contrastive loss in the latent space.\nA simple framework for contrastive learning of visual representations. (Image source:\nChen et al, 2020\n)\nRandomly sample a minibatch of $N$ samples and each sample is applied with two different data augmentation operations, resulting in $2N$ augmented samples in total.\n$$\n\\tilde{\\mathbf{x}}_i = t(\\mathbf{x}),\\quad\\tilde{\\mathbf{x}}_j = t'(\\mathbf{x}),\\quad t, t' \\sim \\mathcal{T}\n$$\nwhere two separate data augmentation operators, $t$ and $t’$, are sampled from the same family of augmentations $\\mathcal{T}$. Data augmentation includes random crop, resize with random flip, color distortions, and Gaussian blur.\nGiven one positive pair, other $2(N-1)$ data points are treated as negative samples. The representation is produced by a base encoder $f(.)$:\n$$\n\\mathbf{h}_i = f(\\tilde{\\mathbf{x}}_i),\\quad \\mathbf{h}_j = f(\\tilde{\\mathbf{x}}_j)\n$$\nThe contrastive learning loss is defined using cosine similarity $\\text{sim}(.,.)$. Note that the loss operates on an extra projection layer of the representation $g(.)$ rather than on the representation space directly. But only the representation $\\mathbf{h}$ is used for downstream tasks.\n$$\n\\begin{aligned}\n\\mathbf{z}_i &= g(\\mathbf{h}_i),\\quad\n\\mathbf{z}_j = g(\\mathbf{h}_j) \\\\\n\\mathcal{L}_\\text{SimCLR}^{(i,j)} &= - \\log\\frac{\\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_j) / \\tau)}{\\sum_{k=1}^{2N} \\mathbb{1}_{[k \\neq i]} \\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_k) / \\tau)}\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{[k \\neq i]}$ is an indicator function: 1 if $k\\neq i$ 0 otherwise.\nSimCLR needs a large batch size to incorporate enough negative samples to achieve good performance.\nThe algorithm for SimCLR. (Image source:\nChen et al, 2020\n).\nBarlow Twins\n#\nBarlow Twins\n(\nZbontar et al. 2021\n) feeds two distorted versions of samples into the same network to extract features and learns to make the\ncross-correlation matrix\nbetween these two groups of output features close to the identity. The goal is to keep the representation vectors of different distorted versions of one sample similar, while minimizing the redundancy between these vectors.\nIllustration of Barlow Twins learning pipeline. (Image source:\nZbontar et al. 2021\n).\nLet $\\mathcal{C}$ be a cross-correlation matrix computed between outputs from two identical networks along the batch dimension. $\\mathcal{C}$ is a square matrix with the size same as the feature network’s output dimensionality. Each entry in the matrix $\\mathcal{C}_{ij}$ is the cosine similarity between network output vector dimension at index $i, j$ and batch index $b$, $\\mathbf{z}_{b,i}^A$ and $\\mathbf{z}_{b,j}^B$, with a value between -1 (i.e. perfect anti-correlation) and 1 (i.e. perfect correlation).\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{BT} &= \\underbrace{\\sum_i (1-\\mathcal{C}_{ii})^2}_\\text{invariance term} + \\lambda \\underbrace{\\sum_i\\sum_{i\\neq j} \\mathcal{C}_{ij}^2}_\\text{redundancy reduction term} \\\\ \\text{where } \\mathcal{C}_{ij} &= \\frac{\\sum_b \\mathbf{z}^A_{b,i} \\mathbf{z}^B_{b,j}}{\\sqrt{\\sum_b (\\mathbf{z}^A_{b,i})^2}\\sqrt{\\sum_b (\\mathbf{z}^B_{b,j})^2}}\n\\end{aligned}\n$$\nBarlow Twins is competitive with SOTA methods for self-supervised learning. It naturally avoids trivial constants (i.e. collapsed representations), and is robust to different training batch sizes.\nAlgorithm of Barlow Twins in Pytorch style pseudo code. (Image source:\nZbontar et al. 2021\n).\nBYOL\n#\nDifferent from the above approaches, interestingly,\nBYOL\n(Bootstrap Your Own Latent;\nGrill, et al 2020\n) claims to achieve a new state-of-the-art results\nwithout using negative samples\n. It relies on two neural networks, referred to as\nonline\nand\ntarget\nnetworks that interact and learn from each other. The target network (parameterized by $\\xi$) has the same architecture as the online one (parameterized by $\\theta$), but with polyak averaged weights, $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe goal is to learn a presentation $y$ that can be used in downstream tasks. The online network parameterized by $\\theta$ contains:\nAn encoder $f_\\theta$;\nA projector $g_\\theta$;\nA predictor $q_\\theta$.\nThe target network has the same network architecture, but with different parameter $\\xi$, updated by polyak averaging $\\theta$: $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe model architecture of BYOL. After training, we only care about $f\\_\\theta$ for producing representation, $y=f\\_\\theta(x)$, and everything else is discarded. $\\text{sg}$ means stop gradient. (Image source:\nGrill, et al 2020\n)\nGiven an image $\\mathbf{x}$, the BYOL loss is constructed as follows:\nCreate two augmented views: $\\mathbf{v}=t(\\mathbf{x}); \\mathbf{v}’=t’(\\mathbf{x})$ with augmentations sampled $t \\sim \\mathcal{T}, t’ \\sim \\mathcal{T}’$;\nThen they are encoded into representations, $\\mathbf{y}_\\theta=f_\\theta(\\mathbf{v}), \\mathbf{y}’=f_\\xi(\\mathbf{v}’)$;\nThen they are projected into latent variables, $\\mathbf{z}_\\theta=g_\\theta(\\mathbf{y}_\\theta), \\mathbf{z}’=g_\\xi(\\mathbf{y}’)$;\nThe online network outputs a prediction $q_\\theta(\\mathbf{z}_\\theta)$;\nBoth $q_\\theta(\\mathbf{z}_\\theta)$ and $\\mathbf{z}’$ are L2-normalized, giving us $\\bar{q}_\\theta(\\mathbf{z}_\\theta) = q_\\theta(\\mathbf{z}_\\theta) / | q_\\theta(\\mathbf{z}_\\theta) |$ and $\\bar{\\mathbf{z}’} = \\mathbf{z}’ / |\\mathbf{z}’|$;\nThe loss $\\mathcal{L}^\\text{BYOL}_\\theta$ is MSE between L2-normalized prediction $\\bar{q}_\\theta(\\mathbf{z})$ and $\\bar{\\mathbf{z}’}$;\nThe other symmetric loss $\\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ can be generated by switching $\\mathbf{v}’$ and $\\mathbf{v}$; that is, feeding $\\mathbf{v}’$ to online network and $\\mathbf{v}$ to target network.\nThe final loss is $\\mathcal{L}^\\text{BYOL}_\\theta + \\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ and only  parameters $\\theta$ are optimized.\nUnlike most popular contrastive learning based approaches, BYOL does not use negative pairs. Most bootstrapping approaches rely on pseudo-labels or cluster indices, but BYOL directly boostrapps the latent representation.\nIt is quite interesting and surprising that\nwithout\nnegative samples, BYOL still works well. Later I ran into this\npost\nby Abe Fetterman & Josh Albrecht, they highlighted two surprising findings while they were trying to reproduce BYOL:\nBYOL generally performs no better than random when\nbatch normalization is removed\n.\nThe presence of batch normalization implicitly causes a form of contrastive learning.\nThey believe that using negative samples is important for avoiding model collapse (i.e. what if you use all-zeros representation for every data point?). Batch normalization injects dependency on negative samples\ninexplicitly\nbecause no matter how similar a batch of inputs are, the values are re-distributed (spread out $\\sim \\mathcal{N}(0, 1$) and therefore batch normalization prevents model collapse. Strongly recommend you to read the\nfull article\nif you are working in this area.\nMemory Bank\n#\nComputing embeddings for a large number of negative samples in every batch is extremely expensive. One common approach is to store the representation in memory to trade off data staleness for cheaper compute.\nInstance Discrimination with Memoy Bank\n#\nInstance contrastive learning\n(\nWu et al, 2018\n) pushes the class-wise supervision to the extreme by considering each instance as\na distinct class of its own\n. It implies that the number of “classes” will be the same as the number of samples in the training dataset. Hence, it is unfeasible to train a softmax layer with these many heads, but instead it can be approximated by\nNCE\n.\nThe training pipeline of instance-level contrastive learning. The learned embedding is L2-normalized. (Image source:\nWu et al, 2018\n)\nLet $\\mathbf{v} = f_\\theta(x)$ be an embedding function to learn and the vector is normalized to have $|\\mathbf{v}|=1$. A non-parametric classifier predicts the probability of a sample $\\mathbf{v}$ belonging to class $i$ with a temperature parameter $\\tau$:\n$$\nP(C=i\\vert \\mathbf{v}) = \\frac{\\exp(\\mathbf{v}_i^\\top \\mathbf{v} / \\tau)}{\\sum_{j=1}^n \\exp(\\mathbf{v}_j^\\top \\mathbf{v} / \\tau)}\n$$\nInstead of computing the representations for all the samples every time, they implement an\nMemory Bank\nfor storing sample representation in the database from past iterations. Let $V=\\{ \\mathbf{v}_i \\}$ be the memory bank and $\\mathbf{f}_i = f_\\theta(\\mathbf{x}_i)$ be the feature generated by forwarding the network. We can use the representation from the memory bank $\\mathbf{v}_i$ instead of the feature forwarded from the network $\\mathbf{f}_i$ when comparing pairwise similarity.\nThe denominator theoretically requires access to the representations of all the samples, but that is too expensive in practice. Instead we can estimate it via Monte Carlo approximation using a random subset of $M$ indices $\\{j_k\\}_{k=1}^M$.\n$$\nP(i\\vert \\mathbf{v}) \n= \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\sum_{j=1}^N \\exp(\\mathbf{v}_j^\\top \\mathbf{f}_i / \\tau)}\n\\simeq \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\frac{N}{M} \\sum_{k=1}^M \\exp(\\mathbf{v}_{j_k}^\\top \\mathbf{f}_i / \\tau)}\n$$\nBecause there is only one instance per class, the training is unstable and fluctuates a lot. To improve the training smoothness, they introduced an extra term for positive samples in the loss function based on the\nproximal optimization method\n. The final NCE loss objective looks like:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{instance} &= - \\mathbb{E}_{P_d}\\big[\\log h(i, \\mathbf{v}^{(t-1)}_i) - \\lambda \\|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i\\|^2_2\\big] - M\\mathbb{E}_{P_n}\\big[\\log(1 - h(i, \\mathbf{v}'^{(t-1)})\\big] \\\\\nh(i, \\mathbf{v}) &= \\frac{P(i\\vert\\mathbf{v})}{P(i\\vert\\mathbf{v}) + MP_n(i)} \\text{ where the noise distribution is uniform }P_n = 1/N\n\\end{aligned}\n$$\nwhere $\\{ \\mathbf{v}^{(t-1)} \\}$ are embeddings stored in the memory bank from the previous iteration. The difference between iterations $|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i|^2_2$ will gradually vanish as the learned embedding converges.\nMoCo & MoCo-V2\n#\nMomentum Contrast\n(\nMoCo\n;\nHe et al, 2019\n) provides a framework of unsupervised learning visual representation as a\ndynamic dictionary look-up\n. The dictionary is structured as a large FIFO queue of encoded representations of data samples.\nGiven a query sample $\\mathbf{x}_q$, we get a query representation through an encoder $\\mathbf{q} = f_q(\\mathbf{x}_q)$. A list of key representations $\\{\\mathbf{k}_1, \\mathbf{k}_2, \\dots \\}$ in the dictionary are encoded by a momentum encoder $\\mathbf{k}_i = f_k (\\mathbf{x}^k_i)$. Let’s assume among them there is a single\npositive\nkey $\\mathbf{k}^+$ in the dictionary that matches $\\mathbf{q}$. In the paper, they create $\\mathbf{k}^+$ using a noise copy of $\\mathbf{x}_q$ with different\naugmentation\n. Then the\nInfoNCE\ncontrastive loss with temperature $\\tau$ is used over one positive and $N-1$ negative samples:\n$$\n\\mathcal{L}_\\text{MoCo} = - \\log \\frac{\\exp(\\mathbf{q} \\cdot \\mathbf{k}^+ / \\tau)}{\\sum_{i=1}^N \\exp(\\mathbf{q} \\cdot \\mathbf{k}_i / \\tau)}\n$$\nCompared to the\nmemory bank\n, a queue-based dictionary in MoCo enables us to reuse representations of immediately preceding mini-batches of data.\nThe MoCo dictionary is not differentiable as a queue, so we cannot rely on back-propagation to update the key encoder $f_k$. One naive way might be to use the same encoder for both $f_q$ and $f_k$. Differently, MoCo proposed to use a momentum-based update with a momentum coefficient $m \\in [0, 1)$. Say, the parameters of $f_q$ and $f_k$ are labeled as $\\theta_q$ and $\\theta_k$, respectively.\n$$\n\\theta_k \\leftarrow m \\theta_k + (1-m) \\theta_q\n$$\nIllustration of how Momentum Contrast (MoCo) learns visual representations. (Image source:\nHe et al, 2019\n)\nThe advantage of MoCo compared to\nSimCLR\nis that MoCo decouples the batch size from the number of negatives, but SimCLR requires a large batch size in order to have enough negative samples and suffers performance drops when their batch size is reduced.\nTwo designs in SimCLR, namely, (1) an MLP projection head and (2) stronger data augmentation, are proved to be very efficient.\nMoCo V2\n(\nChen et al, 2020\n) combined these two designs, achieving even better transfer performance with no dependency on a very large batch size.\nCURL\n#\nCURL\n(\nSrinivas, et al. 2020\n) applies the above ideas in\nReinforcement Learning\n. It learns a visual representation for RL tasks by matching embeddings of two data-augmented versions, $o_q$ and $o_k$, of the raw observation $o$ via contrastive loss. CURL primarily relies on random crop data augmentation. The key encoder is implemented as a momentum encoder with weights as EMA of the query encoder weights, same as in\nMoCo\n.\nOne significant difference between RL and supervised visual tasks is that RL depends on\ntemporal consistency\nbetween consecutive frames. Therefore, CURL applies augmentation consistently on each stack of frames to retain information about the temporal structure of the observation.\nThe architecture of CURL. (Image source:\nSrinivas, et al. 2020\n)\nFeature Clustering\n#\nDeepCluster\n#\nDeepCluster\n(\nCaron et al. 2018\n) iteratively clusters features via k-means and uses cluster assignments as pseudo labels to provide supervised signals.\nIllustration of DeepCluster method which iteratively clusters deep features and uses the cluster assignments as pseudo-labels. (Image source:\nCaron et al. 2018\n)\nIn each iteration, DeepCluster clusters data points using the prior representation and then produces the new cluster assignments as the classification targets for the new representation. However this iterative process is prone to trivial solutions. While avoiding the use of negative pairs, it requires a costly clustering phase and specific precautions to avoid collapsing to trivial solutions.\nSwAV\n#\nSwAV\n(\nSwapping Assignments between multiple Views\n;\nCaron et al. 2020\n) is an online contrastive learning algorithm. It computes a code from an augmented version of the image and tries to predict this code using another augmented version of the same image.\nComparison of SwAV and [contrastive instance learning](#instance-discrimination-with-memoy-bank). (Image source:\nCaron et al. 2020\n)\nGiven features of images with two different augmentations, $\\mathbf{z}_t$ and $\\mathbf{z}_s$, SwAV computes corresponding codes $\\mathbf{q}_t$ and $\\mathbf{q}_s$ and the loss quantifies the fit by swapping two codes using $\\ell(.)$ to measure the fit between a feature and a code.\n$$\n\\mathcal{L}_\\text{SwAV}(\\mathbf{z}_t, \\mathbf{z}_s) = \\ell(\\mathbf{z}_t, \\mathbf{q}_s) + \\ell(\\mathbf{z}_s, \\mathbf{q}_t)\n$$\nThe swapped fit prediction depends on the cross entropy between the predicted code and a set of $K$ trainable prototype vectors $\\mathbf{C} = \\{\\mathbf{c}_1, \\dots, \\mathbf{c}_K\\}$. The prototype vector matrix is shared across different batches and represents\nanchor clusters\nthat each instance should be clustered to.\n$$\n\\ell(\\mathbf{z}_t, \\mathbf{q}_s) = - \\sum_k \\mathbf{q}^{(k)}_s\\log\\mathbf{p}^{(k)}_t \\text{ where } \\mathbf{p}^{(k)}_t = \\frac{\\exp(\\mathbf{z}_t^\\top\\mathbf{c}_k  / \\tau)}{\\sum_{k'}\\exp(\\mathbf{z}_t^\\top \\mathbf{c}_{k'} / \\tau)}\n$$\nIn a mini-batch containing $B$ feature vectors $\\mathbf{Z} = [\\mathbf{z}_1, \\dots, \\mathbf{z}_B]$, the mapping matrix between features and prototype vectors is defined as $\\mathbf{Q} = [\\mathbf{q}_1, \\dots, \\mathbf{q}_B] \\in \\mathbb{R}_+^{K\\times B}$. We would like to maximize the similarity between the features and the prototypes:\n$$\n\\begin{aligned}\n\\max_{\\mathbf{Q}\\in\\mathcal{Q}} &\\text{Tr}(\\mathbf{Q}^\\top \\mathbf{C}^\\top \\mathbf{Z}) + \\varepsilon \\mathcal{H}(\\mathbf{Q}) \\\\\n\\text{where }\\mathcal{Q} &= \\big\\{ \\mathbf{Q} \\in \\mathbb{R}_{+}^{K \\times B} \\mid \\mathbf{Q}\\mathbf{1}_B = \\frac{1}{K}\\mathbf{1}_K, \\mathbf{Q}^\\top\\mathbf{1}_K = \\frac{1}{B}\\mathbf{1}_B \\big\\}\n\\end{aligned}\n$$\nwhere $\\mathcal{H}$ is the entropy, $\\mathcal{H}(\\mathbf{Q}) = - \\sum_{ij} \\mathbf{Q}_{ij} \\log \\mathbf{Q}_{ij}$, controlling the smoothness of the code. The coefficient $\\epsilon$ should not be too large; otherwise, all the samples will be assigned uniformly to all the clusters. The candidate set of solutions for $\\mathbf{Q}$ requires every mapping matrix to have each row sum up to $1/K$ and each column to sum up to $1/B$, enforcing that each prototype gets selected at least $B/K$ times on average.\nSwAV relies on the iterative Sinkhorn-Knopp algorithm (\nCuturi 2013\n) to find the solution for $\\mathbf{Q}$.\nWorking with Supervised Datasets\n#\nCLIP\n#\nCLIP\n(\nContrastive Language-Image Pre-training\n;\nRadford et al. 2021\n) jointly trains a text encoder and an image feature extractor over the pretraining task that predicts which caption goes with which image.\nIllustration of CLIP contrastive pre-training over text-image pairs. (Image source:\nRadford et al. 2021\n)\nGiven a batch of $N$ (image, text) pairs, CLIP computes the dense cosine similarity matrix between all $N\\times N$ possible (image, text) candidates within this batch. The text and image encoders are jointly trained to maximize the similarity between $N$ correct pairs of (image, text) associations while minimizing the similarity for $N(N-1)$ incorrect pairs via a symmetric cross entropy loss over the dense matrix.\nSee the numy-like pseudo code for CLIP in\nCLIP algorithm in Numpy style pseudo code. (Image source:\nRadford et al. 2021\n)\nCompared to other methods above for learning good visual representation, what makes CLIP really special is\n“the appreciation of using natural language as a training signal”\n. It does demand access to supervised dataset in which we know which text matches which image. It is trained on 400 million (text, image) pairs, collected from the Internet. The query list contains all the words occurring at least 100 times in the English version of Wikipedia. Interestingly, they found that Transformer-based language models are 3x slower than a bag-of-words (BoW) text encoder at zero-shot ImageNet classification. Using contrastive objective instead of trying to predict the exact words associated with images (i.e. a method commonly adopted by image caption prediction tasks) can further improve the data efficiency another 4x.\nUsing bag-of-words text encoding and contrastive training objectives can bring in multiple folds of data efficiency improvement. (Image source:\nRadford et al. 2021\n)\nCLIP produces good visual representation that can non-trivially transfer to many CV benchmark datasets, achieving results competitive with supervised baseline. Among tested transfer tasks, CLIP struggles with very fine-grained classification, as well as abstract or systematic tasks such as counting the number of objects. The transfer performance of CLIP models is smoothly correlated with the amount of model compute.\nSupervised Contrastive Learning\n#\nThere are several known issues with cross entropy loss, such as the lack of robustness to noisy labels and the possibility of poor margins. Existing improvement for cross entropy loss involves the curation of better training data, such as label smoothing and data augmentation.\nSupervised Contrastive Loss\n(\nKhosla et al. 2021\n) aims to leverage label information more effectively than cross entropy, imposing that normalized embeddings from the same class are closer together than embeddings from different classes.\nSupervised vs self-supervised contrastive losses. Supervised contrastive learning considers different samples from the same class as positive examples, in addition to augmented versions. (Image source:\nKhosla et al. 2021\n)\nGiven a set of randomly sampled $n$ (image, label) pairs, $\\{\\mathbf{x}_i, y_i\\}_{i=1}^n$, $2n$ training pairs can be created by applying two random augmentations of every sample, $\\{\\tilde{\\mathbf{x}}_i, \\tilde{y}_i\\}_{i=1}^{2n}$.\nSupervised contrastive loss $\\mathcal{L}_\\text{supcon}$ utilizes multiple positive and negative samples, very similar to\nsoft nearest-neighbor loss\n:\n$$\n\\mathcal{L}_\\text{supcon} = - \\sum_{i=1}^{2n} \\frac{1}{2 \\vert N_i \\vert - 1} \\sum_{j \\in N(y_i), j \\neq i} \\log \\frac{\\exp(\\mathbf{z}_i \\cdot \\mathbf{z}_j / \\tau)}{\\sum_{k \\in I, k \\neq i}\\exp({\\mathbf{z}_i \\cdot \\mathbf{z}_k / \\tau})}\n$$\nwhere $\\mathbf{z}_k=P(E(\\tilde{\\mathbf{x}_k}))$, in which $E(.)$ is an encoder network (augmented image mapped to vector) $P(.)$ is a projection network (one vector mapped to another). $N_i= \\{j \\in I: \\tilde{y}_j = \\tilde{y}_i \\}$ contains a set of indices of samples with label $y_i$. Including more positive samples into the set $N_i$ leads to improved results.\nAccording to their experiments, supervised contrastive loss:\ndoes outperform the base cross entropy, but only by a small amount.\noutperforms the cross entropy on robustness benchmark (ImageNet-C, which applies common naturally occuring perturbations such as noise, blur and contrast changes to the ImageNet dataset).\nis less sensitive to hyperparameter changes.\nLanguage: Sentence Embedding\n#\nIn this section, we focus on how to learn sentence embedding.\nText Augmentation\n#\nMost contrastive methods in vision applications depend on creating an augmented version of each image. However, it is more challenging to construct text augmentation which does not alter the semantics of a sentence.  In this section we look into three approaches for augmenting text sequences, including lexical edits, back-translation and applying cutoff or dropout.\nLexical Edits\n#\nEDA\n(\nEasy Data Augmentation\n;\nWei & Zou 2019\n) defines a set of simple but powerful operations for text augmentation. Given a sentence, EDA randomly chooses and applies one of four simple operations:\nSynonym replacement (SR): Replace $n$ random non-stop words with their synonyms.\nRandom insertion (RI): Place a random synonym of a randomly selected non-stop word in the sentence at a random position.\nRandom swap (RS): Randomly swap two words and repeat $n$ times.\nRandom deletion (RD): Randomly delete each word in the sentence with probability $p$.\nwhere $p=\\alpha$ and $n=\\alpha \\times \\text{sentence_length}$, with the intuition that longer sentences can absorb more noise while maintaining the original label. The hyperparameter $\\alpha$ roughly indicates the percent of words in one sentence that may be changed by one augmentation.\nEDA is shown to improve the classification accuracy on several classification benchmark datasets compared to baseline without EDA. The performance lift is more significant on a smaller training set. All the four operations in EDA help improve the classification accuracy, but get to optimal at different $\\alpha$’s.\nEDA leads to performance improvement on several classification benchmarks. (Image source:\nWei & Zou 2019\n)\nIn\nContextual Augmentation\n(\nSosuke Kobayashi, 2018\n), new substitutes for word $w_i$ at position $i$ can be smoothly sampled from a given probability distribution, $p(.\\mid S\\setminus\\{w_i\\})$, which is predicted by a bidirectional LM like BERT.\nBack-translation\n#\nCERT\n(\nContrastive self-supervised Encoder Representations from Transformers\n;\nFang et al. (2020)\n;\ncode\n) generates augmented sentences via\nback-translation\n. Various translation models for different languages can be employed for creating different versions of augmentations. Once we have a noise version of text samples, many contrastive learning frameworks introduced above, such as\nMoCo\n, can be used to learn sentence embedding.\nDropout and Cutoff\n#\nShen et al. (2020)\nproposed to apply\nCutoff\nto text augmentation, inspired by\ncross-view training\n. They proposed three cutoff augmentation strategies:\nToken cutoff\nremoves the information of a few selected tokens. To make sure there is no data leakage, corresponding tokens in the input, positional and other relevant embedding matrices should all be zeroed out.,\nFeature cutoff\nremoves a few feature columns.\nSpan cutoff\nremoves a continuous chunk of texts.\nSchematic illustration of token, feature and span cutoff augmentation strategies. (Image source:\nShen et al. 2020\n)\nMultiple augmented versions of one sample can be created. When training,\nShen et al. (2020)\napplied an additional KL-divergence term to measure the consensus between predictions from different augmented samples.\nSimCSE\n(\nGao et al. 2021\n;\ncode\n) learns from unsupervised data by predicting a sentence from itself with only\ndropout\nnoise. In other words, they treat dropout as data augmentation for text sequences. A sample is simply fed into the encoder twice with different dropout masks and these two versions are the positive pair where the other in-batch samples are considered as negative pairs. It feels quite similar to the cutoff augmentation, but dropout is more flexible with less well-defined semantic meaning of what content can be masked off.\nSimCSE creates augmented samples by applying different dropout masks. The supervised version leverages NLI datasets to predict positive (entailment) or negative (contradiction) given a pair of sentences. (Image source:\nGao et al. 2021\n)\nThey ran experiments on 7 STS (Semantic Text Similarity) datasets and computed cosine similarity between sentence embeddings.  They also tried out an optional MLM auxiliary objective loss to help avoid catastrophic forgetting of token-level knowledge. This aux loss was found to help improve performance on transfer tasks, but a consistent drop on the main STS tasks.\nExperiment numbers on a collection of STS benchmarks with SimCES. (Image source:\nGao et al. 2021\n)\nSupervision from NLI\n#\nThe pre-trained BERT sentence embedding without any fine-tuning has been found to have poor performance for semantic similarity tasks. Instead of using the raw embeddings directly, we need to refine the embedding with further fine-tuning.\nNatural Language Inference (NLI)\ntasks are the main data sources to provide supervised signals for learning sentence embedding; such as\nSNLI\n,\nMNLI\n, and\nQQP\n.\nSentence-BERT\n#\nSBERT (Sentence-BERT)\n(\nReimers & Gurevych, 2019\n) relies on siamese and triplet network architectures to learn sentence embeddings such that the sentence similarity can be estimated by cosine similarity between pairs of embeddings. Note that learning SBERT depends on supervised data, as it is fine-tuned on several NLI datasets.\nThey experimented with a few different prediction heads on top of BERT model:\nSoftmax classification objective: The classification head of the siamese network is built on the concatenation of two embeddings $f(\\mathbf{x}), f(\\mathbf{x}’)$ and $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$. The predicted output is $\\hat{y}=\\text{softmax}(\\mathbf{W}_t [f(\\mathbf{x}); f(\\mathbf{x}’); \\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert])$. They showed that the most important component is the element-wise difference $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$.\nRegression objective: This is the regression loss on $\\cos(f(\\mathbf{x}), f(\\mathbf{x}’))$, in which the pooling strategy has a big impact. In the experiments, they observed that\nmax\nperforms much worse than\nmean\nand\nCLS\n-token.\nTriplet objective: $\\max(0, |f(\\mathbf{x}) - f(\\mathbf{x}^+)|- |f(\\mathbf{x}) - f(\\mathbf{x}^-)| + \\epsilon)$, where $\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-$ are embeddings of the anchor, positive and negative sentences.\nIn the experiments, which objective function works the best depends on the datasets, so there is no universal winner.\nIllustration of Sentence-BERT training framework with softmax classification head and regression head. (Image source:\nReimers & Gurevych, 2019\n)\nThe\nSentEval\nlibrary (\nConneau and Kiela, 2018\n) is commonly used for evaluating the quality of learned sentence embedding. SBERT outperformed other baselines at that time (Aug 2019) on 5 out of 7 tasks.\nThe performance of Sentence-BERT on the SentEval benchmark. (Image source:\nReimers & Gurevych, 2019\n)\nBERT-flow\n#\nThe embedding representation space is deemed\nisotropic\nif embeddings are uniformly distributed on each dimension; otherwise, it is\nanisotropic\n.\nLi et al, (2020)\nshowed that a pre-trained BERT learns a non-smooth\nanisotropic\nsemantic space of sentence embeddings and thus leads to poor performance for text similarity tasks without fine-tuning. Empirically, they observed two issues with BERT sentence embedding:\nWord frequency biases the embedding space. High-frequency words are close to the origin, but low-frequency ones are far away from the origin.\nLow-frequency words scatter sparsely. The embeddings of low-frequency words tend to be farther to their $k$-NN neighbors, while the embeddings of high-frequency words concentrate more densely.\nBERT-flow\n(\nLi et al, 2020\n;\ncode\n) was proposed to transform the embedding to a smooth and isotropic Gaussian distribution via\nnormalizing flows\n.\nIllustration of the flow-based calibration over the original sentence embedding space in BERT-flow. (Image source:\nLi et al, 2020\n)\nLet $\\mathcal{U}$ be the observed BERT sentence embedding space and $\\mathcal{Z}$ be the desired latent space which is a standard Gaussian. Thus, $p_\\mathcal{Z}$ is a Gaussian density function and $f_\\phi: \\mathcal{Z}\\to\\mathcal{U}$ is an invertible transformation:\n$$\n\\mathbf{z}\\sim p_\\mathcal{Z}(\\mathbf{z}) \\quad \n\\mathbf{u}=f_\\phi(\\mathbf{z}) \\quad\n\\mathbf{z}=f^{-1}_\\phi(\\mathbf{u}) \n$$\nA flow-based generative model learns the invertible mapping function by maximizing the likelihood of $\\mathcal{U}$’s marginal:\n$$\n\\max_\\phi\\mathbb{E}_{\\mathbf{u}=\\text{BERT}(s), s\\sim\\mathcal{D}} \\Big[ \\log p_\\mathcal{Z}(f^{-1}_\\phi(\\mathbf{u})) + \\log\\big\\vert\\det\\frac{\\partial f^{-1}_\\phi(\\mathbf{u})}{\\partial\\mathbf{u}}\\big\\vert \\Big]\n$$\nwhere $s$ is a sentence sampled from the text corpus $\\mathcal{D}$. Only the flow parameters $\\phi$ are optimized while parameters in the pretrained BERT stay unchanged.\nBERT-flow was shown to improve the performance on most STS tasks either with or without supervision from NLI datasets. Because learning normalizing flows for calibration does not require labels, it can utilize the entire dataset including validation and test sets.\nWhitening Operation\n#\nSu et al. (2021)\napplied\nwhitening\noperation to improve the\nisotropy\nof the learned representation and also to reduce the dimensionality of sentence embedding.\nThey transform the mean value of the sentence vectors to 0 and the covariance matrix to the identity matrix. Given a set of samples $\\{\\mathbf{x}_i\\}_{i=1}^N$, let $\\tilde{\\mathbf{x}}_i$ and $\\tilde{\\Sigma}$ be the transformed samples and corresponding covariance matrix:\n$$\n\\begin{aligned}\n\\mu &= \\frac{1}{N}\\sum_{i=1}^N \\mathbf{x}_i \\quad \\Sigma = \\frac{1}{N}\\sum_{i=1}^N (\\mathbf{x}_i - \\mu)^\\top (\\mathbf{x}_i - \\mu) \\\\\n\\tilde{\\mathbf{x}}_i &= (\\mathbf{x}_i - \\mu)W \\quad \\tilde{\\Sigma} = W^\\top\\Sigma W = I \\text{ thus } \\Sigma = (W^{-1})^\\top W^{-1}\n\\end{aligned}\n$$\nIf we get\nSVD\ndecomposition of $\\Sigma = U\\Lambda U^\\top$, we will have $W^{-1}=\\sqrt{\\Lambda} U^\\top$ and  $W=U\\sqrt{\\Lambda^{-1}}$. Note that within SVD, $U$ is an orthogonal matrix with column vectors as eigenvectors and $\\Lambda$ is a diagonal matrix with all positive elements as sorted eigenvalues.\nA dimensionality reduction strategy can be applied by only taking the first $k$ columns of $W$, named\nWhitening\n-$k$.\nPseudo code of the whitening-$k$ operation. (Image source:\nSu et al. 2021\n)\nWhitening operations were shown to outperform BERT-flow and achieve SOTA with 256 sentence dimensionality on many STS benchmarks, either with or without NLI supervision.\nUnsupervised Sentence Embedding Learning\n#\nContext Prediction\n#\nQuick-Thought (QT) vectors\n(\nLogeswaran & Lee, 2018\n) formulate sentence representation learning as a\nclassification\nproblem: Given a sentence and its context, a classifier distinguishes context sentences from other contrastive sentences based on their vector representations (\n“cloze test”\n). Such a formulation removes the softmax output layer which causes training slowdown.\nIllustration of how Quick-Thought sentence embedding vectors are learned. (Image source:\nLogeswaran & Lee, 2018\n)\nLet $f(.)$ and $g(.)$ be two functions that encode a sentence $s$ into a fixed-length vector. Let $C(s)$ be the set of sentences in the context of $s$ and $S(s)$ be the set of candidate sentences including only one sentence $s_c \\in C(s)$ and many other non-context negative sentences. Quick Thoughts model learns to optimize the probability of predicting the only true context sentence $s_c \\in S(s)$. It is essentially NCE loss when considering the sentence $(s, s_c)$ as the positive pairs while other pairs $(s, s’)$ where $s’ \\in S(s), s’\\neq s_c$ as negatives.\n$$\n\\mathcal{L}_\\text{QT} \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)} \\log p(s_c \\vert s, S(s)) \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)}\\frac{\\exp(f(s)^\\top g(s_c))}{\\sum_{s'\\in S(s)} \\exp(f(s)^\\top g(s'))}\n$$\nMutual Information Maximization\n#\nIS-BERT (Info-Sentence BERT)\n(\nZhang et al. 2020\n;\ncode\n) adopts a self-supervised learning objective based on\nmutual information maximization\nto learn good sentence embeddings in the\nunsupervised\nmanners.\nIllustration of Info-Sentence BERT. (Image source:\nZhang et al. 2020\n)\nIS-BERT works as follows:\nUse BERT to encode an input sentence $s$ to a token embedding of length $l$, $\\mathbf{h}_{1:l}$.\nThen apply 1-D conv net with different kernel sizes (e.g. 1, 3, 5) to process the token embedding sequence to capture the n-gram local contextual dependencies: $\\mathbf{c}_i = \\text{ReLU}(\\mathbf{w} \\cdot \\mathbf{h}_{i:i+k-1} + \\mathbf{b})$. The output sequences are padded to stay the same sizes of the inputs.\nThe final local representation of the $i$-th token $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$ is the concatenation of representations of different kernel sizes.\nThe global sentence representation $\\mathcal{E}_\\theta(\\mathbf{x})$ is computed by applying a mean-over-time pooling layer on the token representations $\\mathcal{F}_\\theta(\\mathbf{x}) = \\{\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}) \\in \\mathbb{R}^d\\}_{i=1}^l$.\nSince the mutual information estimation is generally intractable for continuous and high-dimensional random variables, IS-BERT relies on the Jensen-Shannon estimator (\nNowozin et al., 2016\n,\nHjelm et al., 2019\n) to maximize the mutual information between $\\mathcal{E}_\\theta(\\mathbf{x})$ and $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$.\n$$\nI^\\text{JSD}_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})) = \\mathbb{E}_{\\mathbf{x}\\sim P} [-\\text{sp}(-T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})))] \\\\ - \\mathbb{E}_{\\mathbf{x}\\sim P, \\mathbf{x}' \\sim\\tilde{P}} [\\text{sp}(T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}'); \\mathcal{E}_\\theta(\\mathbf{x})))]\n$$\nwhere $T_\\omega: \\mathcal{F}\\times\\mathcal{E} \\to \\mathbb{R}$ is a learnable network with parameters $\\omega$, generating discriminator scores. The negative sample $\\mathbf{x}’$ is sampled from the distribution $\\tilde{P}=P$. And $\\text{sp}(x)=\\log(1+e^x)$ is the softplus activation function.\nThe unsupervised numbers on SentEval with IS-BERT outperforms most of the unsupervised baselines (Sep 2020), but unsurprisingly weaker than supervised runs. When using labelled NLI datasets, IS-BERT produces results comparable with SBERT (See Fig. 25 & 30).\nThe performance of IS-BERT on the SentEval benchmark. (Image source:\nZhang et al. 2020\n)\nCitation\n#\nCited as:\nWeng, Lilian. (May 2021). Contrastive representation learning. Lil’Log. https://lilianweng.github.io/posts/2021-05-31-contrastive/.\nOr\n@article{weng2021contrastive,\n  title   = \"Contrastive Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"May\",\n  url     = \"https://lilianweng.github.io/posts/2021-05-31-contrastive/\"\n}\nReferences\n#\n[1] Sumit Chopra, Raia Hadsell and Yann LeCun.\n“Learning a similarity metric discriminatively, with application to face verification.”\nCVPR 2005.\n[2] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering.”\nCVPR 2015.\n[3] Hyun Oh Song et al.\n“Deep Metric Learning via Lifted Structured Feature Embedding.”\nCVPR 2016. [\ncode\n]\n[4] Ruslan Salakhutdinov and Geoff Hinton.\n“Learning a Nonlinear Embedding by Preserving Class Neighbourhood Structure”\nAISTATS 2007.\n[5] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nAISTATS 2010.\n[6] Kihyuk Sohn et al.\n“Improved Deep Metric Learning with Multi-class N-pair Loss Objective”\nNIPS 2016.\n[7] Nicholas Frosst, Nicolas Papernot and Geoffrey Hinton.\n“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”\nICML 2019\n[8] Tongzhou Wang and Phillip Isola.\n“Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere.”\nICML 2020. [\ncode\n]\n[9] Zhirong Wu et al.\n“Unsupervised feature learning via non-parametric instance-level discrimination.”\nCVPR 2018.\n[10] Ekin D. Cubuk et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv preprint arXiv:1805.09501 (2018).\n[11] Daniel Ho et al.\n“Population Based Augmentation: Efficient Learning of Augmentation Policy Schedules.”\nICML 2019.\n[12] Ekin D. Cubuk & Barret Zoph et al.\n“RandAugment: Practical automated data augmentation with a reduced search space.”\narXiv preprint arXiv:1909.13719 (2019).\n[13] Hongyi Zhang et al.\n“mixup: Beyond Empirical Risk Minimization.”\nICLR 2017.\n[14] Sangdoo Yun et al.\n“CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features.”\nICCV 2019.\n[15] Yannis Kalantidis et al.\n“Mixing of Contrastive Hard Negatives”\nNeuriPS 2020.\n[16] Ashish Jaiswal et al.\n“A Survey on Contrastive Self-Supervised Learning.”\narXiv preprint arXiv:2011.00362 (2021)\n[17] Jure Zbontar et al.\n“Barlow Twins: Self-Supervised Learning via Redundancy Reduction.”\narXiv preprint arXiv:2103.03230 (2021) [\ncode\n]\n[18] Alec Radford, et al.\n“Learning Transferable Visual Models From Natural Language Supervision”\narXiv preprint arXiv:2103.00020 (2021)\n[19] Mathilde Caron et al.\n“Unsupervised Learning of Visual Features by Contrasting Cluster Assignments (SwAV).”\nNeuriPS 2020.\n[20] Mathilde Caron et al.\n“Deep Clustering for Unsupervised Learning of Visual Features.”\nECCV 2018.\n[21] Prannay Khosla et al.\n“Supervised Contrastive Learning.”\nNeurIPS 2020.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748 (2018).\n[23] Jason Wei and Kai Zou.\n“EDA: Easy data augmentation techniques for boosting performance on text classification tasks.”\nEMNLP-IJCNLP 2019.\n[24] Sosuke Kobayashi.\n“Contextual Augmentation: Data Augmentation by Words with Paradigmatic Relations.”\nNAACL 2018\n[25] Hongchao Fang et al.\n“CERT: Contrastive self-supervised learning for language understanding.”\narXiv preprint arXiv:2005.12766 (2020).\n[26] Dinghan Shen et al.\n“A Simple but Tough-to-Beat Data Augmentation Approach for Natural Language Understanding and Generation.”\narXiv preprint arXiv:2009.13818 (2020) [\ncode\n]\n[27] Tianyu Gao et al.\n“SimCSE: Simple Contrastive Learning of Sentence Embeddings.”\narXiv preprint arXiv:2104.08821 (2020). [\ncode\n]\n[28] Nils Reimers and Iryna Gurevych.\n“Sentence-BERT: Sentence embeddings using Siamese BERT-networks.”\nEMNLP 2019.\n[29] Jianlin Su et al.\n“Whitening sentence representations for better semantics and faster retrieval.”\narXiv preprint arXiv:2103.15316 (2021). [\ncode\n]\n[30] Yan Zhang et al.\n“An unsupervised sentence embedding method by mutual information maximization.”\nEMNLP 2020. [\ncode\n]\n[31] Bohan Li et al.\n“On the sentence embeddings from pre-trained language models.”\nEMNLP 2020.\n[32] Lajanugen Logeswaran and Honglak Lee.\n“An efficient framework for learning sentence representations.”\nICLR 2018.\n[33] Joshua Robinson, et al.\n“Contrastive Learning with Hard Negative Samples.”\nICLR 2021.\n[34] Ching-Yao Chuang et al.\n“Debiased Contrastive Learning.”\nNeuriPS 2020.",
            "metadata": {
              "title": "Contrastive Representation Learning | Lil'Log",
              "description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "keywords": "representation-learning, long-read, language-model, unsupervised-learning, data-augmentation",
              "author": "Lilian Weng",
              "og:title": "Contrastive Representation Learning",
              "og:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
              "twitter:card": "summary",
              "twitter:title": "Contrastive Representation Learning",
              "twitter:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "article:section": "posts",
              "article:published_time": "2021-05-31T00:00:00+00:00",
              "article:modified_time": "2021-05-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c8f3f2a59bb8/code/body-000.txt",
                "chars": 259,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "bytes": 82669,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-c8feb8e3831d6f407222.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "bytes": 238558,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-864616500d13b290a57d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "bytes": 618000,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4d1eafbd2698e4b13414.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "bytes": 447800,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2202dbf059680ff25f64.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "bytes": 331316,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-56fdc531021fd8fc266d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "bytes": 92328,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-a3de29261702db65276c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "bytes": 292083,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fbb7be242e78cf4064e.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "bytes": 165448,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7c6e570b2b4acaea53ee.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "bytes": 410905,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0dc7fb2e267a076918a0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "bytes": 160971,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-64c06b583b29bc8d849d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "bytes": 575598,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-24abca83dac665bdfd2c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "bytes": 191327,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-68a57a589ced1a8dcbeb.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "bytes": 458778,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dec760a7d6d875b1e5f6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "bytes": 413067,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-3b05f2c9b09900dd678c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "bytes": 307781,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fe78703c0d6dd59901b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "bytes": 395407,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-bcffab9e56e403b12eb6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "bytes": 378369,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-14fc3bb2a028bd633430.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "bytes": 269518,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1cdb06387d4aabe19e7f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "bytes": 1172082,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dc3294612801cee60ee0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "bytes": 299081,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4ecf4ae1a9c6c75e0b98.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "bytes": 102477,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2f938fd27f3112a7668b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "bytes": 302804,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-476b14449fa38214486c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "bytes": 459618,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-d417f179aa932198443f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "bytes": 248555,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-61290a159906f77df170.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "bytes": 263986,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-25636cdf26fe48bc32a6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "bytes": 127994,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1f6149bb39a134da1e75.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "bytes": 167429,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-75a0434d42ea9e13e5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "bytes": 235880,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0873d959165b59705852.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "bytes": 403903,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7fc9d0b8fcf86efd800b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "bytes": 237372,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4a85aecfe0dc34b27289.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "label": "Chopra et al. 2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "Schroff et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06452",
                "label": "Song et al. 2015",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2016/hash/6b180037abbebea991d8b1232f8a8ca9-Abstract.html",
                "label": "Sohn 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a.html",
                "label": "Gutmann & Hyvarinen",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v2/salakhutdinov07a.html",
                "label": "Salakhutdinov & Hinton 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01889",
                "label": "Frosst et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.10242",
                "label": "Wang & Isola 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "DPR",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.00224",
                "label": "Chuang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.04592",
                "label": "Robinson et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "AutoAugment",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.05393",
                "label": "Ho et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.04899",
                "label": "Yun et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.04552",
                "label": "DeVries & Taylor 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.01028",
                "label": "Kalantidis et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.03230",
                "label": "Zbontar et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "Grill, et al 2020",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "Wu et al, 2018",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/~boyd/papers/prox_algs.html",
                "label": "proximal optimization method",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "He et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "Srinivas, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.05520",
                "label": "Caron et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09882",
                "label": "Caron et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1306.0895",
                "label": "Cuturi 2013",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.00020",
                "label": "Radford et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.11362",
                "label": "Khosla et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11196",
                "label": "Wei & Zou 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.06201",
                "label": "Sosuke Kobayashi, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.12766",
                "label": "Fang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/UCSD-AI4H/CERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.13818",
                "label": "Shen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "cross-view training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08821",
                "label": "Gao et al. 2021",
                "type": "a"
              },
              {
                "href": "https://github.com/princeton-nlp/SimCSE",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://cims.nyu.edu/~sbowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/c/quora-question-pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.10084",
                "label": "Reimers & Gurevych, 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/SentEval",
                "label": "SentEval",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.05449",
                "label": "Conneau and Kiela, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.05864",
                "label": "Li et al, (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/bohanli/BERT-flow",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.15316",
                "label": "Su et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Singular_value_decomposition",
                "label": "SVD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02893",
                "label": "Logeswaran & Lee, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.12061",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/yanzhangnlp/IS-BERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.00709",
                "label": "Nowozin et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.06670",
                "label": "Hjelm et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/rksltnl/Deep-Metric-Learning-CVPR16",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v97/frosst19a.html",
                "label": "“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”",
                "type": "a"
              },
              {
                "href": "https://ssnl.github.io/hypersphere/",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978",
                "label": "“Unsupervised feature learning via non-parametric instance-level discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.00362",
                "label": "“A Survey on Contrastive Self-Supervised Learning.”",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/barlowtwins",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/dinghanshen/cutoff",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/bojone/BERT-whitening",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:20Z",
            "source_url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "papers": [
              {
                "status": "ok",
                "url": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "bytes": 313804,
                "reused": false,
                "local_path": "papers/repair/84881b743b9447eb9afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": false,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06452",
                "bytes": 9011569,
                "reused": false,
                "local_path": "papers/repair/738c3f04b7e4d7dad3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": false,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01889",
                "bytes": 3823806,
                "reused": false,
                "local_path": "papers/repair/66ab4748bfca0238682e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.10242",
                "bytes": 4185717,
                "reused": false,
                "local_path": "papers/repair/8a0c585591f7f1918d90.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.00224",
                "bytes": 5343399,
                "reused": false,
                "local_path": "papers/repair/7dcaf70ed91e5defcf23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.04592",
                "bytes": 2199907,
                "reused": false,
                "local_path": "papers/repair/3f84b66b72f5c381c05a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": true,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.05393",
                "bytes": 873126,
                "reused": true,
                "local_path": "papers/repair/4634b6280b855d570ac8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": true,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": true,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.04899",
                "bytes": 1682836,
                "reused": true,
                "local_path": "papers/repair/fec62c4fe8efdeebd877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.04552",
                "bytes": 741919,
                "reused": true,
                "local_path": "papers/repair/c3d681ed19bf88f43a98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.01028",
                "bytes": 970998,
                "reused": true,
                "local_path": "papers/repair/d4d3c2412459021d347a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": false,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.03230",
                "bytes": 2434163,
                "reused": false,
                "local_path": "papers/repair/7f141d9ed4155ccf53f5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": false,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": false,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": false,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": false,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.05520",
                "bytes": 8629266,
                "reused": false,
                "local_path": "papers/repair/0a5b97b834b6a105dd9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09882",
                "bytes": 702914,
                "reused": false,
                "local_path": "papers/repair/0838c337bef6ccd33d62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1306.0895",
                "bytes": 1004298,
                "reused": false,
                "local_path": "papers/repair/598da2f78a40c9c822ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.00020",
                "bytes": 6813639,
                "reused": true,
                "local_path": "papers/repair/7db0b9244bb1fd42ae98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.11362",
                "bytes": 2197586,
                "reused": false,
                "local_path": "papers/repair/a64eec551d692894bad9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11196",
                "bytes": 365049,
                "reused": true,
                "local_path": "papers/repair/389e34d78a0045e6d861.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.06201",
                "bytes": 722323,
                "reused": true,
                "local_path": "papers/repair/aebd3f77254c72e012a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.12766",
                "bytes": 412104,
                "reused": false,
                "local_path": "papers/repair/bae8e6b74f13390eb0a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.13818",
                "bytes": 398629,
                "reused": true,
                "local_path": "papers/repair/40a2d9b786e78e3cf30e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08821",
                "bytes": 1672580,
                "reused": true,
                "local_path": "papers/repair/e7a40652bdd04cd4b25f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.10084",
                "bytes": 548961,
                "reused": true,
                "local_path": "papers/repair/20151599fbbbabacaa9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.05449",
                "bytes": 1257905,
                "reused": false,
                "local_path": "papers/repair/748bb3642ea0aef5571f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.05864",
                "bytes": 408978,
                "reused": false,
                "local_path": "papers/repair/3bfe284fc1ebd8a9d3a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.15316",
                "bytes": 659541,
                "reused": false,
                "local_path": "papers/repair/6e8262dafcfd96e9b679.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02893",
                "bytes": 232651,
                "reused": false,
                "local_path": "papers/repair/12ee892560b48ed47fb8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.12061",
                "bytes": 408861,
                "reused": false,
                "local_path": "papers/repair/5c6f2a504c1b0ff66969.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.00709",
                "bytes": 3615251,
                "reused": false,
                "local_path": "papers/repair/b555d3a1dac849208314.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.06670",
                "bytes": 4984410,
                "reused": false,
                "local_path": "papers/repair/ca0c4e18cba031b31bd0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/2408633e99d87285a643.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.00362",
                "bytes": 5998084,
                "reused": false,
                "local_path": "papers/repair/20fd1312b2e030a81069.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 62279,
            "expected_body_images": 30,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c8f3f2a59bb8/pages/source.html",
            "local_html": "attachments/c8f3f2a59bb8/pages/article.html",
            "body_base_path": "attachments/c8f3f2a59bb8/pages/",
            "body_markdown_path": "attachments/c8f3f2a59bb8/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
          "status": "partial",
          "article_id": "3e47ba682561",
          "local_path": "series-follow/1600/repair/f7460f9330e723bf3e4f.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
              "bytes": 179202,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e21a214c6127867b9495.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
              "bytes": 183003,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0f5bdb5a435b843e8180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
              "bytes": 18594,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f369233bacf831326935.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning Word Embedding",
            "keywords": "词嵌入,word2vec,GloVe",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "publish_date": "2017-10",
            "corpus_stage": "预训练/SFT",
            "notes": "词嵌入学习综述",
            "id": "3e47ba682561",
            "collected_at": "2026-10-02T14:13:32",
            "title": "Learning Word Embedding | Lil'Log",
            "body_markdown": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).\nHowever, one-hot encoding is impractical computationally when dealing with the entire vocabulary, as the representation demands hundreds of thousands of dimensions. Word embedding represents words and phrases in vectors of (non-binary) numeric values with much lower and thus denser dimensions. An intuitive assumption for good word embedding is that they can approximate the similarity between words (i.e., “cat” and “kitten” are similar words, and thus they are expected to be close in the reduced vector space) or disclose hidden semantic relationships (i.e., the relationship between “cat” and “kitten” is an analogy to the one between “dog” and “puppy”). Contextual information is super useful for learning word meaning and relationship, as similar words may appear in the similar context often.\nThere are two main approaches for learning word embedding, both relying on the contextual knowledge.\nCount-based\n: The first one is unsupervised, based on matrix factorization of a global word co-occurrence matrix. Raw co-occurrence counts do not work well, so we want to do smart things on top.\nContext-based\n: The second approach is supervised. Given a local context, we want to design a model to predict the target words and in the meantime, this model learns the efficient word embedding representation.\nCount-Based Vector Space Model\n#\nCount-based vector space models heavily rely on the word frequency and co-occurrence matrix with the assumption that words in the same contexts share similar or related semantic meanings. The models map count-based statistics like co-occurrences between neighboring words down to a small and dense word vectors. PCA, topic models, and neural probabilistic language models are all good examples of this category.\nDifferent from the count-based approaches, context-based methods build predictive models that directly target at predicting a word given its neighbors. The dense word vectors are part of the model parameters. The best vector representation of each word is learned during the model training process.\nContext-Based: Skip-Gram Model\n#\nSuppose that you have a sliding window of a fixed size moving along a sentence: the word in the middle is the “target” and those on its left and right within the sliding window are the context words. The skip-gram model (\nMikolov et al., 2013\n) is trained to predict the probabilities of a word being a context word for the given target.\nThe following example demonstrates multiple pairs of target and context words as training samples, generated by a 5-word window sliding along the sentence.\n“The man who passes the sentence should swing the sword.” – Ned Stark\nSliding window (size = 5)\nTarget word\nContext\n[The man who]\nthe\nman, who\n[The man who passes]\nman\nthe, who, passes\n[The man who passes the]\nwho\nthe, man, passes, the\n[man who passes the sentence]\npasses\nman, who, the, sentence\n…\n…\n…\n[sentence should swing the sword]\nswing\nsentence, should, the, sword\n[should swing the sword]\nthe\nshould, swing, sword\n[swing the sword]\nsword\nswing, the\n{:.info}\nEach context-target pair is treated as a new observation in the data. For example, the target word “swing” in the above case produces four training samples: (“swing”, “sentence”), (“swing”, “should”), (“swing”, “the”), and (“swing”, “sword”).\nThe skip-gram model. Both the input vector $\\mathbf{x}$ and the output $\\mathbf{y}$ are one-hot encoded word representations. The hidden layer is the word embedding of size $N$.\nGiven the vocabulary size $V$, we are about to learn word embedding vectors of size $N$. The model learns to predict one context word (output) using one target word (input) at a time.\nAccording to Fig. 1,\nBoth input word $w_i$ and the output word $w_j$ are one-hot encoded into binary vectors $\\mathbf{x}$ and $\\mathbf{y}$ of size $V$.\nFirst, the multiplication of the binary vector $\\mathbf{x}$ and the word embedding matrix $W$ of size $V \\times N$ gives us the embedding vector of the input word $w_i$: the i-th row of the matrix $W$.\nThis newly discovered embedding vector of dimension $N$ forms the hidden layer.\nThe multiplication of the hidden layer and the word context matrix $W’$ of size $N \\times V$ produces the output one-hot encoded vector $\\mathbf{y}$.\nThe output context matrix $W’$ encodes the meanings of words as context, different from the embedding matrix $W$. NOTE: Despite the name, $W’$ is independent of $W$, not a transpose or inverse or whatsoever.\nContext-Based: Continuous Bag-of-Words (CBOW)\n#\nThe Continuous Bag-of-Words (CBOW) is another similar model for learning word vectors. It predicts the target word (i.e. “swing”) from source context words (i.e., “sentence should the sword”).\nThe CBOW model. Word vectors of multiple context words are averaged to get a fixed-length vector as in the hidden layer. Other symbols have the same meanings as in Fig 1.\nBecause there are multiple contextual words, we average their corresponding word vectors, constructed by the multiplication of the input vector and the matrix $W$. Because the averaging stage smoothes over a lot of the distributional information, some people believe the CBOW model is better for small dataset.\nLoss Functions\n#\nBoth the skip-gram model and the CBOW model should be trained to minimize a well-designed loss/objective function. There are several loss functions we can incorporate to train these language models. In the following discussion, we will use the skip-gram model as an example to describe how the loss is computed.\nFull Softmax\n#\nThe skip-gram model defines the embedding vector of every word by the matrix $W$ and the context vector by the output matrix $W’$. Given an input word $w_I$, let us label the corresponding row of $W$ as vector $v_{w_I}$ (embedding vector) and its corresponding column of $W’$ as $v’_{w_I}$ (context vector). The final output layer applies softmax to compute the probability of predicting the output word $w_O$ given $w_I$, and therefore:\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nThis is accurate as presented in However, when $V$ is extremely large, calculating the denominator by going through all the words for every single sample is computationally impractical. The demand for more efficient conditional probability estimation leads to the new methods like\nhierarchical softmax\n.\nHierarchical Softmax\n#\nMorin and Bengio (\n2005\n) proposed hierarchical softmax to make the sum calculation faster with the help of a binary tree structure. The hierarchical softmax encodes the language model’s output softmax layer into a tree hierarchy, where each leaf is one word and each internal node stands for relative probabilities of the children nodes.\nAn illustration of the hierarchical softmax binary tree. The leaf nodes in white are words in the vocabulary. The gray inner nodes carry information on the probabilities of reaching its child nodes. One path starting from the root to the leaf $w\\_i$. $n(w\\_i, j)$ denotes the j-th node on this path. (Image source:\nword2vec Parameter Learning Explained\n)\nEach word $w_i$ has a unique path from the root down to its corresponding leaf. The probability of picking this word is equivalent to the probability of taking this path from the root down through the tree branches. Since we know the embedding vector $v_n$ of the internal node $n$, the probability of getting the word can be computed by the product of taking left or right turn at every internal node stop.\nAccording to Fig. 3, the probability of one node is ($\\sigma$ is the sigmoid function):\n$$\n\\begin{align}\np(\\text{turn right} \\to \\dots w_I \\vert n) &= \\sigma({v'_n}^{\\top} v_{w_I})\\\\\np(\\text{turn left } \\to \\dots w_I \\vert n) &= 1 - p(\\text{turn right} \\vert n) = \\sigma(-{v'_n}^{\\top} v_{w_I})\n\\end{align}\n$$\nThe final probability of getting a context word $w_O$ given an input word $w_I$ is:\n$$\np(w_O \\vert w_I) = \\prod_{k=1}^{L(w_O)} \\sigma(\\mathbb{I}_{\\text{turn}}(n(w_O, k), n(w_O, k+1)) \\cdot {v'_{n(w_O, k)}}^{\\top} v_{w_I})\n$$\nwhere $L(w_O)$ is the depth of the path leading to the word $w_O$ and $\\mathbb{I}_{\\text{turn}}$ is a specially indicator function which returns 1 if $n(w_O, k+1)$ is the left child of $n(w_O, k)$ otherwise -1. The internal nodes’ embeddings are learned during the model training. The tree structure helps greatly reduce the complexity of the denominator estimation from O(V) (vocabulary size) to O(log V) (the depth of the tree) at the training time. However, at the prediction time, we still to compute the probability of every word and pick the best, as we don’t know which leaf to reach for in advance.\nA good tree structure is crucial to the model performance. Several handy principles are: group words by frequency like what is implemented by Huffman tree for simple speedup; group similar words into same or close branches (i.e. use predefined word clusters, WordNet).\nCross Entropy\n#\nAnother approach completely steers away from the softmax framework. Instead, the loss function measures the cross entropy between the predicted probabilities $p$ and the true binary labels $\\mathbf{y}$.\nFirst, let’s recall that the cross entropy between two distributions $p$ and $q$ is measured as $ H(p, q) = -\\sum_x p(x) \\log q(x) $. In our case, the true label $y_i$ is 1 only when $w_i$ is the output word; $y_j$ is 0 otherwise. The loss function $\\mathcal{L}_\\theta$ of the model with parameter config $\\theta$ aims to minimize the cross entropy between the prediction and the ground truth, as lower cross entropy indicates high similarity between two distributions.\n$$\n\\mathcal{L}_\\theta = - \\sum_{i=1}^V y_i \\log p(w_i | w_I) = - \\log p(w_O \\vert w_I)\n$$\nRecall that,\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nTherefore,\n$$\n\\mathcal{L}_{\\theta} \n= - \\log \\frac{\\exp({v'_{w_O}}^{\\top}{v_{w_I}})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top}{v_{w_I} })}\n= - {v'_{w_O}}^{\\top}{v_{w_I} } + \\log \\sum_{i=1}^V \\exp({v'_{w_i} }^{\\top}{v_{w_I}})\n$$\nTo start training the model using back-propagation with SGD, we need to compute the gradient of the loss function. For simplicity, let’s label $z_{IO} = {v’_{w_O}}^{\\top}{v_{w_I}}$.\n$$\n\\begin{align}\n\\nabla_\\theta \\mathcal{L}_{\\theta}\n&= \\nabla_\\theta\\big( - z_{IO} + \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\ \n&= - \\nabla_\\theta z_{IO} + \\nabla_\\theta \\big( \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\\n&= - \\nabla_\\theta z_{IO} + \\frac{1}{\\sum_{i=1}^V e^{z_{Ii}}} \\sum_{i=1}^V e^{z_{Ii}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V \\frac{e^{z_{Ii}}}{\\sum_{i=1}^V e^{z_{Ii}}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V p(w_i \\vert w_I) \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta z_{Ii}\n\\end{align}\n$$\nwhere $Q(\\tilde{w})$ is the distribution of noise samples.\nAccording to the formula above, the correct output word has a positive reinforcement according to the first term (the larger $\\nabla_\\theta z_{IO}$ the better loss we have), while other words have a negative impact as captured by the second term.\nHow to estimate $\\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta {v’_{w_i}}^{\\top}{v_{w_I}}$ with a sample set of noise words rather than scanning through the entire vocabulary is the key of using cross-entropy-based sampling approach.\nNoise Contrastive Estimation (NCE)\n#\nThe Noise Contrastive Estimation (NCE) metric intends to differentiate the target word from noise samples using a logistic regression classifier (\nGutmann and Hyvärinen, 2010\n).\nGiven an input word $w_I$, the correct output word is known as $w$. In the meantime, we sample $N$ other words from the noise sample distribution $Q$, denoted as $\\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N \\sim Q$. Let’s label the decision of the binary classifier as $d$ and $d$$ can only take a binary value.\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) + \\sum_{i=1, \\tilde{w}_i \\sim Q}^N \\log p(d=0|\\tilde{w}_i, w_I) ]\n$$\nWhen $N$ is big enough, according to\nthe Law of large numbers\n,\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) +  N\\mathbb{E}_{\\tilde{w}_i \\sim Q} \\log p(d=0|\\tilde{w}_i, w_I)]\n$$\nTo compute the probability $p(d=1 \\vert w, w_I)$, we can start with the joint probability $p(d, w \\vert w_I)$. Among $w, \\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N$, we have 1 out of (N+1) chance to pick the true word $w$, which is sampled from the conditional probability $p(w \\vert w_I)$; meanwhile, we have N out of (N+1) chances to pick a noise word, each sampled from $q(\\tilde{w}) \\sim Q$. Thus,\n$$\np(d, w | w_I) = \n  \\begin{cases}\n  \\frac{1}{N+1} p(w \\vert w_I) & \\text{if } d=1 \\\\\n  \\frac{N}{N+1} q(\\tilde{w}) & \\text{if } d=0\n  \\end{cases}\n$$\nThen we can figure out $p(d=1 \\vert w, w_I)$ and $p(d=0 \\vert w, w_I)$:\n$$\n\\begin{align}\np(d=1 \\vert w, w_I) \n&= \\frac{p(d=1, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\n$$\n\\begin{align}\np(d=0 \\vert w, w_I) \n&= \\frac{p(d=0, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{Nq(\\tilde{w})}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\nFinally the loss function of NCE’s binary classifier becomes:\n$$\n\\begin{align}\n\\mathcal{L}_\\theta \n& = - [ \\log p(d=1 \\vert w, w_I) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log p(d=0|\\tilde{w}_i, w_I)] \\\\\n& = - [ \\log \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{p(w \\vert w_I) + Nq(\\tilde{w}_i)}]\n\\end{align}\n$$\nHowever, $p(w \\vert w_I)$ still involves summing up the entire vocabulary in the denominator. Let’s label the denominator as a partition function of the input word, $Z(w_I)$. A common assumption is $Z(w) \\approx 1$ given that we expect the softmax output layer to be normalized (\nMinh and Teh, 2012\n). Then the loss function is simplified to:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\frac{\\exp({v'_w}^{\\top}{v_{w_I}})}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w}_i)}]\n$$\nThe noise distribution $Q$ is a tunable parameter and we would like to design it in a way so that:\nintuitively it should be very similar to the real data distribution; and\nit should be easy to sample from.\nFor example, the sampling implementation (\nlog_uniform_candidate_sampler\n) of NCE loss in tensorflow assumes that such noise samples follow a log-uniform distribution, also known as\nZipfian’s law\n. The probability of a given word in logarithm is expected to be reversely proportional to its rank, while high-frequency words are assigned with lower ranks. In this case, $q(\\tilde{w}) = \\frac{1}{ \\log V}(\\log (r_{\\tilde{w}} + 1) - \\log r_{\\tilde{w}})$, where $r_{\\tilde{w}} \\in [1, V]$ is the rank of a word by frequency in descending order.\nNegative Sampling (NEG)\n#\nThe Negative Sampling (NEG) proposed by Mikolov et al. (\n2013\n) is a simplified variation of NCE loss. It is especially famous for training Google’s\nword2vec\nproject. Different from NCE Loss which attempts to approximately maximize the log probability of the softmax output, negative sampling did further simplification because it focuses on learning high-quality word embedding rather than modeling the word distribution in natural language.\nNEG approximates the binary classifier’s output with sigmoid functions as follows:\n$$\n\\begin{align}\np(d=1 \\vert w_, w_I) &= \\sigma({v'_{w}}^\\top v_{w_I}) \\\\\np(d=0 \\vert w, w_I) &= 1 - \\sigma({v'_{w}}^\\top v_{w_I}) = \\sigma(-{v'_{w}}^\\top v_{w_I})\n\\end{align}\n$$\nThe final NCE loss function looks like:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\sigma({v'_{w}}^\\top v_{w_I}) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\sigma(-{v'_{\\tilde{w}_i}}^\\top v_{w_I})]\n$$\nOther Tips for Learning Word Embedding\n#\nMikolov et al. (\n2013\n) suggested several helpful practices that could result in good word embedding learning outcomes.\nSoft sliding window\n. When pairing the words within the sliding window, we could assign less weight to more distant words. One heuristic is — given a maximum window size parameter defined, $s_{\\text{max}}$, the actual window size is randomly sampled between 1 and $s_{\\text{max}}$ for every training sample. Thus, each context word has the probability of 1/(its distance to the target word) being observed, while the adjacent words are always observed.\nSubsampling frequent words\n. Extremely frequent words might be too general to differentiate the context (i.e. think about stopwords). While on the other hand, rare words are more likely to carry distinct information. To balance the frequent and rare words, Mikolov et al. proposed to discard words $w$ with probability $1-\\sqrt{t/f(w)}$ during sampling. Here $f(w)$ is the word frequency and $t$ is an adjustable threshold.\nLearning phrases first\n. A phrase often stands as a conceptual unit, rather than a simple composition of individual words. For example, we cannot really tell “New York” is a city name even we know the meanings of “new” and “york”. Learning such phrases first and treating them as word units before training the word embedding model improves the outcome quality. A simple data-driven approach is based on unigram and bigram counts: $s_{\\text{phrase}} = \\frac{C(w_i w_j) - \\delta}{ C(w_i)C(w_j)}$, where $C(.)$ is simple count of an unigram $w_i$ or bigram $w_i w_j$ and $\\delta$ is a discounting threshold to prevent super infrequent words and phrases. Higher scores indicate higher chances of being phrases. To form phrases longer than two words, we can scan the vocabulary multiple times with decreasing score cutoff values.\nGloVe: Global Vectors\n#\nThe Global Vector (GloVe) model proposed by Pennington et al. (\n2014\n) aims to combine the count-based matrix factorization and the context-based skip-gram model together.\nWe all know the counts and co-occurrences can reveal the meanings of words. To distinguish from $p(w_O \\vert w_I)$ in the context of a word embedding word, we would like to define the co-ocurrence probability as:\n$$\np_{\\text{co}}(w_k \\vert w_i) = \\frac{C(w_i, w_k)}{C(w_i)}\n$$\n$C(w_i, w_k)$ counts the co-occurrence between words $w_i$ and $w_k$.\nSay, we have two words, $w_i$=“ice” and $w_j$=“steam”. The third word $\\tilde{w}_k$=“solid” is related to “ice” but not “steam”, and thus we expect $p_{\\text{co}}(\\tilde{w}_k \\vert w_i)$ to be much larger than $p_{\\text{co}}(\\tilde{w}_k \\vert w_j)$ and therefore $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ to be very large. If the third word $\\tilde{w}_k$ = “water” is related to both or $\\tilde{w}_k$ = “fashion” is unrelated to either of them, $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ is expected to be close to one.\nThe intuition here is that the word meanings are captured by the ratios of co-occurrence probabilities rather than the probabilities themselves. The global vector models the relationship between two words regarding to the third context word as:\n$$\nF(w_i, w_j, \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nFurther, since the goal is to learn meaningful word vectors, $F$ is designed to be a function of the linear difference between two words $w_i - w_j$:\n$$\nF((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nWith the consideration of $F$ being symmetric between target words and context words, the final solution is to model $F$ as an\nexponential\nfunction. Please read the original paper (\nPennington et al., 2014\n) for more details of the equations.\n$$\n\\begin{align}\nF({w_i}^\\top \\tilde{w}_k) &= \\exp({w_i}^\\top \\tilde{w}_k) = p_{\\text{co}}(\\tilde{w}_k \\vert w_i) \\\\\nF((w_i - w_j)^\\top \\tilde{w}_k) &= \\exp((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{\\exp(w_i^\\top \\tilde{w}_k)}{\\exp(w_j^\\top \\tilde{w}_k)} = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n\\end{align}\n$$\nFinally,\n$$\n{w_i}^\\top \\tilde{w}_k = \\log p_{\\text{co}}(\\tilde{w}_k \\vert w_i) = \\log \\frac{C(w_i, \\tilde{w}_k)}{C(w_i)} = \\log C(w_i, \\tilde{w}_k) - \\log C(w_i)\n$$\nSince the second term $-\\log C(w_i)$ is independent of $k$, we can add bias term $b_i$ for $w_i$ to capture $-\\log C(w_i)$. To keep the symmetric form, we also add in a bias $\\tilde{b}_k$ for $\\tilde{w}_k$.\n$$\n\\log C(w_i, \\tilde{w}_k) = {w_i}^\\top \\tilde{w}_k + b_i + \\tilde{b}_k\n$$\nThe loss function for the GloVe model is designed to preserve the above formula by minimizing the sum of the squared errors:\n$$\n\\mathcal{L}_\\theta = \\sum_{i=1, j=1}^V f(C(w_i,w_j)) ({w_i}^\\top \\tilde{w}_j + b_i + \\tilde{b}_j - \\log C(w_i, \\tilde{w}_j))^2\n$$\nThe weighting schema $f(c)$ is a function of the co-occurrence of $w_i$ and $w_j$ and it is an adjustable model configuration. It should be close to zero as $c \\to 0$; should be non-decreasing as higher co-occurrence should have more impact; should saturate when $c$ become extremely large. The paper proposed the following weighting function.\n$$\nf(c) = \n  \\begin{cases}\n  (\\frac{c}{c_{\\max}})^\\alpha & \\text{if } c < c_{\\max} \\text{, } c_{\\max} \\text{ is adjustable.} \\\\\n  1 & \\text{if } \\text{otherwise}\n  \\end{cases}\n$$\nExamples: word2vec on “Game of Thrones”\n#\nAfter reviewing all the theoretical knowledge above, let’s try a little experiment in word embedding extracted from “the Games of Thrones corpus”. The process is super straightforward using\ngensim\n.\nStep 1: Extract words\nimport\nsys\nfrom\nnltk.corpus\nimport\nstopwords\nfrom\nnltk.tokenize\nimport\nsent_tokenize\nSTOP_WORDS\n=\nset(stopwords\n.\nwords(\n'english'\n))\ndef\nget_words\n(txt):\nreturn\nfilter(\nlambda\nx: x\nnot\nin\nSTOP_WORDS,\nre\n.\nfindall(\nr\n'\\b(\\w+)\\b'\n, txt)\n)\ndef\nparse_sentence_words\n(input_file_names):\n\"\"\"Returns a list of a list of words. Each sublist is a sentence.\"\"\"\nsentence_words\n=\n[]\nfor\nfile_name\nin\ninput_file_names:\nfor\nline\nin\nopen(file_name):\nline\n=\nline\n.\nstrip()\n.\nlower()\nline\n=\nline\n.\ndecode(\n'unicode_escape'\n)\n.\nencode(\n'ascii'\n,\n'ignore'\n)\nsent_words\n=\nmap(get_words, sent_tokenize(line))\nsent_words\n=\nfilter(\nlambda\nsw: len(sw)\n>\n1\n, sent_words)\nif\nlen(sent_words)\n>\n1\n:\nsentence_words\n+=\nsent_words\nreturn\nsentence_words\n# You would see five .txt files after unzip 'a_song_of_ice_and_fire.zip'\ninput_file_names\n=\n[\n\"001ssb.txt\"\n,\n\"002ssb.txt\"\n,\n\"003ssb.txt\"\n,\n\"004ssb.txt\"\n,\n\"005ssb.txt\"\n]\nGOT_SENTENCE_WORDS\n=\nparse_sentence_words(input_file_names)\nStep 2: Feed a word2vec model\nfrom\ngensim.models\nimport\nWord2Vec\n# size: the dimensionality of the embedding vectors.\n# window: the maximum distance between the current and predicted word within a sentence.\nmodel\n=\nWord2Vec(GOT_SENTENCE_WORDS, size\n=\n128\n, window\n=\n3\n, min_count\n=\n5\n, workers\n=\n4\n)\nmodel\n.\nwv\n.\nsave_word2vec_format(\n\"got_word2vec.txt\"\n, binary\n=\nFalse\n)\nStep 3: Check the results\nIn the GoT word embedding space, the top similar words to “king” and “queen” are:\nmodel.most_similar('king', topn=10)\n(word, similarity with ‘king’)\nmodel.most_similar('queen', topn=10)\n(word, similarity with ‘queen’)\n(‘kings’, 0.897245)\n(‘cersei’, 0.942618)\n(‘baratheon’, 0.809675)\n(‘joffrey’, 0.933756)\n(‘son’, 0.763614)\n(‘margaery’, 0.931099)\n(‘robert’, 0.708522)\n(‘sister’, 0.928902)\n(’lords’, 0.698684)\n(‘prince’, 0.927364)\n(‘joffrey’, 0.696455)\n(‘uncle’, 0.922507)\n(‘prince’, 0.695699)\n(‘varys’, 0.918421)\n(‘brother’, 0.685239)\n(’ned’, 0.917492)\n(‘aerys’, 0.684527)\n(‘melisandre’, 0.915403)\n(‘stannis’, 0.682932)\n(‘robb’, 0.915272)\nCited as:\n@article{weng2017wordembedding,\n  title   = \"Learning word embedding\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-15-word-embedding/\"\n}\nReferences\n#\n[1] Tensorflow Tutorial\nVector Representations of Words\n.\n[2]\n“Word2Vec Tutorial - The Skip-Gram Model”\nby Chris McCormick.\n[3]\n“On word embeddings - Part 2: Approximating the Softmax”\nby Sebastian Ruder.\n[4] Xin Rong.\nword2vec Parameter Learning Explained\n[5] Mikolov, Tomas, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[6] Frederic Morin and Yoshua Bengio.\n“Hierarchical Probabilistic Neural Network Language Model.”\nAistats. Vol. 5. 2005.\n[7] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nProc. Intl. Conf. on Artificial Intelligence and Statistics. 2010.\n[8] Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Distributed representations of words and phrases and their compositionality.”\nAdvances in neural information processing systems. 2013.\n[9] Tomas Mikolov, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[10] Marco Baroni, Georgiana Dinu, and Germán Kruszewski.\n“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”\nACL (1). 2014.\n[11] Jeffrey Pennington, Richard Socher, and Christopher Manning.\n“Glove: Global vectors for word representation.”\nProc. Conf. on empirical methods in natural language processing (EMNLP). 2014.",
            "metadata": {
              "title": "Learning Word Embedding | Lil'Log",
              "description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "keywords": "nlp, language-model",
              "author": "Lilian Weng",
              "og:title": "Learning Word Embedding",
              "og:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
              "twitter:card": "summary",
              "twitter:title": "Learning Word Embedding",
              "twitter:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "article:section": "posts",
              "article:published_time": "2017-10-15T00:00:00+00:00",
              "article:modified_time": "2017-10-15T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/3e47ba682561/code/body-000.txt",
                "chars": 1066,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-001.txt",
                "chars": 323,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-002.txt",
                "chars": 233,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "bytes": 179202,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-e21a214c6127867b9495.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "bytes": 183003,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-0f5bdb5a435b843e8180.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "bytes": 18594,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-f369233bacf831326935.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://arxiv.org/pdf/1301.3781.pdf",
                "label": "Mikolov et al., 2013",
                "type": "a"
              },
              {
                "href": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "label": "2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1411.2738.pdf",
                "label": "word2vec Parameter Learning Explained",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "label": "Gutmann and Hyvärinen, 2010",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "the Law of large numbers",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "label": "Minh and Teh, 2012",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/candidate_sampling_ops.py",
                "label": "log_uniform_candidate_sampler",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Zipf%27s_law",
                "label": "Zipfian’s law",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "label": "2013",
                "type": "a"
              },
              {
                "href": "https://code.google.com/archive/p/word2vec/",
                "label": "word2vec",
                "type": "a"
              },
              {
                "href": "http://www.aclweb.org/anthology/D14-1162",
                "label": "2014",
                "type": "a"
              },
              {
                "href": "https://radimrehurek.com/gensim/models/word2vec.html",
                "label": "gensim",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/word2vec",
                "label": "Vector Representations of Words",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/",
                "label": "“Word2Vec Tutorial - The Skip-Gram Model”",
                "type": "a"
              },
              {
                "href": "http://ruder.io/word-embeddings-softmax/",
                "label": "“On word embeddings - Part 2: Approximating the Softmax”",
                "type": "a"
              },
              {
                "href": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "label": "“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:36Z",
            "source_url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3781.pdf",
                "bytes": 228716,
                "reused": false,
                "local_path": "papers/repair/1e8e84311c23b0346b07.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T18:04:55Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1411.2738.pdf",
                "bytes": 816833,
                "reused": false,
                "local_path": "papers/repair/b37b38f8ebbcb26bcb27.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "bytes": 633631,
                "reused": false,
                "local_path": "papers/repair/4e238b55e8eb6f9638d6.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "bytes": 332740,
                "reused": false,
                "local_path": "papers/repair/d0eae5ee0263039f0b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "bytes": 111997,
                "reused": false,
                "local_path": "papers/repair/32de112509f802883250.pdf"
              },
              {
                "status": "ok",
                "url": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "bytes": 152976,
                "reused": false,
                "local_path": "papers/repair/c28d8258a40dec5bef84.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25736,
            "expected_body_images": 3,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/3e47ba682561/pages/source.html",
            "local_html": "attachments/3e47ba682561/pages/article.html",
            "body_base_path": "attachments/3e47ba682561/pages/",
            "body_markdown_path": "attachments/3e47ba682561/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
          "status": "partial",
          "article_id": "1c9291c74af3",
          "local_path": "series-follow/1600/repair/7ed03d41ab2c6b4d9091.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
              "bytes": 2159899,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8571ab535bf08b3eb897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
              "bytes": 36779,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/244663c064863ba3add1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
              "bytes": 163006,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/417a080a721a8da35e76.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
              "bytes": 360658,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7a8e772d26ca2075d030.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
              "bytes": 329846,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a79121328d38f1e7decb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
              "bytes": 1061108,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/217a917d5b695d69920e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
              "bytes": 3290656,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/16ff0e0557cd1ec7183b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
              "bytes": 190907,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/68ed274d29e23ec04058.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
              "bytes": 20601,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f7ff47f8ed0c85c31c04.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
              "bytes": 194344,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d885b9f00fc903916eff.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
              "bytes": 236994,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/43b2947b31f475b9d117.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
              "bytes": 476899,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/202d6793b7b96d2f655a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
              "bytes": 401199,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/47a02b382f80dc9a2137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
              "bytes": 106503,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d314a0ab86b5abc9e45b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
              "bytes": 136297,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/5bee749c4008d551aef3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
              "bytes": 198560,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9686a8baee36d438f09c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
              "bytes": 376109,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7cfc826648a35a656e03.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
              "bytes": 485628,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4f9fa106ff81362212ba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
              "bytes": 124592,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3442cdcfc8a317d5e9cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
              "bytes": 392406,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d18eeaedd090128a06bf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
              "bytes": 3409897,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/82aaa856d170c7aa0cea.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Attention? Attention!",
            "keywords": "注意力机制,自注意力,多头",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "publish_date": "2018-06",
            "corpus_stage": "预训练/SFT",
            "notes": "注意力机制经典综述",
            "id": "1c9291c74af3",
            "collected_at": "2026-10-02T14:13:17",
            "title": "Attention? Attention! | Lil'Log",
            "body_markdown": "[Updated on 2018-10-28: Add\nPointer Network\nand the\nlink\nto my implementation of Transformer.]\n[Updated on 2018-11-06: Add a\nlink\nto the implementation of Transformer model.]\n[Updated on 2018-11-18: Add\nNeural Turing Machines\n.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the\nshow-attention-tell\npaper; moved it to\nSelf-Attention\nsection.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is\nhere\n.]\nAttention is, to some extent, motivated by how we pay visual attention to different regions of an image or correlate words in one sentence. Take the picture of a Shiba Inu in Fig. 1 as an example.\nA Shiba Inu in a men’s outfit. The credit of the original photo goes to Instagram\n@mensweardog\n.\nHuman visual attention allows us to focus on a certain region with “high resolution” (i.e. look at the pointy ear in the yellow box) while perceiving the surrounding image in “low resolution” (i.e. now how about the snowy background and the outfit?), and then adjust the focal point or do the inference accordingly. Given a small patch of an image, pixels in the rest provide clues what should be displayed there. We expect to see a pointy ear in the yellow box because we have seen a dog’s nose, another pointy ear on the right, and Shiba’s mystery eyes (stuff in the red boxes). However, the sweater and blanket at the bottom would not be as helpful as those doggy features.\nSimilarly, we can explain the relationship between words in one sentence or close context. When we see “eating”, we expect to encounter a food word very soon. The color term describes the food, but probably not so much with “eating” directly.\nOne word \"attends\" to other words in the same sentence differently.\nIn a nutshell, attention in deep learning can be broadly interpreted as a vector of importance weights: in order to predict or infer one element, such as a pixel in an image or a word in a sentence, we estimate using the attention vector how strongly it is correlated with (or “\nattends to\n” as you may have read in many papers) other elements and take the sum of their values weighted by the attention vector as the approximation of the target.\nWhat’s Wrong with Seq2Seq Model?\n#\nThe\nseq2seq\nmodel was born in the field of language modeling (\nSutskever, et al. 2014\n). Broadly speaking, it aims to transform an input sequence (source) to a new one (target) and both sequences can be of arbitrary lengths. Examples of transformation tasks include machine translation between multiple languages in either text or audio, question-answer dialog generation, or even parsing sentences into grammar trees.\nThe seq2seq model normally has an encoder-decoder architecture, composed of:\nAn\nencoder\nprocesses the input sequence and compresses the information into a context vector (also known as sentence embedding or “thought” vector) of a\nfixed length\n. This representation is expected to be a good summary of the meaning of the\nwhole\nsource sequence.\nA\ndecoder\nis initialized with the context vector to emit the transformed output. The early work only used the last state of the encoder network as the decoder initial state.\nBoth the encoder and decoder are recurrent neural networks, i.e. using\nLSTM or GRU\nunits.\nThe encoder-decoder model, translating the sentence \"she is eating a green apple\" to Chinese. The visualization of both encoder and decoder is unrolled in time.\nA critical and apparent disadvantage of this fixed-length context vector design is incapability of remembering long sentences. Often it has forgotten the first part once it completes processing the whole input. The attention mechanism was born (\nBahdanau et al., 2015\n) to resolve this problem.\nBorn for Translation\n#\nThe attention mechanism was born to help memorize long source sentences in neural machine translation (\nNMT\n). Rather than building a single context vector out of the encoder’s last hidden state, the secret sauce invented by attention is to create shortcuts between the context vector and the entire source input. The weights of these shortcut connections are customizable for each output element.\nWhile the context vector has access to the entire input sequence, we don’t need to worry about forgetting. The alignment between the source and target is learned and controlled by the context vector. Essentially the context vector consumes three pieces of information:\nencoder hidden states;\ndecoder hidden states;\nalignment between source and target.\nThe encoder-decoder model with additive attention mechanism in\nBahdanau et al., 2015\n.\nDefinition\n#\nNow let’s define the attention mechanism introduced in NMT in a scientific way. Say, we have a source sequence $\\mathbf{x}$ of length $n$ and try to output a target sequence $\\mathbf{y}$ of length $m$:\n$$\n\\begin{aligned}\n\\mathbf{x} &= [x_1, x_2, \\dots, x_n] \\\\\n\\mathbf{y} &= [y_1, y_2, \\dots, y_m]\n\\end{aligned}\n$$\n(Variables in bold indicate that they are vectors; same for everything else in this post.)\nThe encoder is a\nbidirectional RNN\n(or other recurrent network setting of your choice) with a forward hidden state $\\overrightarrow{\\boldsymbol{h}}_i$ and a backward one $\\overleftarrow{\\boldsymbol{h}}_i$. A simple concatenation of two represents the encoder state. The motivation is to include both the preceding and following words in the annotation of one word.\n$$\n\\boldsymbol{h}_i = [\\overrightarrow{\\boldsymbol{h}}_i^\\top; \\overleftarrow{\\boldsymbol{h}}_i^\\top]^\\top, i=1,\\dots,n\n$$\nThe decoder network has hidden state $\\boldsymbol{s}_t=f(\\boldsymbol{s}_{t-1}, y_{t-1}, \\mathbf{c}_t)$ for the output word at position t, $t=1,\\dots,m$, where the context vector $\\mathbf{c}_t$ is a sum of hidden states of the input sequence, weighted by alignment scores:\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\sum_{i=1}^n \\alpha_{t,i} \\boldsymbol{h}_i & \\small{\\text{; Context vector for output }y_t}\\\\\n\\alpha_{t,i} &= \\text{align}(y_t, x_i) & \\small{\\text{; How well two words }y_t\\text{ and }x_i\\text{ are aligned.}}\\\\\n&= \\frac{\\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_i))}{\\sum_{i'=1}^n \\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_{i'}))} & \\small{\\text{; Softmax of some predefined alignment score.}}.\n\\end{aligned}\n$$\nThe alignment model assigns a score $\\alpha_{t,i}$ to the pair of input at position i and output at position t, $(y_t, x_i)$, based on how well they match. The set of $\\{\\alpha_{t, i}\\}$ are weights defining how much of each source hidden state should be considered for each output. In Bahdanau’s paper, the alignment score $\\alpha$ is parametrized by a\nfeed-forward network\nwith a single hidden layer and this network is jointly trained with other parts of the model. The score function is therefore in the following form, given that tanh is used as the non-linear activation function:\n$$\n\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i])\n$$\nwhere both $\\mathbf{v}_a$ and $\\mathbf{W}_a$ are weight matrices to be learned in the alignment model.\nThe matrix of alignment scores is a nice byproduct to explicitly show the correlation between source and target words.\nAlignment matrix of \"L'accord sur l'Espace économique européen a été signé en août 1992\" (French) and its English translation \"The agreement on the European Economic Area was signed in August 1992\". (Image source: Fig 3 in\nBahdanau et al., 2015\n)\nCheck out this nice\ntutorial\nby Tensorflow team for more implementation instructions.\nA Family of Attention Mechanisms\n#\nWith the help of the attention, the dependencies between source and target sequences are not restricted by the in-between distance anymore! Given the big improvement by attention in machine translation, it soon got extended into the computer vision field (\nXu et al. 2015\n) and people started exploring various other forms of attention mechanisms (\nLuong, et al., 2015\n;\nBritz et al., 2017\n;\nVaswani, et al., 2017\n).\nSummary\n#\nBelow is a summary table of several popular attention mechanisms and corresponding alignment score functions:\nName\nAlignment score function\nCitation\nContent-base attention\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\text{cosine}[\\boldsymbol{s}_t, \\boldsymbol{h}_i]$\nGraves2014\nAdditive(*)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_{t-1}; \\boldsymbol{h}_i])$\nBahdanau2015\nLocation-Base\n$\\alpha_{t,i} = \\text{softmax}(\\mathbf{W}_a \\boldsymbol{s}_t)$\nNote: This simplifies the softmax alignment to only depend on the target position.\nLuong2015\nGeneral\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\mathbf{W}_a\\boldsymbol{h}_i$\nwhere $\\mathbf{W}_a$ is a trainable weight matrix in the attention layer.\nLuong2015\nDot-Product\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\boldsymbol{h}_i$\nLuong2015\nScaled Dot-Product(^)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\frac{\\boldsymbol{s}_t^\\top\\boldsymbol{h}_i}{\\sqrt{n}}$\nNote: very similar to the dot-product attention except for a scaling factor; where n is the dimension of the source hidden state.\nVaswani2017\n(*) Referred to as “concat” in Luong, et al., 2015 and as “additive attention” in Vaswani, et al., 2017.\n(^) It adds a scaling factor $1/\\sqrt{n}$, motivated by the concern when the input is large, the softmax function may have an extremely small gradient, hard for efficient learning.\nHere are a summary of broader categories of attention mechanisms:\nName\nDefinition\nCitation\nSelf-Attention(&)\nRelating different positions of the same input sequence. Theoretically the self-attention can adopt any score functions above, but just replace the target sequence with the same input sequence.\nCheng2016\nGlobal/Soft\nAttending to the entire input state space.\nXu2015\nLocal/Hard\nAttending to the part of input state space; i.e. a patch of the input image.\nXu2015\n;\nLuong2015\n(&) Also, referred to as “intra-attention” in Cheng et al., 2016 and some other papers.\nSelf-Attention\n#\nSelf-attention\n, also known as\nintra-attention\n, is an attention mechanism relating different positions of a single sequence in order to compute a representation of the same sequence. It has been shown to be very useful in machine reading, abstractive summarization, or image description generation.\nThe\nlong short-term memory network\npaper used self-attention to do machine reading. In the example below, the self-attention mechanism enables us to learn the correlation between the current words and the previous part of the sentence.\nThe current word is in red and the size of the blue shade indicates the activation level. (Image source:\nCheng et al., 2016\n)\nSoft vs Hard Attention\n#\nIn the\nshow, attend and tell\npaper, attention mechanism is applied to images to generate captions. The image is first encoded by a CNN to extract features. Then a LSTM decoder consumes the convolution features to produce descriptive words one by one, where the weights are learned through attention. The visualization of the attention weights clearly demonstrates which regions of the image the model is paying attention to so as to output a certain word.\n\"A woman is throwing a frisbee in a park.\" (Image source: Fig. 6(b) in\nXu et al. 2015\n)\nThis paper first proposed the distinction between “soft” vs “hard” attention, based on whether the attention has access to the entire image or only a patch:\nSoft\nAttention: the alignment weights are learned and placed “softly” over all patches in the source image; essentially the same type of attention as in\nBahdanau et al., 2015\n.\nPro\n: the model is smooth and differentiable.\nCon\n: expensive when the source input is large.\nHard\nAttention: only selects one patch of the image to attend to at a time.\nPro\n: less calculation at the inference time.\nCon\n: the model is non-differentiable and requires more complicated techniques such as variance reduction or reinforcement learning to train. (\nLuong, et al., 2015\n)\nGlobal vs Local Attention\n#\nLuong, et al., 2015\nproposed the “global” and “local” attention. The global attention is similar to the soft attention, while the local one is an interesting blend between\nhard and soft\n, an improvement over the hard attention to make it differentiable: the model first predicts a single aligned position for the current target word and a window centered around the source position is then used to compute a context vector.\nGlobal vs local attention (Image source: Fig 2 & 3 in\nLuong, et al., 2015\n)\nNeural Turing Machines\n#\nAlan Turing in\n1936\nproposed a minimalistic model of computation. It is composed of a infinitely long tape and a head to interact with the tape. The tape has countless cells on it, each filled with a symbol: 0, 1 or blank (\" “). The operation head can read symbols, edit symbols and move left/right on the tape. Theoretically a Turing machine can simulate any computer algorithm, irrespective of how complex or expensive the procedure might be. The infinite memory gives a Turing machine an edge to be mathematically limitless. However, infinite memory is not feasible in real modern computers and then we only consider Turing machine as a mathematical model of computation.\nHow a Turing machine looks like: a tape + a head that handles the tape. (Image source:\nhttp://aturingmachine.com/\n)\nNeural Turing Machine\n(\nNTM\n,\nGraves, Wayne & Danihelka, 2014\n) is a model architecture for coupling a neural network with external memory storage. The memory mimics the Turing machine tape and the neural network controls the operation heads to read from or write to the tape. However, the memory in NTM is finite, and thus it probably looks more like a “Neural\nvon Neumann\nMachine”.\nNTM contains two major components, a\ncontroller\nneural network and a\nmemory\nbank.\nController: is in charge of executing operations on the memory. It can be any type of neural network, feed-forward or recurrent.\nMemory: stores processed information. It is a matrix of size $N \\times M$, containing N vector rows and each has $M$ dimensions.\nIn one update iteration, the controller processes the input and interacts with the memory bank accordingly to generate output. The interaction is handled by a set of parallel\nread\nand\nwrite\nheads. Both read and write operations are “blurry” by softly attending to all the memory addresses.\nFig 10. Neural Turing Machine Architecture.\nReading and Writing\n#\nWhen reading from the memory at time t, an attention vector of size $N$, $\\mathbf{w}_t$ controls how much attention to assign to different memory locations (matrix rows). The read vector $\\mathbf{r}_t$ is a sum weighted by attention intensity:\n$$\n\\mathbf{r}_t = \\sum_{i=1}^N w_t(i)\\mathbf{M}_t(i)\\text{, where }\\sum_{i=1}^N w_t(i)=1, \\forall i: 0 \\leq w_t(i) \\leq 1\n$$\nwhere $w_t(i)$ is the $i$-th element in $\\mathbf{w}_t$ and $\\mathbf{M}_t(i)$ is the $i$-th row vector in the memory.\nWhen writing into the memory at time t, as inspired by the input and forget gates in LSTM, a write head first wipes off some old content according to an erase vector $\\mathbf{e}_t$ and then adds new information by an add vector $\\mathbf{a}_t$.\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{M}}_t(i) &= \\mathbf{M}_{t-1}(i) [\\mathbf{1} - w_t(i)\\mathbf{e}_t] &\\scriptstyle{\\text{; erase}}\\\\\n\\mathbf{M}_t(i) &= \\tilde{\\mathbf{M}}_t(i) + w_t(i) \\mathbf{a}_t &\\scriptstyle{\\text{; add}}\n\\end{aligned}\n$$\nAttention Mechanisms\n#\nIn Neural Turing Machine, how to generate the attention distribution $\\mathbf{w}_t$ depends on the addressing mechanisms: NTM uses a mixture of content-based and location-based addressings.\nContent-based addressing\nThe content-addressing creates attention vectors based on the similarity between the key vector $\\mathbf{k}_t$ extracted by the controller from the input and memory rows. The content-based attention scores are computed as cosine similarity and then normalized by softmax. In addition, NTM adds a strength multiplier $\\beta_t$ to amplify or attenuate the focus of the distribution.\n$$\nw_t^c(i) \n= \\text{softmax}(\\beta_t \\cdot \\text{cosine}[\\mathbf{k}_t, \\mathbf{M}_t(i)])\n= \\frac{\\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})}{\\sum_{j=1}^N \\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(j)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(j)\\|})}\n$$\nInterpolation\nThen an interpolation gate scalar $g_t$ is used to blend the newly generated content-based attention vector with the attention weights in the last time step:\n$$\n\\mathbf{w}_t^g = g_t \\mathbf{w}_t^c + (1 - g_t) \\mathbf{w}_{t-1} \n$$\nLocation-based addressing\nThe location-based addressing sums up the values at different positions in the attention vector, weighted by a weighting distribution over allowable integer shifts. It is equivalent to a 1-d convolution with a kernel $\\mathbf{s}_t(.)$, a function of the position offset. There are multiple ways to define this distribution. See for inspiration.\nTwo ways to represent the shift weighting distribution $\\mathbf{s}\\_t$.\nFinally the attention distribution is enhanced by a sharpening scalar $\\gamma_t \\geq 1$.\n$$\n\\begin{aligned}\n\\tilde{w}_t(i) &= \\sum_{j=1}^N w_t^g(j) s_t(i-j) & \\scriptstyle{\\text{; circular convolution}}\\\\\nw_t(i) &= \\frac{\\tilde{w}_t(i)^{\\gamma_t}}{\\sum_{j=1}^N \\tilde{w}_t(j)^{\\gamma_t}} & \\scriptstyle{\\text{; sharpen}}\n\\end{aligned}\n$$\nThe complete process of generating the attention vector $\\mathbf{w}_t$ at time step t is illustrated in All the parameters produced by the controller are unique for each head. If there are multiple read and write heads in parallel, the controller would output multiple sets.\nFlow diagram of the addressing mechanisms in Neural Turing Machine. (Image source:\nGraves, Wayne & Danihelka, 2014\n)\nPointer Network\n#\nIn problems like sorting or travelling salesman, both input and output are sequential data. Unfortunately, they cannot be easily solved by classic seq-2-seq or NMT models, given that the discrete categories of output elements are not determined in advance, but depends on the variable input size. The\nPointer Net\n(\nPtr-Net\n;\nVinyals, et al. 2015\n) is proposed to resolve this type of problems: When the output elements correspond to\npositions\nin an input sequence. Rather than using attention to blend hidden units of an encoder into a context vector (See Fig. 8), the Pointer Net applies attention over the input elements to pick one as the output at each decoder step.\nThe architecture of a Pointer Network model. (Image source:\nVinyals, et al. 2015\n)\nThe Ptr-Net outputs a sequence of integer indices, $\\boldsymbol{c} = (c_1, \\dots, c_m)$ given a sequence of input vectors $\\boldsymbol{x} = (x_1, \\dots, x_n)$ and $1 \\leq c_i \\leq n$. The model still embraces an encoder-decoder framework. The encoder and decoder hidden states are denoted as $(\\boldsymbol{h}_1, \\dots, \\boldsymbol{h}_n)$ and $(\\boldsymbol{s}_1, \\dots, \\boldsymbol{s}_m)$, respectively. Note that $\\mathbf{s}_i$ is the output gate after cell activation in the decoder. The Ptr-Net applies additive attention between states and then normalizes it by softmax to model the output conditional probability:\n$$\n\\begin{aligned}\ny_i &= p(c_i \\vert c_1, \\dots, c_{i-1}, \\boldsymbol{x}) \\\\\n    &= \\text{softmax}(\\text{score}(\\boldsymbol{s}_t; \\boldsymbol{h}_i)) = \\text{softmax}(\\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i]))\n\\end{aligned}\n$$\nThe attention mechanism is simplified, as Ptr-Net does not blend the encoder states into the output with attention weights. In this way, the output only responds to the positions but not the input content.\nTransformer\n#\n“Attention is All you Need”\n(Vaswani, et al., 2017), without a doubt, is one of the most impactful and interesting paper in 2017. It presented a lot of improvements to the soft attention and make it possible to do seq2seq modeling\nwithout\nrecurrent network units. The proposed “\ntransformer\n” model is entirely built on the self-attention mechanisms without using sequence-aligned recurrent architecture.\nThe secret recipe is carried in its model architecture.\nKey, Value and Query\n#\nThe major component in the transformer is the unit of\nmulti-head self-attention mechanism\n. The transformer views the encoded representation of the input as a set of\nkey\n-\nvalue\npairs, $(\\mathbf{K}, \\mathbf{V})$, both of dimension $n$ (input sequence length); in the context of NMT, both the keys and values are the encoder hidden states. In the decoder, the previous output is compressed into a\nquery\n($\\mathbf{Q}$ of dimension $m$) and the next output is produced by mapping this query and the set of keys and values.\nThe transformer adopts the\nscaled dot-product attention\n: the output is a weighted sum of the values, where the weight assigned to each value is determined by the dot-product of the query with all the keys:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{n}})\\mathbf{V}\n$$\nMulti-Head Self-Attention\n#\nMulti-head scaled dot-product attention mechanism. (Image source: Fig 2 in\nVaswani, et al., 2017\n)\nRather than only computing the attention once, the multi-head mechanism runs through the scaled dot-product attention multiple times in parallel. The independent attention outputs are simply concatenated and linearly transformed into the expected dimensions. I assume the motivation is because ensembling always helps? ;) According to the paper,\n“multi-head attention allows the model to jointly attend to information from different representation\nsubspaces\nat different positions. With a single attention head, averaging inhibits this.”\n$$\n\\begin{aligned}\n\\text{MultiHead}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) &= [\\text{head}_1; \\dots; \\text{head}_h]\\mathbf{W}^O \\\\\n\\text{where head}_i &= \\text{Attention}(\\mathbf{Q}\\mathbf{W}^Q_i, \\mathbf{K}\\mathbf{W}^K_i, \\mathbf{V}\\mathbf{W}^V_i)\n\\end{aligned}\n$$\nwhere $\\mathbf{W}^Q_i$, $\\mathbf{W}^K_i$, $\\mathbf{W}^V_i$, and $\\mathbf{W}^O$ are parameter matrices to be learned.\nEncoder\n#\nThe transformer’s encoder. (Image source:\nVaswani, et al., 2017\n)\nThe encoder generates an attention-based representation with capability to locate a specific piece of information from a potentially infinitely-large context.\nA stack of N=6 identical layers.\nEach layer has a\nmulti-head self-attention layer\nand a simple position-wise\nfully connected feed-forward network\n.\nEach sub-layer adopts a\nresidual\nconnection and a layer\nnormalization\n.\nAll the sub-layers output data of the same dimension $d_\\text{model} = 512$.\nDecoder\n#\nThe transformer’s decoder. (Image source:\nVaswani, et al., 2017\n)\nThe decoder is able to retrieval from the encoded representation.\nA stack of N = 6 identical layers\nEach layer has two sub-layers of multi-head attention mechanisms and one sub-layer of fully-connected feed-forward network.\nSimilar to the encoder, each sub-layer adopts a residual connection and a layer normalization.\nThe first multi-head attention sub-layer is\nmodified\nto prevent positions from attending to subsequent positions, as we don’t want to look into the future of the target sequence when predicting the current position.\nFull Architecture\n#\nFinally here is the complete view of the transformer’s architecture:\nBoth the source and target sequences first go through embedding layers to produce data of the same dimension $d_\\text{model} =512$.\nTo preserve the position information, a sinusoid-wave-based positional encoding is applied and summed with the embedding output.\nA softmax and linear layer are added to the final decoder output.\nThe full model architecture of the transformer. (Image source: Fig 1 & 2 in\nVaswani, et al., 2017\n.)\nTry to implement the transformer model is an interesting experience, here is mine:\nlilianweng/transformer-tensorflow\n. Read the comments in the code if you are interested.\nSNAIL\n#\nThe transformer has no recurrent or convolutional structure, even with the positional encoding added to the embedding vector, the sequential order is only weakly incorporated. For problems sensitive to the positional dependency like\nreinforcement learning\n, this can be a big problem.\nThe\nSimple Neural Attention\nMeta-Learner\n(\nSNAIL\n) (\nMishra et al., 2017\n) was developed partially to resolve the problem with\npositioning\nin the transformer model by combining the self-attention mechanism in transformer with\ntemporal convolutions\n. It has been demonstrated to be good at both supervised learning and reinforcement learning tasks.\nSNAIL model architecture (Image source:\nMishra et al., 2017\n)\nSNAIL was born in the field of meta-learning, which is another big topic worthy of a post by itself. But in simple words, the meta-learning model is expected to be generalizable to novel, unseen tasks in the similar distribution. Read\nthis\nnice introduction if interested.\nSelf-Attention GAN\n#\nSelf-Attention GAN\n(\nSAGAN\n;\nZhang et al., 2018\n) adds self-attention layers into\nGAN\nto enable both the generator and the discriminator to better model relationships between spatial regions.\nThe classic\nDCGAN\n(Deep Convolutional GAN) represents both discriminator and generator as multi-layer convolutional networks. However, the representation capacity of the network is restrained by the filter size, as the feature of one pixel is limited to a small local region. In order to connect regions far apart, the features have to be dilute through layers of convolutional operations and the dependencies are not guaranteed to be maintained.\nAs the (soft) self-attention in the vision context is designed to explicitly learn the relationship between one pixel and all other positions, even regions far apart, it can easily capture global dependencies. Hence GAN equipped with self-attention is expected to\nhandle details better\n, hooray!\nConvolution operation and self-attention have access to regions of very different sizes.\nThe SAGAN adopts the\nnon-local neural network\nto apply the attention computation. The convolutional image feature maps $\\mathbf{x}$ is branched out into three copies, corresponding to the concepts of\nkey, value, and query\nin the transformer:\nKey: $f(\\mathbf{x}) = \\mathbf{W}_f \\mathbf{x}$\nQuery: $g(\\mathbf{x}) = \\mathbf{W}_g \\mathbf{x}$\nValue: $h(\\mathbf{x}) = \\mathbf{W}_h \\mathbf{x}$\nThen we apply the dot-product attention to output the self-attention feature maps:\n$$\n\\begin{aligned}\n\\alpha_{i,j} &= \\text{softmax}(f(\\mathbf{x}_i)^\\top g(\\mathbf{x}_j)) \\\\\n\\mathbf{o}_j &= \\mathbf{W}_v \\Big( \\sum_{i=1}^N \\alpha_{i,j} h(\\mathbf{x}_i) \\Big)\n\\end{aligned}\n$$\nThe self-attention mechanism in SAGAN. (Image source: Fig. 2 in\nZhang et al., 2018\n)\nNote that $\\alpha_{i,j}$ is one entry in the attention map, indicating how much attention the model should pay to the $i$-th position when synthesizing the $j$-th location. $\\mathbf{W}_f$, $\\mathbf{W}_g$, and $\\mathbf{W}_h$ are all 1x1 convolution filters. If you feel that 1x1 conv sounds like a weird concept (i.e., isn’t it just to multiply the whole feature map with one number?), watch this short\ntutorial\nby Andrew Ng. The output $\\mathbf{o}_j$ is a column vector of the final output $\\mathbf{o}= (\\mathbf{o}_1, \\mathbf{o}_2, \\dots, \\mathbf{o}_j, \\dots, \\mathbf{o}_N)$.\nFurthermore, the output of the attention layer is multiplied by a scale parameter and added back to the original input feature map:\n$$\n\\mathbf{y} = \\mathbf{x}_i + \\gamma \\mathbf{o}_i\n$$\nWhile the scaling parameter $\\gamma$ is increased gradually from 0 during the training, the network is configured to first rely on the cues in the local regions and then gradually learn to assign more weight to the regions that are further away.\n128×128 example images generated by SAGAN for different classes. (Image source: Partial Fig. 6 in\nZhang et al., 2018\n)\nCited as:\n@article{weng2018attention,\n  title   = \"Attention? Attention!\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-06-24-attention/\"\n}\nReferences\n#\n[1]\n“Attention and Memory in Deep Learning and NLP.”\n- Jan 3, 2016 by Denny Britz\n[2]\n“Neural Machine Translation (seq2seq) Tutorial”\n[3] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio.\n“Neural machine translation by jointly learning to align and translate.”\nICLR 2015.\n[4] Kelvin Xu, Jimmy Ba, Ryan Kiros, Kyunghyun Cho, Aaron Courville, Ruslan Salakhudinov, Rich Zemel, and Yoshua Bengio.\n“Show, attend and tell: Neural image caption generation with visual attention.”\nICML, 2015.\n[5] Ilya Sutskever, Oriol Vinyals, and Quoc V. Le.\n“Sequence to sequence learning with neural networks.”\nNIPS 2014.\n[6] Thang Luong, Hieu Pham, Christopher D. Manning.\n“Effective Approaches to Attention-based Neural Machine Translation.”\nEMNLP 2015.\n[7] Denny Britz, Anna Goldie, Thang Luong, and Quoc Le.\n“Massive exploration of neural machine translation architectures.”\nACL 2017.\n[8] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[9] Jianpeng Cheng, Li Dong, and Mirella Lapata.\n“Long short-term memory-networks for machine reading.”\nEMNLP 2016.\n[10] Xiaolong Wang, et al.\n“Non-local Neural Networks.”\nCVPR 2018\n[11] Han Zhang, Ian Goodfellow, Dimitris Metaxas, and Augustus Odena.\n“Self-Attention Generative Adversarial Networks.”\narXiv preprint arXiv:1805.08318 (2018).\n[12] Nikhil Mishra, Mostafa Rohaninejad, Xi Chen, and Pieter Abbeel.\n“A simple neural attentive meta-learner.”\nICLR 2018.\n[13]\n“WaveNet: A Generative Model for Raw Audio”\n- Sep 8, 2016 by DeepMind.\n[14]  Oriol Vinyals, Meire Fortunato, and Navdeep Jaitly.\n“Pointer networks.”\nNIPS 2015.\n[15] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).",
            "metadata": {
              "title": "Attention? Attention! | Lil'Log",
              "description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "keywords": "architecture, attention, transformer, rnn",
              "author": "Lilian Weng",
              "og:title": "Attention? Attention!",
              "og:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
              "twitter:card": "summary",
              "twitter:title": "Attention? Attention!",
              "twitter:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "article:section": "posts",
              "article:published_time": "2018-06-24T00:00:00+00:00",
              "article:modified_time": "2018-06-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/1c9291c74af3/code/body-000.txt",
                "chars": 222,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "bytes": 2159899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-8571ab535bf08b3eb897.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "bytes": 36779,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-244663c064863ba3add1.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "bytes": 163006,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-417a080a721a8da35e76.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "bytes": 360658,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7a8e772d26ca2075d030.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "bytes": 329846,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-a79121328d38f1e7decb.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "bytes": 1061108,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-217a917d5b695d69920e.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "bytes": 3290656,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-16ff0e0557cd1ec7183b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "bytes": 190907,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-68ed274d29e23ec04058.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "bytes": 20601,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-f7ff47f8ed0c85c31c04.jpg",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d885b9f00fc903916eff.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "bytes": 236994,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-43b2947b31f475b9d117.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "bytes": 476899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-202d6793b7b96d2f655a.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "bytes": 401199,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-47a02b382f80dc9a2137.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d314a0ab86b5abc9e45b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "bytes": 136297,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-5bee749c4008d551aef3.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "bytes": 198560,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-9686a8baee36d438f09c.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7cfc826648a35a656e03.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "bytes": 485628,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-4f9fa106ff81362212ba.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "bytes": 124592,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-3442cdcfc8a317d5e9cd.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "bytes": 392406,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d18eeaedd090128a06bf.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "bytes": 3409897,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-82aaa856d170c7aa0cea.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/lilianweng/transformer-tensorflow",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03044",
                "label": "show-attention-tell",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://www.instagram.com/mensweardog/?hl=en",
                "label": "@mensweardog",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.3215",
                "label": "Sutskever, et al. 2014",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "LSTM or GRU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1409.0473.pdf",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/nlp-sequence-models/bidirectional-rnn-fyXnn",
                "label": "bidirectional RNN",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/versions/master/tutorials/seq2seq",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "label": "Xu et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.04025.pdf",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03906",
                "label": "Britz et al., 2017",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "Graves2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.4025.pdf",
                "label": "Luong2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1601.06733.pdf",
                "label": "Cheng2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.0473",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.04025",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Turing_machine",
                "label": "1936",
                "type": "a"
              },
              {
                "href": "http://aturingmachine.com/",
                "label": "http://aturingmachine.com/",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Von_Neumann_architecture",
                "label": "von Neumann",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.03134",
                "label": "Vinyals, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1512.03385.pdf",
                "label": "residual",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "http://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "Meta-Learner",
                "type": "a"
              },
              {
                "href": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "label": "Mishra et al., 2017",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/wavenet-generative-model-raw-audio/",
                "label": "temporal convolutions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1805.08318.pdf",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "DCGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1711.07971.pdf",
                "label": "non-local neural network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.08318",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/convolutional-neural-networks/networks-in-networks-and-1x1-convolutions-ZTb8x",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2016/01/attention-and-memory-in-deep-learning-and-nlp/",
                "label": "“Attention and Memory in Deep Learning and NLP.”",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/nmt",
                "label": "“Neural Machine Translation (seq2seq) Tutorial”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "label": "“Sequence to sequence learning with neural networks.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.03141",
                "label": "“A simple neural attentive meta-learner.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03044",
                "bytes": 9582640,
                "reused": false,
                "local_path": "papers/repair/cc9ae4c67126750bbe41.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.3215",
                "bytes": 112084,
                "reused": false,
                "local_path": "papers/repair/61d552395d0f0789263b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473.pdf",
                "bytes": 444482,
                "reused": false,
                "local_path": "papers/repair/ffb5ff16a013792114ac.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "bytes": 3126761,
                "reused": false,
                "local_path": "papers/repair/53e1470cf7704d6e3cb9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/dac4f1215a64e5bf890e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03906",
                "bytes": 305967,
                "reused": false,
                "local_path": "papers/repair/2864d7bf295692b04b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": false,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.4025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/538f66bff21c49b4a2af.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06733.pdf",
                "bytes": 2520829,
                "reused": false,
                "local_path": "papers/repair/eab5cb0dbe082766664e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473",
                "bytes": 444482,
                "reused": true,
                "local_path": "papers/repair/b6909588ff7b9ebf375f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025",
                "bytes": 249825,
                "reused": true,
                "local_path": "papers/repair/94d3d49016ad40753c67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.03134",
                "bytes": 469544,
                "reused": false,
                "local_path": "papers/repair/88d23cac0369adc66dcd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385.pdf",
                "bytes": 819383,
                "reused": false,
                "local_path": "papers/repair/984099b2816e5988dbb2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "retried_at": "2026-10-20T18:09:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318.pdf",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/09d96a257954f78287a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": false,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.07971.pdf",
                "bytes": 2853537,
                "reused": false,
                "local_path": "papers/repair/684df287e5824edb084a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/72f7e2aac2061b4b2acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "bytes": 142950,
                "reused": false,
                "local_path": "papers/repair/3cc5c95987280b914097.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.03141",
                "bytes": 1026799,
                "reused": false,
                "local_path": "papers/repair/75189519ab64f046e1aa.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29634,
            "expected_body_images": 21,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/1c9291c74af3/pages/source.html",
            "local_html": "attachments/1c9291c74af3/pages/article.html",
            "body_base_path": "attachments/1c9291c74af3/pages/",
            "body_markdown_path": "attachments/1c9291c74af3/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
          "status": "ok",
          "article_id": "dcd5da018bf2",
          "local_path": "series-follow/1600/repair/827224e799e103f1e0f7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
              "bytes": 106503,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9b7d412df1022e9dd836.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
              "bytes": 376109,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/25f0b2690092af605c3d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7d80cffa1089cf5d2768.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
              "bytes": 570814,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/df4282f24e52a002c1e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
              "bytes": 464230,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cab3cb57db5f98d84069.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
              "bytes": 420355,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0f97e3b0cd6e0f9d33d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
              "bytes": 128314,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ce9b993dcf304f3ee690.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
              "bytes": 49638,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/aea346be74eb04186d40.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
              "bytes": 92635,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/73a84b0003e99b52aabb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
              "bytes": 244624,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dcd62d1b6219e852f4e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/33280c015fb683b19da0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
              "bytes": 306995,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/14870bcbb3ef6e114eb5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/86a19bc020c6f7606039.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
              "bytes": 118602,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cc3c4b64a92e45404da4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a987ca8a4f296dda91fa.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family",
            "keywords": "Transformer,自注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "publish_date": "2020-04",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer家族综述（初版）",
            "id": "dcd5da018bf2",
            "collected_at": "2026-10-02T14:13:14",
            "title": "The Transformer Family | Lil'Log",
            "body_markdown": "[Updated on\n2023-01-27\n: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here:\nThe Transformer Family Version 2.0\n. Please refer to that post on this topic.]\nIt has been almost two years since my last post on\nattention\n. Recent progress on new and enhanced versions of Transformer motivates me to write another post on this specific topic, focusing on how the vanilla Transformer can be improved for longer-term attention span, less memory and computation consumption, RL task solving and more.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of length $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in the neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\mathbf{q}_i {\\mathbf{k}_j}^\\top)}{ \\sqrt{d_k} \\sum_{r \\in S_i} \\exp(\\mathbf{q}_i {\\mathbf{k}_r}^\\top) }\n$$\nSee my old\npost\nfor other types of attention if interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttention}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nTransformer\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nEncoder-Decoder Architecture\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\n(1)\nSinusoidal positional encoding\nis defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\n(2)\nLearned positional encoding\n, as its name suggested, assigns each element with a learned column vector which encodes its\nabsolute\nposition (\nGehring, et al. 2017\n).\nQuick Follow-ups\nFollowing the vanilla Transformer,\nAl-Rfou et al. (2018)\nadded a set of auxiliary losses to enable training a deep Transformer model on character-level language modeling which outperformed LSTMs. Several types of auxiliary tasks are used:\nInstead of producing only one prediction at the sequence end, every\nimmediate position\nis also asked to make a correct prediction, forcing the model to predict given smaller contexts (e.g. first couple tokens at the beginning of a context window).\nEach intermediate Transformer layer is used for making predictions as well. Lower layers are weighted to contribute less and less to the total loss as training progresses.\nEach position in the sequence can predict multiple targets, i.e. two or more predictions of the future tokens.\nAuxiliary prediction tasks used in deep Transformer for character-level language modeling. (Image source:\nAl-Rfou et al. (2018)\n)\nAdaptive Computation Time (ACT)\n#\nAdaptive Computation Time\n(short for\nACT\n;\nGraves, 2016\n) is a mechanism for dynamically deciding how many computational steps are needed in a recurrent neural network. Here is a cool\ntutorial\non ACT from distill.pub.\nLet’s say, we have a RNN model $\\mathcal{R}$ composed of input weights $W_x$, a parametric state transition function $\\mathcal{S}(.)$, a set of output weights $W_y$ and an output bias $b_y$. Given an input sequence $(x_1, \\dots, x_L)$, the output sequence $(y_1, \\dots, y_L)$ is computed by:\n$$\ns_t = \\mathcal{S}(s_{t-1}, W_x x_t), \\quad y_t = W_y s_t + b_y\\quad\\text{for }t=1, \\dots, L\n$$\nACT enables the above RNN setup to perform a variable number of steps at each input element. Multiple computational steps lead to a sequence of intermediate states $(s_t^1, \\dots, s_t^{N(t)})$ and outputs $(y_t^1, \\dots, y_t^{N(t)})$ — they all share the same state transition function $\\mathcal{S}(.)$, as well as the same output weights $W_y$ and bias $b_y$:\n$$\n\\begin{aligned}\ns_t^0 &= s_{t-1} \\\\\ns_t^n &= \\mathcal{S}(s_{t}^{n-1}, x_t^n) = \\mathcal{S}(s_{t}^{n-1}, x_t + \\delta_{n,1}) \\text{ for } n=1, \\dots, N(t)\\\\\ny_t^n &= W_y s_t^n + b_y\n\\end{aligned}\n$$\nwhere $\\delta_{n,1}$ is a binary flag indicating whether the input step has been incremented.\nThe number of steps $N(t)$ is determined by an extra sigmoidal halting unit $h$, with associated weight matrix $W_h$ and bias $b_h$, outputting a halting probability $p_t^n$ at immediate step $n$ for $t$-th input element:\n$$\nh_t^n = \\sigma(W_h s_t^n + b_h)\n$$\nIn order to allow the computation to halt after a single step, ACT introduces a small constant $\\epsilon$ (e.g. 0.01), so that whenever the cumulative probability goes above $1-\\epsilon$, the computation stops.\n$$\n\\begin{aligned}\nN(t) &= \\min(\\min\\{n': \\sum_{n=1}^{n'} h_t^n \\geq 1 -\\epsilon\\}, M) \\\\\np_t^n &= \\begin{cases}\nh_t^n & \\text{if }n < N(t) \\\\\nR(t) = 1 - \\sum_{n=1}^{N(t)-1} h_t^n & \\text{if }n= N(t)\\\\\n\\end{cases}\n\\end{aligned}\n$$\nwhere $M$ is an upper limit for the number of immediate steps allowed.\nThe final state and output are mean-field updates:\n$$\ns_t = \\sum_{n=1}^{N(t)} p_t^n s_t^n,\\quad y_t = \\sum_{n=1}^{N(t)} p_t^n y_t^n\n$$\nThe computation graph of a RNN with ACT mechanism. (Image source:\nGraves, 2016\n)\nTo avoid unnecessary pondering over each input, ACT adds a\nponder cost\n$\\mathcal{P}(x) = \\sum_{t=1}^L N(t) + R(t) $  in the loss function to encourage a smaller number of intermediate computational steps.\nImproved Attention Span\n#\nThe goal of improving attention span is to make the context that can be used in self-attention longer, more efficient and flexible.\nLonger Attention Span (Transformer-XL)\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments.\nThis\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) solves the context segmentation problem with two main modifications:\nReusing hidden states between segments.\nAdopting a new positional encoding that is suitable for reused states.\nHidden State Reuse\nThe recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both key and value rely on the extended hidden state, while the query only consumes hidden state at current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension.\nRelative Positional Encoding\nIn order to work with this new form of attention span, Transformer-XL proposed a new type of positional encoding. If using the same approach by vanilla Transformer and encoding the absolute position, the previous and current segments will be assigned with the same encoding, which is undesired.\nTo keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar, et al., (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 7) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys at positions $j \\in S_i$, where $S_i$ defineds the $i$-th token’s context window.\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clamp}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nLocalized Attention Span (Image Transformer)\n#\nThe original, also the most popular, use case for Transformer is to do language modeling. The text sequence is one-dimensional in a clearly defined chronological order and thus the attention span grows linearly with increased context size.\nHowever, if we want to use Transformer on images, it is unclear how to define the scope of context or the order.\nImage Transformer\n(\nParmer, et al 2018\n) embraces a formulation of image generation similar to sequence modeling within the Transformer framework. Additionally, Image Transformer restricts the self-attention span to only\nlocal\nneighborhoods, so that the model can scale up to process more images in parallel and keep the likelihood loss tractable.\nThe encoder-decoder architecture remains for image-conditioned generation:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThe decoder\nautoregressively\ngenerates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n(1)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n(2)\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nLess Time and Memory Cost\n#\nThis section introduces several improvements made on Transformer to reduce the computation time and memory consumption.\nSparse Attention Matrix Factorization (Sparse Transformers)\n#\nThe compute and memory cost of the vanilla Transformer grows quadratically with sequence length and thus it is hard to be applied on very long sequences.\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn anto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\n(1)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\nA_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n\\end{aligned}\n$$\n(2)\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\nA_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n\\end{aligned}\n$$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. => This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details.\nLocality-Sensitive Hashing (Reformer)\n#\nThe improvements proposed by the\nReformer\nmodel (\nKitaev, et al. 2020\n) aim to solve the following pain points in Transformer:\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nThe attention matrix on sequences of length $L$ often requires $O(L^2)$ in both memory and time.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $O(L^2)$ to $O(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 11:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nMake it Recurrent (Universal Transformer)\n#\nThe\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN.\nRather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{H}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{H}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{H}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{H}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{H}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses sinusoidal position signal but with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{H}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nStabilization for RL (GTrXL)\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Apr 2020). The transformer family. Lil’Log. https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/.\nOr\n@article{weng2020transformer,\n  title   = \"The Transformer Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Apr\",\n  url     = \"https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/\"\n}\nReference\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).",
            "metadata": {
              "title": "The Transformer Family | Lil'Log",
              "description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "keywords": "architecture, attention, transformer, foundation, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family",
              "og:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family",
              "twitter:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "article:section": "posts",
              "article:published_time": "2020-04-07T00:00:00+00:00",
              "article:modified_time": "2020-04-07T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/dcd5da018bf2/code/body-000.txt",
                "chars": 257,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-9b7d412df1022e9dd836.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-25f0b2690092af605c3d.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-7d80cffa1089cf5d2768.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "bytes": 570814,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-df4282f24e52a002c1e4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "bytes": 464230,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cab3cb57db5f98d84069.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-0f97e3b0cd6e0f9d33d1.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-ce9b993dcf304f3ee690.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-aea346be74eb04186d40.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-73a84b0003e99b52aabb.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-dcd62d1b6219e852f4e7.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-33280c015fb683b19da0.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-14870bcbb3ef6e114eb5.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-86a19bc020c6f7606039.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cc3c4b64a92e45404da4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-a987ca8a4f296dda91fa.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
                "label": "The Transformer Family Version 2.0",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08983",
                "label": "Graves, 2016",
                "type": "a"
              },
              {
                "href": "https://distill.pub/2016/augmented-rnns/",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar, et al., (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": true,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": true,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08983",
                "bytes": 6582868,
                "reused": false,
                "local_path": "papers/repair/b07529fb4c15758ccb0e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": true,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": true,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": true,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": true,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": true,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": true,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": true,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": true,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": true,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": true,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 36377,
            "expected_body_images": 15,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/dcd5da018bf2/pages/source.html",
            "local_html": "attachments/dcd5da018bf2/pages/article.html",
            "body_base_path": "attachments/dcd5da018bf2/pages/",
            "body_markdown_path": "attachments/dcd5da018bf2/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
          "status": "partial",
          "article_id": "2cf34df8cd69",
          "local_path": "series-follow/1600/repair/755e367caba0c679040a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
              "bytes": 661245,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7efefadad7e7dd1bd368.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
              "bytes": 173461,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ef8c4099815df32d696d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
              "bytes": 192230,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a2c96b21ecb7e2fe5261.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
              "bytes": 180723,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9d359913e38042c21f68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
              "bytes": 131727,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/658614a9a3e7c1d7b935.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
              "bytes": 337530,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/eaf24c5188513fae50ed.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
              "bytes": 124437,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ff31b70ac499e0b32939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
              "bytes": 865287,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2e1a4cd54853b0630bf6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
              "bytes": 553919,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7826a791054014f6fcfb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
              "bytes": 260572,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d37427b8abf7df28ba56.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
              "bytes": 198348,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1debd5c40323ec83577c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
              "bytes": 290218,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/76ae01d2ac36750aac13.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
              "bytes": 145311,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cb02352f1fcc5796b966.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
              "bytes": 201245,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4a06ae2c872925f426c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
              "bytes": 329545,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/592734de78cf202658cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
              "bytes": 244182,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f4f90d0aeb9507c08585.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Build an Open-Domain Question Answering System?",
            "keywords": "开放域问答,检索,ODQA",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "publish_date": "2020-10",
            "corpus_stage": "预训练/SFT",
            "notes": "开放域问答系统构建综述",
            "id": "2cf34df8cd69",
            "collected_at": "2026-10-02T14:13:11",
            "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
            "body_markdown": "[Updated on 2020-11-12: add\nan example\non closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.\nDisclaimers given so many papers in the wild:\nAssume we have access to a powerful pretrained\nlanguage model\n.\nWe do not cover how to use structured knowledge base (e.g. Freebase, WikiData) here.\nWe only focus on a single-turn QA instead of a multi-turn conversation style QA.\nWe mostly focus on QA models that contain neural networks, specially Transformer-based language models.\nI admit that I missed a lot of papers with architectures designed specifically for QA tasks between 2017-2019😔\nWhat is Open-Domain Question Answering?\n#\nOpen-domain Question Answering (ODQA)\nis a type of language tasks, asking a model to produce answers to factoid questions in natural language. The true answer is objective, so it is simple to evaluate model performance.\nFor example,\nQuestion: What did Albert Einstein win the Nobel Prize for?\nAnswer: The law of the photoelectric effect.\nThe “open-domain” part refers to the lack of the relevant context for any arbitrarily asked factual question. In the above case, the model only takes as the input the question but no article about “why Einstein didn’t win a Nobel Prize for the theory of relativity” is provided, where the term “the law of the photoelectric effect” is likely mentioned. In the case when both the question and the context are provided, the task is known as\nReading comprehension (RC)\n.\nAn ODQA model may work with or without\naccess to an external source of knowledge\n(e.g. Wikipedia) and these two conditions are referred to as\nopen-book\nor\nclosed-book\nquestion answering, respectively.\nWhen considering different types of open-domain questions, I like the classification by\nLewis, et al., 2020\n, in increasing order of difficulty:\nA model is able to correctly memorize and respond with the answer to a question that has been seen at training time.\nA model is able to answer novel questions at test time and choose an answer from the set of answers it has seen during training.\nA model is able to answer novel questions which have answers not contained in the training dataset.\nOverview of three frameworks discussed in this post.\nNotation\n#\nGiven a question $x$ and a ground truth answer span $y$, the context passage containing the true answer is labelled as $z \\in \\mathcal{Z}$, where $\\mathcal{Z}$ is an external knowledge corpus. Wikipedia is a common choice for such an external knowledge source.\nConcerns of QA data fine-tuning\n#\nBefore we dive into the details of many models below. I would like to point out one concern of fine-tuning a model with common QA datasets, which appears as one fine-tuning step in several ODQA models. It could be concerning, because there is a significant overlap between questions in the train and test sets in several public QA datasets.\nLewis, et al., (2020)\n(\ncode\n) found that 58-71% of test-time answers are also present somewhere in the training sets and 28-34% of test-set questions have a near-duplicate paraphrase in their corresponding training sets. In their experiments, several models performed notably worse when duplicated or paraphrased questions were removed from the training set.\nOpen-book QA: Retriever-Reader\n#\nGiven a factoid question, if a language model has no context or is not big enough to memorize the context which exists in the training dataset, it is unlikely to guess the correct answer. In an open-book exam, students are allowed to refer to external resources like notes and books while answering test questions. Similarly, a ODQA system can be paired with a rich knowledge base to identify relevant documents as evidence of answers.\nWe can decompose the process of finding answers to given questions into two stages,\nFind the related context in an external repository of knowledge;\nProcess the retrieved context to\nextract\nan answer.\nThe retriever-reader QA framework combines information retrieval with machine reading comprehension.\nSuch a retriever + reader framework was first proposed in\nDrQA\n(“Document retriever Question-Answering” by\nChen et al., 2017\n;\ncode\n). The retriever and the reader components can be set up and trained independently, or jointly trained\nend-to-end\n.\nRetriever Model\n#\nTwo popular approaches for implementing the retriever is to use the information retrieval (IR) system that depends on (1) the classic non-learning-based\nTF-IDF\nfeatures (“classic IR”) or (2) dense embedding vectors of text produced by neural networks (“neural IR”).\nClassic IR\n#\nDrQA\n(\nChen et al., 2017\n) adopts an efficient non-learning-based search engine based on the\nvector space model\n. Every query and document is modelled as a bag-of-word vector, where each term is weighted by TF-IDF (term frequency $\\times$ inverse document frequency).\n$$\n\\begin{aligned}\n\\text{tf-idf}(t, d, \\mathcal{D}) &= \\text{tf}(t, d) \\times \\text{idf}(t, \\mathcal{D}) \\\\\n\\text{tf}(t, d) &= \\log(1 + \\text{freq}(t, d)) \\\\\n\\text{idf}(t, \\mathcal{D}) &= \\log \\Big( \\frac{\\vert\\mathcal{D}\\vert}{\\vert d\\in\\mathcal{D}: t\\in d\\vert} \\Big)\n\\end{aligned}\n$$\nwhere $t$ is a unigram or bigram term in a document $d$ from a collection of documents $\\mathcal{D}$ . $\\text{freq}(t, d)$ measures how many times a term $t$ appears in $d$. Note that the term-frequency here includes bigram counts too, which is found to be very helpful because the local word order is taken into consideration via bigrams. As part of the implementation, DrQA maps the bigrams of $2^{24}$ bins using unsigned murmur3 hash.\nPrecisely, DrQA implemented Wikipedia as its knowledge source and this choice has became a default setting for many ODQA studies since then. The non-ML document retriever returns the top $k=5$ most relevant Wikipedia articles given a question.\nBERTserini\n(\nYang et al., 2019\n) pairs the open-source\nAnserini\nIR toolkit as the retriever with a fine-tuned pre-trained BERT model as the reader. The top $k$ documents ($k=10$) are retrieved via the\npost-v3.0\nbranch of Anserini with the query treated as a bag of words. The retrieved text segments are ranked by\nBM25\n, a classic TF-IDF-based retrieval scoring function. In terms of the effect of text granularity on performance, they found that paragraph retrieval > sentence retrieval > article retrieval.\nAn illustration of BERTserini architecture. (Image source:\nYang et al., 2019\n)\nElasticSearch + BM25\nis used by the\nMulti-passage BERT\nQA model (\nWang et al., 2019\n). They found that splitting articles into passages with the length of 100 words by\nsliding window\nbrings 4% improvements, since splitting documents into passages without overlap may cause some near-boundary evidence to lose useful contexts.\nNeural IR\n#\nThere is a long history in learning a low-dimensional representation of text, denser than raw term-based vectors (\nDeerwester et al., 1990\n;\nYih, et al., 2011\n). Dense representations can be learned through matrix decomposition or some neural network architectures (e.g. MLP, LSTM, bidirectional LSTM, etc). When involving neural networks, such approaches are referred to as “Neural IR”, Neural IR is a new category of methods for retrieval problems, but it is not necessary to perform better/superior than classic IR (\nLim, 2018\n).\nAfter the success of many large-scale\ngeneral language models\n, many QA models embrace the following approach:\n$$\nh_x = E_x(x)\\quad\nh_z = E_z(z)\\quad\n\\text{score}(x, z) = h_x^\\top h_z\n$$\nExtract the dense representations of a question $x$ and a context passage $z$ by feeding them into a language model;\nUse the dot-product of these two representations as the retrieval score to rank and select most relevant passages.\nORQA, REALM and DPR all use such a scoring function for context retrieval, which will be described in detail in a\nlater section\non the end-to-end QA model.\nAn extreme approach, investigated by\nDenSPI\n(“Dense-Sparse Phrase Index”;\nSeo et al., 2019\n), is to encode all the text in the knowledge corpus at the\nphrase\nlevel and then only rely on the retriever to identify the most relevant phrase as the predicted answer. In this way, the retriever+reader pipeline is reduced to only retriever. Of course, the index would be much larger and the retrieval problem is more challenging.\nDenSPI introduces a\nquery-agnostic\nindexable representation of document phrases. Precisely it encodes query-agnostic representations of text spans in Wikipedia offline and looks for the answer at inference time by performing nearest neighbor search. It can drastically speed up the inference time, because there is no need to re-encode documents for every new query, which is often required by a reader model.\nGiven a question $x$ and a fixed set of (Wikipedia) documents, $z_1, \\dots, z_K$ and each document $z_k$ contains $N_k$ words, $z_k = \\langle z_k^{(1)}, \\dots, z_k^{(N_k)}\\rangle$. An ODQA model is a scoring function $F$ for each candidate phrase span $z_k^{(i:j)}, 1 \\leq i \\leq j \\leq N_k$, such that the truth answer is the phrase with maximum score: $y = {\\arg\\max}_{k,i,j} F(x, z_k^{(i:j)})$.\nThe phrase representation $z_k^{(i:j)}$ combines both dense and sparse vectors, $z_k^{(i:j)} = [d_k^{(i:j)}, s_k^{(i:j)}] \\in \\mathbb{R}^{d^d + d^s}$ (note that $d^d \\ll d^s$):\nThe dense vector $d_k^{(i:j)}$ is effective for encoding local\nsyntactic\nand\nsemantic\ncues, as what can be learned by a pretrained language model.\nThe sparse vector $s_k^{(i:j)}$ is superior at encoding precise\nlexical\ninformation. The sparse vector is term-frequency-based encoding. DenSPI uses 2-gram term-frequency same as DrQA, resulting a highly sparse representation ($d^s \\approx 16$M)\nThe dense vector $d^{(i:j)}$ is further decomposed into three parts, $d^{(i:j)} = [a_i, b_j, c_{ij}] \\in \\mathbb{R}^{2d^b + 1}$ where $2d^b + 1 = d^d$. All three components are learned based on different columns of the fine-tuned BERT representations.\nA vector $a_i$ encodes the\nstart\nposition for the $i$-th word of the document;\nA vector $b_j$ encodes the\nend\nposition for the $j$-th word of the document;\nA scalar $c_{ij}$ measures the\ncoherency\nbetween the start and the end vectors, helping avoid non-constituent phrases during inference.\nFor all possible $(i,j,k)$ tuples where $j-i < J$, the text span embeddings are precomputed and stored as a\nphrase index\n. The maximum span length $J$ is a predefined scalar constant.\nAn illustration of Dense-Sparse Phrase Index (DenSPI) architecture. (Image source:\nSeo et al., 2019\n)\nAt the inference time, the question is mapped into the same vector space $x=[d’, s’] \\in \\mathbb{R}^{d^d + d^s}$, where the dense vector $d’$ is extracted from the BERT embedding of the special\n[CLS]\nsymbol. The same BERT model is shared for encoding both questions and phrases. The final answer is predicted by $k^*, i^*, j^* = \\arg\\max x^\\top z_k^{(i:j)}$.\nReader Model\n#\nThe reader model learns to solve the reading comprehension task — extract an answer for a given question from a given context document. Here we only discuss approaches for machine comprehension using neural networks.\nBi-directional LSTM\n#\nThe reader model for answer detection of\nDrQA\n(\nChen et al., 2017\n) is a 3-layer bidirectional LSTM with hidden size 128. Every relevant paragraph of retrieved Wikipedia articles is encoded by a sequence of feature vector, $\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m \\}$. Each feature vector $\\hat{\\mathbf{z}}_i \\in \\mathbb{R}^{d_z}$ is expected to capture useful contextual information around one token $z_i$. The feature consists of several categories of features:\nWord embeddings: A 300d\nGlove\nword embedding trained from 800B Web crawl data, $f_\\text{embed} = E_g(z_i)$.\nExact match: Whether a word $z_i$ appears in the question $x$, $f_\\text{match} = \\mathbb{I}(z_i \\in x)$.\nToken features: This includes POS (part-of-speech) tagging, NER (named entity recognition), and TF (term-frequency), $f_\\text{token}(z_i) = (\\text{POS}(z_i), \\text{NER}(z_i), \\text{TF}(z_i))$.\nAligned question embedding: The attention score $y_{ij}$ is designed to capture inter-sentence matching and similarity between the paragraph token $z_i$ and the question word $x_j$. This feature adds soft alignments between similar but non-identical words.\n$$\n\\begin{aligned}\nf_\\text{align}(z_i) &= \\sum_j y_{i,j} E_g(x_j) \\\\ \ny_{i,j} &= \\frac{\\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_j)) )}{\\sum_{j'} \\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_{j'})) ) }\n\\end{aligned}\n$$\nwhere $\\alpha$ is a single dense layer with ReLU and $E_g(.)$ is the glove word embedding.\nThe feature vector of a paragraph of $m$ tokens is fed into LSTM to obtain the final paragraph vectors:\n$$\n\\begin{aligned}\n\\mathbf{z} = \\{\\mathbf{z}_1, \\dots, \\mathbf{z}_m\\} &= \\text{LSTM}(\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m\\}) \\\\\n\\text{where } \\tilde{\\mathbf{z}}_i &= \\{f_\\text{embed}, f_\\text{match}, f_\\text{token}, f_\\text{align}\\}\n\\end{aligned}\n$$\nThe question is encoded as a weighted sum of the embeddings of every word in the question:\n$$\n\\mathbf{x} = \\sum_j b_j E(x_j) \\quad b_j = \\text{softmax}(\\mathbf{w}^\\top E(x_j))\n$$\nwhere $\\mathbf{w}$ is a weight vector to learn.\nOnce the feature vectors are constructed for the question and all the related paragraphs, the reader needs to predict the probabilities of each position in a paragraph to be the start and the end of an answer span, $p_\\text{start}(i_s)$ and $p_\\text{end}(i_s)$, respectively. Across all the paragraphs, the optimal span is returned as the final answer with maximum $p_\\text{start}(i_s)  \\times p_\\text{end}(i_e) $.\n$$\n\\begin{aligned}\np_\\text{start}(i_s) \\propto \\exp(\\mathbf{z}_{i_s} \\mathbf{W}_s \\mathbf{x}) \\\\ \np_\\text{end}(i_e) \\propto \\exp(\\mathbf{z}_{i_e} \\mathbf{W}_e \\mathbf{x}) \\\\\n\\text{ s.t. } i_s \\leq i_e \\leq i_s + 15\n\\end{aligned}\n$$\nwhere $\\mathbf{W}_s$ and $\\mathbf{W}_e$ are learned parameters.\nBERT-universe\n#\nFollowing the success of\nBERT\n(\nDevlin et al., 2018\n), many QA models develop the machine comprehension component based on BERT. Let’s define the BERT model as a function that can take one or multiple strings (concatenated by\n[SEP]\n) as input and outputs a set of BERT encoding vectors for the special\n[CLS]\ntoken and every input token:\n$$\n\\text{BERT}(s_1, s_2, \\dots) = [\\mathbf{h}^\\texttt{[CLS]}, \\mathbf{h}^{(1)}, \\mathbf{h}^{(2)}, \\dots]\n$$\nwhere $\\mathbf{h}^\\texttt{[CLS]}$ is the embedding vector for the special\n[CLS]\ntoken and $\\mathbf{h}^{(i)}$ is the embedding vector for the $i$-th token.\nTo use BERT for reading comprehension, it learns two additional weights, $\\mathbf{W}_s$ and $\\mathbf{W}_e$, and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_s)$ and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_e)$ define two probability distributions of start and end position of the predicted span per token.\nBERTserini\n(\nYang et al., 2019\n) utilizes a pre-trained BERT model to work as the reader. Their experiments showed that\nfine-tuning\npretrained BERT with SQuAD is sufficient to achieve high accuracy in identifying answer spans.\nHow BERT is used to solve question-answering tasks. (Image source:\nDevlin et al., 2018\n)\nThe key difference of the BERTserini reader from the original BERT is: to allow comparison and aggregation of results from different segments, the final softmax layer over different answer spans is removed. The pre-trained BERT model is fine-tuned on the training set of SQuAD, where all inputs to the reader are padded to 384 tokens with the learning rate 3e-5.\nWhen ranking all the extracted answer spans, the retriever score (BM25) and the reader score (probability of token being the start position $\\times$ probability of the same token being the end position ) are combined via linear interpolation.\nThe original BERT normalizes the probability distributions of start and end position per token for every passage independently. Differently, the\nMulti-passage BERT\n(\nWang et al., 2019\n) normalizes answer scores across all the retrieved passages of one question\nglobally\n. Precisely, multi-passage BERT removes the final normalization layer per passage in BERT for QA (same as in BERTserini) and then adds a global\nsoftmax\nover all the word positions of all the passages. Global normalization makes the reader model more stable while pin-pointing answers from a large number of passages.\nIn addition, multi-passage BERT implemented an independent\npassage ranker\nmodel via another BERT model and the rank score for $(x, z)$ is generated by a\nsoftmax\nover the representation vectors of the first\n[CLS]\ntoken. The passage ranker brings in extra 2% improvements. Similar idea of re-ranking passages with BERT was discussed in\nNogueira & Cho, 2019\n, too.\nInterestingly,\nWang et al., 2019\nfound that\nexplicit inter-sentence matching\ndoes not seem to be critical for RC tasks with BERT; check the original paper for how the experiments were designed. One possible reason is that the multi-head self-attention layers in BERT has already embedded the inter-sentence matching.\nEnd-to-end Joint Training\n#\nThe retriever and reader components can be jointly trained. This section covers R^3, ORQA, REALM and DPR. There are a lot of common designs, such as BERT-based dense vectors for retrieval and the loss function on maximizing the marginal likelihood of obtaining true answers.\nThe retriever and reader models in the\nR^3\n(“Reinforced Ranker-Reader”;\nWang, et al., 2017\n) QA system are jointly trained via\nreinforcement learning\n. (Note that to keep the term consistent between papers in this section, the “ranker” model in the original R^3 paper is referred to as the “retriever” model here.) Both components are variants of\nMatch-LSTM\n, which relies on an attention mechanism to compute word similarities between the passage and question sequences.\nHow does the Match-LSTM module work?\nGiven a question $\\mathbf{X}$ of $d_x$ words and a passage $\\mathbf{Z}$ of $d_z$ words, both representations use fixed\nGlove\nword embeddings,\n$$\n\\begin{aligned}\n\\mathbf{H}^x &= \\text{BiLSTM}(\\mathbf{X}) \\in \\mathbb{R}^{l \\times d_x} \\\\\n\\mathbf{H}^z &= \\text{BiLSTM}(\\mathbf{Z}) \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{G} &= \\text{softmax}((\\mathbf{W}^g \\mathbf{H}^x + \\mathbf{b}^g \\otimes \\mathbf{e}_{d_x})^\\top \\mathbf{H}^z) \\in \\mathbb{R}^{d_x \\times d_z} & \\text{; an attention matrix}\\\\\n\\bar{\\mathbf{H}}^x &= \\mathbf{H}^x \\mathbf{G} \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{M} &= \\text{ReLU} \\Big( \\mathbf{W}^m \\begin{bmatrix}\n\\mathbf{H}^z \\\\\n\\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z \\odot \\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z - \\bar{\\mathbf{H}}^x\n\\end{bmatrix} \\Big) \\in \\mathbb{R}^{2l \\times d_z} \\\\\n\\mathbf{H}^m &= \\text{BiLSTM}(M) \\in \\mathbb{R}^{l \\times d_z}\n\\end{aligned}\n$$\nwhere $l$ is the hidden dimension of the bidirectional LSTM module. $\\mathbf{W}^g \\in \\mathbb{R}^{l\\times l}$, $\\mathbf{b}^g \\in \\mathbb{R}^l$, and $\\mathbf{W}^m \\in \\mathbb{R}^{2l \\times 4l}$ are parameters to learn. The operator $\\otimes \\mathbf{e}_{d_x}$ is the outer product to repeat the column vector $\\mathbf{b}^g$ $d_x$ times.\nThe ranker and reader components share the same Match-LSTM module with two separate prediction heads in the last layer, resulting in $\\mathbf{H}^\\text{rank}$ and $\\mathbf{H}^\\text{reader}$.\nThe overview of R^3 (reinforced ranker-reader) architecture. Both components share the same Match-LSTM module. (Image source:\nWang, et al., 2017\n)\nThe retriever runs a max-pooling operation per passage and then aggregates to output a probability of each passage entailing the answer.\n$$\n\\begin{aligned}\n\\mathbf{u}_i &= \\text{max-pooling}(\\mathbf{H}^\\text{rank}_i) \\in \\mathbb{R}^l \\\\\n\\mathbf{C} &= \\text{tanh}(\\mathbf{W}^c[\\mathbf{u}_1;\\dots;\\mathbf{u}_N] + \\mathbf{b}^c \\otimes \\mathbf{e}_N) \\in \\mathbb{R}^{l \\times n} \\\\\n\\gamma &= \\text{softmax}(\\mathbf{w}^c \\mathbf{C}) \\in \\mathbb{R}^n\n\\end{aligned}\n$$\nFinally, the retriever is viewed as a\npolicy\nto output action to sample a passage according to predicted $\\gamma$,\n$$\n\\pi(z \\vert x; \\theta^\\gamma) = \\gamma_z\n$$\nThe reader predicts the start position $\\beta^s$ and the end position $\\beta^e$ of the answer span. Two positions are computed in the same way, with independent parameters to learn. There are $V$ words in all the passages involved.\n$$\n\\begin{aligned}\n\\mathbf{H}^\\text{read} &= [\\mathbf{H}^\\text{read}_\\tau; \\mathbf{H}^\\text{read}_{\\text{neg}_1}; \\dots; \\mathbf{H}^\\text{read}_{\\text{neg}_n}] \\\\\n\\mathbf{F}^s &= \\text{tanh}(\\mathbf{W}^s \\mathbf{H}^\\text{read} + \\mathbf{b}^s \\otimes \\mathbf{e}_V) \\quad\n\\beta^s = \\text{softmax}(\\mathbf{w}^s \\mathbf{F}^s) \\in \\mathbb{R}^V \\\\\n\\mathbf{F}^e &= \\text{tanh}(\\mathbf{W}^e \\mathbf{H}^\\text{read} + \\mathbf{b}^e \\otimes \\mathbf{e}_V) \\quad\n\\beta^e = \\text{softmax}(\\mathbf{w}^e \\mathbf{F}^e) \\in \\mathbb{R}^V \\\\\nL(y \\vert z, x) &= -\\log(\\beta^s_{y_z^s})-\\log(\\beta^e_{y_z^e})\n\\end{aligned}\n$$\nwhere $y$ is the ground-truth answer and the passage $z$ is sampled by the retriever. $\\beta^s_{y_z^s}$ and $\\beta^s_{y_z^e}$ represent the probabilities of the start and end positions of $y$ in passage $z$.\nThe training objective for the end-to-end R^3 QA system is to minimize the negative log-likelihood of obtaining the correct answer $y$ given a question $x$,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= -\\mathbb{E}_{z\\sim\\pi(.\\vert x)} [L(y \\vert z, x)] \\\\\n\\nabla \\mathcal{J}(\\theta) \n&= - \\nabla_\\theta \\sum_z \\pi(z \\vert x) L(y \\vert z, x) \\\\\n&= - \\sum_z \\big( L(y \\vert z, x) \\nabla_\\theta\\pi(z \\vert x) + \\pi(z \\vert x) \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&= - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\color{red}{L(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)} + \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&\\approx - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\underbrace{\\color{red}{R(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)}}_\\text{REINFORCE} + \\nabla_\\theta L(y \\vert z, x) \\big)\n\\end{aligned}\n$$\nEssentially in training, given a passage $z$ sampled by the retriever, the reader is trained by gradient descent while the retriever is trained by\nREINFORCE\nusing $L(y \\vert z, x)$ as the reward function. However, $L(y \\vert z, x)$ is not bounded and may introduce a lot of variance. The paper replaces the reward with a customized scoring function by comparing the ground truth $y$ and the answer extracted by the reader $\\hat{y}$:\n$$\nR(y, \\hat{y} \\vert z) = \\begin{cases}\n2 & \\text{if } y = \\hat{y}\\\\\nf1(y, \\hat{y}) & \\text{if } y \\cap \\hat{y} = \\varnothing \\\\\n-1 & \\text{otherwise}\n\\end{cases}\n$$\nThe workflow of R^3 training process. (Image source:\nacl2020-openqa-tutorial/slides/part4\n)\nORQA\n(“Open-Retrieval Question-Answering”;\nLee et al., 2019\n) jointly learns a retriever + reader QA model to optimize marginal log-likelihood of obtaining correct answers in a supervised manner. No explicit “black-box” IR system is involved. Instead, it is capable of retrieving any text in an open corpus. During training, ORQA does not need ground-truth context passages (i.e. reading comprehension datasets) but only needs (question, answer) string pairs. Both retriever and reader components are based on BERT, but not shared.\nAn illustration of the retriever component in ORQA. (Image source: replotted based on one slide in\nacl2020-openqa-tutorial/slides/part5\n)\nAll the evidence blocks are ranked by a retrieval score, defined as the inner product of BERT embedding vectors of the\n[CLS]\ntoken of the question $x$ and the evidence block $z$. Note that the encoders for questions and context are independent.\n$$\n\\begin{aligned}\nh_x &= \\mathbf{W}_x \\text{BERT}_x(x)^{\\mathtt{[CLS]}} \\\\\nh_z &= \\mathbf{W}_z \\text{BERT}_z(z)^{\\mathtt{[CLS]}} \\\\\nS_\\text{retr}(z, x) &= h_x^\\top h_z\n\\end{aligned}\n$$\nThe retriever module is pretrained with\nInverse Cloze Task (ICT)\n, which is to predict the context given a sentence, opposite to the standard\nCloze Task\n. The ICT objective is to maximize the retrieval score of the correct context $z$ given a random sentence $x$:\n$$\nL_\\text{ICT} = p_\\text{early}(z \\vert x) = \\frac{\\exp(S_\\text{retr}(z, x))}{\\sum_{z'\\in\\text{BATCH}(\\mathcal{Z})} \\exp(S_\\text{retr}(z', x))}\n$$\nwhere $\\text{BATCH}(\\mathcal{Z})$ is the set of evidence blocks in the same batch used as sampled negatives.\nAfter such pretraining, the BERT retriever is expected to have representations good enough for evidence retrieval. Only the question encoder needs to be fine-tuned for answer extraction. In other words, the evidence block encoder (i.e., $\\mathbf{W}_z$ and $\\text{BERT}_z$) is fixed and thus all the evidence block encodings can be pre-computed with support for\nfast Maximum Inner Product Search (MIPS)\n.\nAn illustration of the reader component in ORQA. (Image source:\nacl2020-openqa-tutorial/slides/part5\n)\nThe reader follows the same design as in the original\nBERT RC\nexperiments. It learns in a supervised manner, while the parameters of the evidence block encoder are fixed and all other parameters are fine-tuned. Given a question $x$ and a gold answer string $y$, the reader loss contains two parts:\n$$\n\\mathcal{L}(x, y) = \\mathcal{L}_\\text{early}(x, y) + \\mathcal{L}_\\text{full}(x, y)\n$$\n(1) Find all correct text spans within top $k$ evidence blocks and optimize for the marginal likelihood of a text span $s$ that matches the true answer $y$:\n$$\n\\begin{aligned}\nh_s &= \\text{BERT}_R(x, y)^{(\\text{START}(s))} \\\\\nh_e &= \\text{BERT}_R(x, y)^{(\\text{END}(s))} \\\\\nS_\\text{read}(z, s, x) &= \\text{MLP}([h_s; h_e]) \\\\\np(z, s \\vert x) &= \\frac{\\exp(S_\\text{read}(z, s, x))}{\\sum_{z'\\in\\text{TOP}(k)} \\sum_{s'\\in z'} \\exp(S_\\text{read}(z', s', x))} \\\\\nL_\\text{full}(x, y) &= - \\log \\sum_{\\substack{z \\in \\text{TOP}(k)\\\\ s \\in z}} \\sum_{y=\\text{TEXT}(s)} p(z, s \\vert x)\n\\end{aligned}\n$$\nwhere $y=\\text{TEXT}(s)$ indicates whether the answer $y$ matches the text span $s$. $\\text{TOP}(k)$ is the top $k$ retrieved blocks according to $S_\\text{retr}(z, x)$. The paper sets $k=5$.\n(2) At the early stage of learning, when the retriever is not strong enough, it is possible none of the top $k$ blocks contains the answer. To avoid such sparse learning signals, ORQA considers a larger set of $c$ evidence blocks for more aggressive learning. The paper has $c=5000$.\n$$\nL_\\text{early}(x, y)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} p_\\text{early}(z\\vert x)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} \\frac{\\exp(S_\\text{retr}(z, x)}{\\sum_{z'\\in\\text{TOP}(c)} \\exp(S_\\text{retr}(z', x)}\n$$\nSome issues in SQuAD dataset were discussed in the ORQA paper:\n\" The notable drop between development and test accuracy for SQuAD is a reflection of an artifact in the dataset—its 100k questions are derived from only 536 documents. Therefore, good retrieval targets are highly correlated between training examples, violating the IID assumption, and making it unsuitable for learned retrieval. We strongly suggest that those who are interested in end-to-end open-domain QA models no longer train and evaluate with SQuAD for this reason.\"\nREALM\n(“Retrieval-Augmented Language Model pre-training”;\nGuu et al., 2020\n) also jointly trains retriever + reader by optimizing the marginal likelihood of obtaining the true answer:\n$$\np(y \\vert x) \n= \\sum_{z \\in \\mathcal{Z}} \\underbrace{p(y \\vert x, z)}_\\text{reader} \\underbrace{p(z \\vert x)}_\\text{retriever}\n\\approx \\sum_{z \\in \\text{TOP}_k(\\mathcal{Z})} p(y \\vert x, z) p(z \\vert x)\n$$\nREALM is first unsupervised pre-trained with salient spans masking and then fine-tuned with QA data. (Image source:\nGuu et al., 2020\n).\nREALM computes two probabilities, $p(z \\vert x)$ and $p(y \\vert x, z)$, same as ORQA. However, different from ICT in ORQA, REALM upgrades the unsupervised pre-training step with several new design decisions, leading towards better retrievals. REALM pre-trains the model with Wikipedia or CC-News corpus.\nUse\nsalient span masking\n. Named entities and dates are identified. Then one of these “salient spans” is selected and masked. Salient span masking is a special case of MLM and works out well for QA tasks.\nAdd an\nempty null document\n. Because not every question demands a context document.\nNo trivial retrieval. The context document should not be same as the selected sentence with a masked span.\nApply the same ICT loss as in ORQA to encourage learning when the retrieval quality is still poor at the early stage of training.\n“Among all systems, the most direct comparison with REALM is ORQA (Lee et al., 2019), where the fine-tuning setup, hyperparameters and training data are identical. The improvement of REALM over ORQA is purely due to better pre-training methods.” — from REALM paper.\nBoth unsupervised pre-training and supervised fine-tuning optimize the same log-likelihood $\\log p(y \\vert x)$. Because the parameters of the retriever encoder for evidence documents are also updated in the process, the index for MIPS is changing. REALM asynchronously refreshes the index with the updated encoder parameters every several hundred training steps.\nBalachandran, et al. (2021)\nfound that REALM is significantly undertrained and REALM++ achieves great EM accuracy improvement (3-5%) by scaling up the model training with larger batch size and more retrieved documents for the reader to process.\nDPR\n(“Dense Passage Retriever”;\nKarpukhin et al., 2020\n,\ncode\n) argues that ICT pre-training could be too computationally expensive and the ORQA’s context encoder might be sub-optimal because it is not fine-tuned with question-answer pairs. DPR aims to resolve these two issues by only training a dense dual-encoder architecture for retrieval only from a small number of Q/A pairs, without any pre-training.\nSame as previous work, DPR uses the dot-product (L2 distance or cosine similarity also works) of BERT representations as retrieval score. The loss function for training the dual-encoder is the NLL of the positive passage, which essentially takes the same formulation as\nICT loss\nof ORQA. Note that both of them consider other passages in the same batch as the negative samples, named\nin-batch negative sampling\n. The main difference is that DPR relies on supervised QA data, while ORQA trains with ICT on unsupervised corpus. At the inference time, DPR uses\nFAISS\nto run fast MIPS.\nDPR did a set of comparison experiments involving several different types of negatives:\nRandom: any random passage from the corpus;\nBM25: top passages returned by BM25 which don’t contain the answer but match most question tokens;\nIn-batch negative sampling (“gold”): positive passages paired with other questions which appear in the training set.\nDPR found that using gold passages from the same mini-batch and one negative passage with high BM25 score works the best. To further improve the retrieval results, DPR also explored a setting where a BM25 score and a dense embedding retrieval score are linearly combined to serve as a new ranking function.\nOpen-book QA: Retriever-Generator\n#\nCompared to the retriever-reader approach, the retriever-generator also has 2 stages but the second stage is to generate free text directly to answer the question rather than to extract start/end position in a retrieved passage. Some paper also refer to this as\nGenerative question answering\n.\nThe retriever + generator QA framework combines a document retrieval system with a general language model.\nA pretrained LM has a great capacity of memorizing knowledge in its parameters, as shown above. However, they cannot easily modify or expand their memory, cannot straightforwardly provide insights into their predictions, and may produce non-existent illusion.\nPetroni et al. (2020)\nstudied how the retrieved relevant context can help a generative language model produce better answers. They found:\nAugmenting queries with relevant contexts dramatically improves the pretrained LM on unsupervised machine reading capabilities.\nAn off-the-shelf IR system is sufficient for BERT to match the performance of a supervised ODQA baseline;\nBERT’s\nNSP\npre-training strategy is a highly effective unsupervised mechanism in dealing with noisy and irrelevant contexts.\nThey pair the BERT model with different types of context, including adversarial (unrelated context), retrieved (by BM25), and generative (by an autoregressive language model of 1.4N parameters, trained on CC-NEWS). The model is found to be robust to adversarial context, but only when the question and the context are provided as two segments (e.g. separated by\n[SEP]\n). One hypothesis is related to NSP task: “BERT might learn to not condition across segments for masked token prediction if the NSP score is low, thereby implicitly detecting irrelevant and noisy contexts.”\nRAG\n(“Retrieval-Augmented Generation”;\nLewis et al., 2020\n) combines pre-trained parametric (language model) and non-parametric memory (external knowledge index) together for language generation. RAG can be fine-tuned on any seq2seq task, whereby both the retriever and the sequence generator are jointly learned. They found that unconstrained generation outperforms previous extractive approaches.\nRAG consists of a retriever model $p_\\eta(z \\vert x)$ and a generator model $p_\\theta(y_i \\vert x, z, y_{1:i-1})$:\nThe retriever uses the input sequence $x$ to retrieve text passages $z$, implemented as a\nDPR\nretriever. $\\log p_\\eta(z \\vert x) \\propto E_z(z)^\\top E_x(x)$.\nThe generator uses $z$ as additional context when generating the target sequence $y$, where the context and the question are simply concatenated.\nDepending on whether using the same or different retrieved documents for each token generation, there are two versions of RAG:\n$$\n\\begin{aligned}\np_\\text{RAG-seq}(y \\vert x) &= \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z \\vert x) \\prod_i^N p_\\theta(y_i \\vert x, z, y_{1:i-1}) \\\\\np_\\text{RAG-token}(y \\vert x) &= \\prod_i^N \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z_i\\vert x) p_\\theta(y_i \\vert x, z_i, y_{1:i-1})\n\\end{aligned}\n$$\nThe retriever + generator in RAG is jointly trained to minimize the NLL loss, $\\mathcal{L}_\\text{RAG} = \\sum_j -\\log p(y_j \\vert x_j)$. Updating the passage encoder $E_z(.)$ is expensive as it requires the model to re-index the documents for fast MIPS. RAG does not find fine-tuning $E_z(.)$ necessary (like in\nORQA\n) and only updates the query encoder + generator.\nAn illustration of retrieval-augmented generation (RAG) architecture. (Image source:\nLewis et al., 2020\n)\nAt decoding/test time, RAG-token can be evaluated via a\nbeam search\n. RAG-seq cannot be broken down into a set of per-token likelihood, so it runs beam search for each candidate document $z$ and picks the one with optimal $p_\\theta(y_i \\vert x, z, y_{1:i-1})$.\nThe\nFusion-in-Decoder\napproach, proposed by\nIzacard & Grave (2020)\nis also based on a pre-trained T5. It works similar to RAG but differently for how the context is integrated into the decoder.\nRetrieve top $k$ related passage of 100 words each, using BM25 or DPR.\nEach retrieved passage and its title are concatenated with the question using special tokens like\nquestion:\n,\ntitle:\nand\ncontext:\nto indicate the content differences.\nEach retrieved passage is processed independently and later combined in the decoder. Processing passages independently in the encoder allows us to parallelize the computation. OTOH, processing them jointly encourages better aggregation of multiple pieces of evidence. The aggregation part is missing in extractive approaches.\nNote that they did fine-tune the pretrained LM independently for each dataset.\nClosed-book QA: Generative Language Model\n#\nBig language models have been pre-trained on a large collection of unsupervised textual corpus. Given enough parameters, these models are able to memorize some factual knowledge within parameter weights. Therefore, we can use these models to do question-answering without explicit context, just like in a closed-book exam. The pre-trained language models produce\nfree text\nto respond to questions, no explicit reading comprehension.\nThe amount of computation used for training big language models of different sizes is getting big. (Image source:\nBrown et al., 2020\n).\nRoberts et al. (2020)\nmeasured the practical utility of a language model by fine-tuning a pre-trained model to answer questions without access to any external context or knowledge. They fine-tuned the\nT5\nlanguage model (same architecture as the original Transformer) to answer questions without inputting any additional information or context. Such setup enforces the language model to answer questions based on “knowledge” that it internalized during pre-training.\nT5 is first pre-trained with salient span masking and then fine-tuned for each QA dataset to produce answers in free text. (Image source:\nRoberts et al. 2020\n)\nThe original T5 models were pre-trained on a multi-task mixture including an unsupervised\n“masked language modeling”\n(MLM) tasks on the C4 (“Colossal Clean Crawled Corpus”) dataset as well as fine-tuned altogether with supervised translation, summarization, classification, and reading comprehension tasks.\nRoberts, et al. (2020)\ntook a pre-trained T5 model and continued pre-training with\nsalient span masking\nover Wikipedia corpus, which has been found to substantially boost the performance for ODQA. Then they fine-tuned the model for each QA datasets independently.\nWith a pre-trained T5 language model +  continue pre-training with salient spans masking + fine-tuning for each QA dataset,\nIt can attain competitive results in open-domain question answering without access to external knowledge.\nA larger model can obtain better performance. For example, a T5 with 11B parameters is able to match the performance with\nDPR\nwith 3 BERT-base models, each with 330M parameters.\nInterestingly, fine-tuning is not strictly necessary. GPT3 (\nBrown et al., 2020\n) has been evaluated on the closed book question answering task\nwithout any gradient updates or fine-tuning\n. During evaluation, the few-shot, one-shot and zero-shot settings here only refer to how many demonstrations are provided as context in the text input:\n“few-shot learning”: GPT3 is allowed to take as many demonstrations as what can fit into the model’s context window (typically 10 to 100).\n“one-shot learning”: only one demonstration is provided.\n“zero-shot learning”: no demonstrations are allowed and only an instruction in natural language is given to the model.\nThe performance grows with the model size. On the TriviaQA dataset, GPT3 evaluation with demonstrations can match or exceed the performance of SOTA baseline with fine-tuning.\nGPT3's performance on TriviaQA grows smoothly with the model size. More demonstrations lead to better performance. (Image source:\nBrown et al., 2020\n).\nCheck out this cool example in OpenAI API\nplayground viewer\n. The model is able to answer factal questions in short answer and not to make up things when the model does not know the answer. I added the last two questions and asked the model to respond with\nA:\n. The API is still in beta version, so you might need to\napply\nto get on the wait list.\nQ: Who is Batman?\nA: Batman is a fictional comic book character.\n##\nQ: What is torsalplexity?\nA: ?\n##\nQ: What is Devz9?\nA: ?\n##\nQ: Who is George Lucas?\nA: George Lucas is American film director and producer famous for creating Star Wars.\n##\nQ: What is the capital of California?\nA: Sacramento.\n##\nQ: What orbits the Earth?\nA: The Moon.\n##\nQ: Who is Fred Rickerson?\nA: ?\n##\nQ: What is an atom?\nA: An atom is a tiny particle that makes up everything.\n##\nQ: Who is Alvan Muntz?\nA: ?\n##\nQ: What is Kozar-09?\nA: ?\n##\nQ: How many moons does Mars have?\nA: Two, Phobos and Deimos.\n##\nQ: What is COVID-19?\nA: ?\n##\nQ: What is H1N1?\nA: H1N1 is a strain of influenza.\nRelated Techniques\n#\nFast Maximum Inner Product Search (MIPS)\n#\nMIPS (maximum inner product search) is a crucial component in many open-domain question answering models. In retriever + reader/generator framework, a large number of passages from the knowledge source are encoded and stored in a memory. A retrieval model is able to query the memory to identify the top relevant passages which have the maximum inner product with the question’s embedding.\nWe need fast MIPS because the number of precomputed passage representations can be gigantic. There are several ways to achieve fast MIPS at run time, such as\nasymmetric LSH\n,\ndata-dependent hashing\n,  and\nFAISS\n.\nLanguage Model Pre-training\n#\nTwo pre-training tasks are especially helpful for QA tasks, as we have discussed above.\nInverse Cloze Task\n(proposed by\nORQA\n): The goal of\nCloze Task\nis to predict masked-out text based on its context. The prediction of Inverse Cloze Task (ICT) is in the reverse direction, aiming to predict the context given a sentence. In the context of QA tasks, a random sentence can be treated as a pseudo-question, and its context can be treated as pseudo-evidence.\nSalient Spans Masking\n(proposed by\nREALM\n): Salient span masking is a special case for MLM task in language model training. First, we find\nsalient spans\nby using a tagger to identify named entities and a regular expression to identify dates. Then one of the detected salient spans is selected and masked. The task is to predict this masked salient span.\nSummary\n#\nModel\nRetriever\nReader / Generator\nPre-training / Fine-tuning\nEnd2end\nDrQA\nTF-IDF\nBi-directional LSTM\n–\nNo\nBERTserini\nAserini + BM25\nBERT without softmax layer\nFine-tune with SQuAD\nNo\nMulti-passage BERT\nElasticSearch + BM25\nMulti-passage BERT + Passage ranker\nNo\nR^3\nClassic IR + Match-LSTM\nMatch-LSTM\nYes\nORQA\nDot product of BERT embeddings\nBERT-RC\nInverse cloze task\nYes\nREALM\nDot product of BERT embeddings\nBERT-RC\nSalient span masking\nYes\nDPR\nDot product of BERT embeddings\nBERT-RC\nsupervised training with QA pairs\nYes\nDenSPI\nClassic + Neural IR\n–\nYes\nT5 + SSM\n–\nT5\nSSM on\nCommonCrawl\ndata + Fine-tuning on QA data\nYes\nGPT3\n–\nGPT3\nNSP on\nCommonCrawl\ndata\nYes\nRAG\nDPR retriever\nBART\nYes\nFusion-in-Decoder\nBM25 / DPR retriever\nTranformer\nNo\nA comparison of performance of several QA models on common QA datasets. On TriviaQA, two columns of results are reported, on the open domain test set (left) and on the hidden test set (right). (Image source:\nIzacard & Grave, 2020\n).\nCitation\n#\nCited as:\nWeng, Lilian. (Oct 2020). How to build an open-domain question answering system? Lil’Log. https://lilianweng.github.io/posts/2020-10-29-odqa/.\nOr\n@article{weng2020odqa,\n  title   = \"How to Build an Open-Domain Question Answering System?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Oct\"\n  url     = \"https://lilianweng.github.io/posts/2020-10-29-odqa/\"\n}\nAppendix: QA Datasets\n#\nSQuAD 2.0\n: the Stanford QA dataset.\nRACE\n: a reading comprehension dataset collected from English Examinations that are created for middle school and high school students.\nTREC QA\n: the TREC QA collections.\nMS MARCO\n: a QA dataset featuring 100,000 real Bing questions and a human generated answer.\nCuratedTREC\n: based on the benchmarks from the TREC QA tasks that have been curated by\nBaudis & Sedivy (2015)\n.\nGoogle Natural Questions\n:  contains real user questions issued to Google search, and answers found from Wikipedia by annotators.\nWebQuestions\n: designed for knowledge-base QA with answers restricted to Freebase entities.\nWikiQA\n: Bing query logs were used as the source of questions. Each question is then linked to a Wikipedia page that potentially contains the answer.\nWikiMovies\n: contains movie-related questions from the OMDb and MovieLens databases and where the questions can be answered using Wikipedia pages.\nWikiReading\n: to predict textual values from the structured knowledge base Wikidata by reading the text of the corresponding Wikipedia articles.\nTriviaQA\n: a reading comprehension dataset containing 95K question-answer pairs authored by trivia enthusiasts and independently gathered multiple evidence documents per question.\nJeopardy! Questions\n: contains 200,000+\nJeopardy!\nquestions.\nDeepMind Q&A Dataset\n: question/answer pairs from CNN and Daily Mail articles.\nbAbi\n: a rich collection of datasets for text understanding by Facebook.\nFEVER\n: for fact extraction and verification.\nSearchQA\n: question-answer pairs were crawled from from\nJ! Archive\n, and then augmented with text snippets from Google.\nQuasar-T\n: a collection of open-domain trivia questions and their answers obtained from various internet sources.\nQuiz bowl\n: contains data from a trivia competition called quiz bowl.\nAmbigNQ\n: ambiguous questions selected from NQ-OPEN dataset.\nQA-Overlap\n: a collections of overlapped answers/questions between train and test set for Natural Questions, TriviaQA, and WebQuestions.\nReferences\n#\n[1] Danqi Chen & Scott Yih.\n“ACL2020 Tutorial: Open-Domain Question Answering”\nJuly 2020.\n[2] Danqi Chen, et al.\n“Reading Wikipedia to Answer Open-Domain Questions”\nACL 2017. |\ncode\n[3] Shuohang Wang, et al.\n“R^3: Reinforced Ranker-Reader for Open-Domain Question Answering”\nAAAI 2018.\n[4] Jimmy Lin.\n“The neural hype and comparisons against weak baselines.”\nACM SIGIR Forum. Vol. 52. No. 2. 2019.\n[5] Wei Yang, et al.\n“End-to-End Open-Domain Question Answering with BERTserini”\nNAACL 2019.\n[6] Christopher Clark & Matt Gardner.\n“Simple and Effective Multi-Paragraph Reading Comprehension.”\narXiv:1710.10723 (2017).\n[7] Rodrigo Nogueira & Kyunghyun Cho.\n“Passage Re-ranking with BERT.”\narXiv preprint arXiv:1901.04085 (2019). |\ncode\n[8] Zhiguo Wang, et al.\n“Multi-passage BERT: A globally normalized BERT model for open-domain question answering.”\nEMNLP 2019.\n[9] Minjoon Seo et al.\n“Real-time open-domain question answering with dense-sparse phrase index.”\nACL 2019.\n[10] Kenton Lee, et al.\n“Latent Retrieval for Weakly Supervised Open Domain Question Answering”\nACL 2019.\n[11] Kelvin Guu, et al.\n“REALM: Retrieval-Augmented Language Model Pre-Training”\narXiv:2002.08909 (2020).\n[12] Vladimir Karpukhin et al.\n“Dense passage retrieval for open-domain question answering.”\n. EMNLP 2020. |\ncode\n[13] Patrick Lewis et al.\n“Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”\narXiv:2005.11401 (2020).\n[14] Adam Roberts, et al.\n“How Much Knowledge Can You Pack Into the Parameters of a Language Model?”\nEMNLP 2020.\n[15] Tom Brown, et al.\n“Language models are few-shot learners.”\narXiv:2005.14165 (2020).\n[16] Fabio Petroni, et al.\n“How Context Affects Language Models’ Factual Predictions”\nAKBC 2020.\n[17] Gautier Izacard & Edouard Grave.\n“Leveraging passage retrieval with generative models for open domain question answering.”\narXiv:2007.01282 (2020).\n[18]\n“Dive into deep learning: Beam search”\n[19] Patrick Lewis, et al.\n“Question and Answer Test-Train Overlap in Open-Domain Question Answering Datasets”\narXiv:2008.02637 (2020). |\ndata\n[20] Hervé Jegou, et al.\n“Faiss: A library for efficient similarity search”\nMar 2017.\n[21] Vidhisha Balachandran, et al.\n“Simple and Efficient ways to Improve REALM.”\narXiv:2104.08710 (2021).",
            "metadata": {
              "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
              "description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "keywords": "nlp, language-model, attention, transformer",
              "author": "Lilian Weng",
              "og:title": "How to Build an Open-Domain Question Answering System?",
              "og:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
              "twitter:card": "summary",
              "twitter:title": "How to Build an Open-Domain Question Answering System?",
              "twitter:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "article:section": "posts",
              "article:published_time": "2020-10-29T00:00:00+00:00",
              "article:modified_time": "2020-10-29T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/2cf34df8cd69/code/body-000.txt",
                "chars": 105,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-001.txt",
                "chars": 656,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-002.txt",
                "chars": 263,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "bytes": 661245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7efefadad7e7dd1bd368.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "bytes": 173461,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ef8c4099815df32d696d.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "bytes": 192230,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-a2c96b21ecb7e2fe5261.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "bytes": 180723,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-9d359913e38042c21f68.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "bytes": 131727,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-658614a9a3e7c1d7b935.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "bytes": 337530,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-eaf24c5188513fae50ed.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "bytes": 124437,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ff31b70ac499e0b32939.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "bytes": 865287,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-2e1a4cd54853b0630bf6.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "bytes": 553919,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7826a791054014f6fcfb.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "bytes": 260572,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-d37427b8abf7df28ba56.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "bytes": 198348,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-1debd5c40323ec83577c.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "bytes": 290218,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-76ae01d2ac36750aac13.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "bytes": 145311,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-cb02352f1fcc5796b966.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "bytes": 201245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-4a06ae2c872925f426c9.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "bytes": 329545,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-592734de78cf202658cc.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "bytes": 244182,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-f4f90d0aeb9507c08585.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2008.02637",
                "label": "Lewis, et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/QA-Overlap",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.00051",
                "label": "Chen et al., 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DrQA",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "TF-IDF",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Vector_space_model",
                "label": "vector space model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01718",
                "label": "Yang et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/castorini/anserini",
                "label": "Anserini",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Okapi_BM25",
                "label": "BM25",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.08167",
                "label": "Wang et al., 2019",
                "type": "a"
              },
              {
                "href": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "label": "Deerwester et al., 1990",
                "type": "a"
              },
              {
                "href": "https://www.aclweb.org/anthology/W11-0329/",
                "label": "Yih, et al., 2011",
                "type": "a"
              },
              {
                "href": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "label": "Lim, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.05807",
                "label": "Seo et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Glove",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "Devlin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.10723",
                "label": "globally",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.04085",
                "label": "Nogueira & Cho, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.00023",
                "label": "Wang, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.08849",
                "label": "Match-LSTM",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part4-retriever-reader.pdf",
                "label": "acl2020-openqa-tutorial/slides/part4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00300",
                "label": "Lee et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part5-dense-retriever-e2e-training.pdf",
                "label": "acl2020-openqa-tutorial/slides/part5",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Cloze Task",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08909",
                "label": "Guu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08710",
                "label": "Balachandran, et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DPR",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.04611",
                "label": "Petroni et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.11401",
                "label": "Lewis et al., 2020",
                "type": "a"
              },
              {
                "href": "https://d2l.ai/chapter_recurrent-modern/beam-search.html",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.01282",
                "label": "Izacard & Grave (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08910",
                "label": "Roberts et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "T5",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/playground/p/HMoho4552EHXrPLbmOIxpX4X",
                "label": "playground viewer",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/",
                "label": "apply",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "label": "asymmetric LSH",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1501.01062",
                "label": "data-dependent hashing",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/the-data/get-started/",
                "label": "CommonCrawl",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "BART",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD 2.0",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/qa.html",
                "label": "TREC QA",
                "type": "a"
              },
              {
                "href": "https://microsoft.github.io/msmarco/",
                "label": "MS MARCO",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-curated",
                "label": "CuratedTREC",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/chapter/10.1007%2F978-3-319-24027-5_20",
                "label": "Baudis & Sedivy (2015)",
                "type": "a"
              },
              {
                "href": "https://ai.google.com/research/NaturalQuestions/dataset",
                "label": "Google Natural Questions",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-webquestions",
                "label": "WebQuestions",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/publication/wikiqa-a-challenge-dataset-for-open-domain-question-answering/",
                "label": "WikiQA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "WikiMovies",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research-datasets/wiki-reading",
                "label": "WikiReading",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/triviaqa/",
                "label": "TriviaQA",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/tunguz/200000-jeopardy-questions",
                "label": "Jeopardy! Questions",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jeopardy!",
                "label": "Jeopardy!",
                "type": "a"
              },
              {
                "href": "https://cs.nyu.edu/~kcho/DMQA/",
                "label": "DeepMind Q&A Dataset",
                "type": "a"
              },
              {
                "href": "https://fever.ai/data.html",
                "label": "FEVER",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4ir-searchQA",
                "label": "SearchQA",
                "type": "a"
              },
              {
                "href": "https://j-archive.com/",
                "label": "J! Archive",
                "type": "a"
              },
              {
                "href": "https://github.com/bdhingra/quasar",
                "label": "Quasar-T",
                "type": "a"
              },
              {
                "href": "https://people.cs.umass.edu/~miyyer/qblearn/index.html",
                "label": "Quiz bowl",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/ambigqa/",
                "label": "AmbigNQ",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial",
                "label": "“ACL2020 Tutorial: Open-Domain Question Answering”",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4marco-bert",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://engineering.fb.com/2017/03/29/data-infrastructure/faiss-a-library-for-efficient-similarity-search/",
                "label": "“Faiss: A library for efficient similarity search”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:28Z",
            "source_url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2008.02637",
                "bytes": 146376,
                "reused": false,
                "local_path": "papers/repair/8ad962c997b08e996dd4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00051",
                "bytes": 2048034,
                "reused": false,
                "local_path": "papers/repair/d0f7a3fcc176ba86400e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01718",
                "bytes": 1306033,
                "reused": false,
                "local_path": "papers/repair/5601bffbfa0b981b6331.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.08167",
                "bytes": 259305,
                "reused": false,
                "local_path": "papers/repair/fa52b7dcb76039375378.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "content_type": "text/html; charset=UTF-8",
                "retried_at": "2026-10-20T17:40:15Z"
              },
              {
                "status": "ok",
                "url": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "bytes": 134597,
                "reused": false,
                "local_path": "papers/repair/4ab646693162802f854c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.05807",
                "bytes": 359767,
                "reused": false,
                "local_path": "papers/repair/747eb29b4590aa97c069.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.10723",
                "bytes": 452153,
                "reused": false,
                "local_path": "papers/repair/28189a7ac5e78a81e437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.04085",
                "bytes": 179659,
                "reused": false,
                "local_path": "papers/repair/05b68ab5e80214473436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.00023",
                "bytes": 467789,
                "reused": false,
                "local_path": "papers/repair/2b555bf087dc301d5ab3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.08849",
                "bytes": 560057,
                "reused": false,
                "local_path": "papers/repair/4a818c3029a76aba9073.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part4-retriever-reader.pdf",
                "bytes": 7788557,
                "reused": false,
                "local_path": "papers/repair/8edd53d3acc87ec95877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00300",
                "bytes": 324074,
                "reused": false,
                "local_path": "papers/repair/21d0f741ef22e8382844.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part5-dense-retriever-e2e-training.pdf",
                "bytes": 5923321,
                "reused": false,
                "local_path": "papers/repair/09e19d59295cafdb35c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08909",
                "bytes": 419037,
                "reused": false,
                "local_path": "papers/repair/9325ba1ac58281154385.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08710",
                "bytes": 314281,
                "reused": false,
                "local_path": "papers/repair/4afe57efbece847b61fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.04611",
                "bytes": 599811,
                "reused": false,
                "local_path": "papers/repair/d1464f0dd0e30968c8ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.11401",
                "bytes": 885323,
                "reused": true,
                "local_path": "papers/repair/fc8d32f196e0f0c27ffb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.01282",
                "bytes": 326612,
                "reused": false,
                "local_path": "papers/repair/63195f1903a8ee821e29.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08910",
                "bytes": 310594,
                "reused": false,
                "local_path": "papers/repair/4f3639d8e3ec9d8f612f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "bytes": 429326,
                "reused": false,
                "local_path": "papers/repair/615a9235abb8f6f533bd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1501.01062",
                "bytes": 849475,
                "reused": false,
                "local_path": "papers/repair/63f32442dc6c96976afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46975,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/2cf34df8cd69/pages/source.html",
            "local_html": "attachments/2cf34df8cd69/pages/article.html",
            "body_base_path": "attachments/2cf34df8cd69/pages/",
            "body_markdown_path": "attachments/2cf34df8cd69/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
          "status": "partial",
          "article_id": "cd59f7ee3fdb",
          "local_path": "series-follow/1600/repair/8804f3f0e1a2da8b46c4.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
              "bytes": 137292,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/db59b90d279b037a97d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
              "bytes": 256981,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ab7006570b99c84db1b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
              "bytes": 26225,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1c83c8f4d8be7a5b4c49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
              "bytes": 1878475,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2e93bdc2c46162899b3f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
              "bytes": 151943,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/13d9a58c515022883c19.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
              "bytes": 482588,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ee2f9d9fbcd3aed80f31.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
              "bytes": 188866,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2351ecad009ac2895562.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
              "bytes": 274889,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/fae191e6a32c13b2540d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
              "bytes": 806890,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9610ae1d4a5d7cbb7454.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
              "bytes": 943633,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e326acd6fdf8195c78b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
              "bytes": 594737,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/91ba8add21dff9815090.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
              "bytes": 207374,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7020e37618b19a5457cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
              "bytes": 946267,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/da329904d7433579a338.png"
            }
          ],
          "article": {
            "id": "cd59f7ee3fdb",
            "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "source_excel_row": 1600,
            "source_url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "bytes": 137292,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-db59b90d279b037a97d1.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "bytes": 256981,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ab7006570b99c84db1b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "bytes": 26225,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-1c83c8f4d8be7a5b4c49.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "bytes": 1878475,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2e93bdc2c46162899b3f.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "bytes": 151943,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-13d9a58c515022883c19.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "bytes": 482588,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ee2f9d9fbcd3aed80f31.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "bytes": 188866,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2351ecad009ac2895562.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "bytes": 274889,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-fae191e6a32c13b2540d.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "bytes": 806890,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-9610ae1d4a5d7cbb7454.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "bytes": 943633,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-e326acd6fdf8195c78b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "bytes": 594737,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-91ba8add21dff9815090.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "bytes": 207374,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-7020e37618b19a5457cc.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "bytes": 946267,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-da329904d7433579a338.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "src": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/cd59f7ee3fdb/videos/repair-9zKuYvjFFS8.mp4",
                "bytes": 119566312,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "905.001000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-07-18: add a section on\nVQ-VAE & VQ-VAE-2\n.]\n[Updated on 2019-07-26: add a section on\nTD-VAE\n.]\nAutocoder is invented to reconstruct high-dimensional data using a neural network model with a narrow bottleneck layer in the middle (oops, this is probably not true for\nVariational Autoencoder\n, and we will investigate it in details in later sections). A nice byproduct is dimension reduction: the bottleneck layer captures a compressed latent encoding. Such a low-dimensional representation can be used as en embedding vector in various applications (i.e. search), help data compression, or reveal the underlying data generative factors.\nNotation\n#\nSymbol\nMean\n$\\mathcal{D}$\nThe dataset, $\\mathcal{D} = \\{ \\mathbf{x}^{(1)}, \\mathbf{x}^{(2)}, \\dots, \\mathbf{x}^{(n)} \\}$, contains $n$ data samples; $\\vert\\mathcal{D}\\vert =n $.\n$\\mathbf{x}^{(i)}$\nEach data point is a vector of $d$ dimensions, $\\mathbf{x}^{(i)} = [x^{(i)}_1, x^{(i)}_2, \\dots, x^{(i)}_d]$.\n$\\mathbf{x}$\nOne data sample from the dataset, $\\mathbf{x} \\in \\mathcal{D}$.\n$\\mathbf{x}’$\nThe reconstructed version of $\\mathbf{x}$.\n$\\tilde{\\mathbf{x}}$\nThe corrupted version of $\\mathbf{x}$.\n$\\mathbf{z}$\nThe compressed code learned in the bottleneck layer.\n$a_j^{(l)}$\nThe activation function for the $j$-th neuron in the $l$-th hidden layer.\n$g_{\\phi}(.)$\nThe\nencoding\nfunction parameterized by $\\phi$.\n$f_{\\theta}(.)$\nThe\ndecoding\nfunction parameterized by $\\theta$.\n$q_{\\phi}(\\mathbf{z}\\vert\\mathbf{x})$\nEstimated posterior probability function, also known as\nprobabilistic encoder\n.\n$p_{\\theta}(\\mathbf{x}\\vert\\mathbf{z})$\nLikelihood of generating true data sample given the latent code, also known as\nprobabilistic decoder\n.\nAutoencoder\n#\nAutoencoder\nis a neural network designed to learn an identity function in an unsupervised way  to reconstruct the original input while compressing the data in the process so as to discover a more efficient and compressed representation. The idea was originated in\nthe 1980s\n, and later promoted by the seminal paper by\nHinton & Salakhutdinov, 2006\n.\nIt consists of two networks:\nEncoder\nnetwork: It translates the original high-dimension input into the latent low-dimensional code. The input size is larger than the output size.\nDecoder\nnetwork: The decoder network recovers the data from the code, likely with larger and larger output layers.\nIllustration of autoencoder model architecture.\nThe encoder network essentially accomplishes the\ndimensionality reduction\n, just like how we would use Principal Component Analysis (PCA) or Matrix Factorization (MF) for. In addition, the autoencoder is explicitly optimized for the data reconstruction from the code. A good intermediate representation not only can capture latent variables, but also benefits a full\ndecompression\nprocess.\nThe model contains an encoder function $g(.)$ parameterized by $\\phi$ and a decoder function $f(.)$ parameterized by $\\theta$. The low-dimensional code learned for input $\\mathbf{x}$ in the bottleneck layer is $\\mathbf{z} = g_\\phi(\\mathbf{x})$ and the reconstructed input is $\\mathbf{x}’ = f_\\theta(g_\\phi(\\mathbf{x}))$.\nThe parameters $(\\theta, \\phi)$ are learned together to output a reconstructed data sample same as the original input, $\\mathbf{x} \\approx f_\\theta(g_\\phi(\\mathbf{x}))$, or in other words, to learn an identity function. There are various metrics to quantify the difference between two vectors, such as cross entropy when the activation function is sigmoid, or as simple as MSE loss:\n$$\nL_\\text{AE}(\\theta, \\phi) = \\frac{1}{n}\\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\mathbf{x}^{(i)})))^2\n$$\nDenoising Autoencoder\n#\nSince the autoencoder learns the identity function, we are facing the risk of “overfitting” when there are more network parameters than the number of data points.\nTo avoid overfitting and improve the robustness,\nDenoising Autoencoder\n(Vincent et al. 2008) proposed a modification to the basic autoencoder. The input is partially corrupted by adding noises to or masking some values of the input vector in a stochastic manner, $\\tilde{\\mathbf{x}} \\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$. Then the model is trained to recover the original input (note: not the corrupt one).\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{x}}^{(i)} &\\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}}^{(i)} \\vert \\mathbf{x}^{(i)})\\\\\nL_\\text{DAE}(\\theta, \\phi) &= \\frac{1}{n} \\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\tilde{\\mathbf{x}}^{(i)})))^2\n\\end{aligned}\n$$\nwhere $\\mathcal{M}_\\mathcal{D}$ defines the mapping from the true data samples to the noisy or corrupted ones.\nIllustration of denoising autoencoder model architecture.\nThis design is motivated by the fact that humans can easily recognize an object or a scene even the view is partially occluded or corrupted. To “repair” the partially destroyed input, the denoising autoencoder has to discover and capture relationship between dimensions of input in order to infer missing pieces.\nFor high dimensional input with high redundancy, like images, the model is likely to depend on evidence gathered from a combination of many input dimensions to recover the denoised version rather than to overfit one dimension. This builds up a good foundation for learning\nrobust\nlatent representation.\nThe noise is controlled by a stochastic mapping $\\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$, and it is not specific to a particular type of corruption process (i.e. masking noise, Gaussian noise, salt-and-pepper noise, etc.). Naturally the corruption process can be equipped with prior knowledge\nIn the experiment of the original DAE paper, the noise is applied in this way: a fixed proportion of input dimensions are selected at random and their values are forced to 0. Sounds a lot like dropout, right? Well, the denoising autoencoder was proposed in 2008, 4 years before the dropout paper (\nHinton, et al. 2012\n) ;)\nSparse Autoencoder\n#\nSparse Autoencoder\napplies a “sparse” constraint on the hidden unit activation to avoid overfitting and improve robustness. It forces the model to only have a small number of hidden units being activated at the same time, or in other words, one hidden neuron should be inactivate most of time.\nRecall that common\nactivation functions\ninclude sigmoid, tanh, relu, leaky relu, etc. A neuron is activated when the value is close to 1 and inactivate with a value close to 0.\nLet’s say there are $s_l$ neurons in the $l$-th hidden layer and the activation function for the $j$-th neuron in this layer is labelled as $a^{(l)}_j(.)$, $j=1, \\dots, s_l$. The fraction of activation of this neuron $\\hat{\\rho}_j$ is expected to be a small number $\\rho$, known as\nsparsity parameter\n; a common config is $\\rho = 0.05$.\n$$\n\\hat{\\rho}_j^{(l)} = \\frac{1}{n} \\sum_{i=1}^n [a_j^{(l)}(\\mathbf{x}^{(i)})] \\approx \\rho\n$$\nThis constraint is achieved by adding a penalty term into the loss function. The KL-divergence $D_\\text{KL}$ measures the difference between two Bernoulli distributions, one with mean $\\rho$ and the other with mean $\\hat{\\rho}_j^{(l)}$. The hyperparameter $\\beta$ controls how strong the penalty we want to apply on the sparsity loss.\n$$\n\\begin{aligned}\nL_\\text{SAE}(\\theta) \n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} D_\\text{KL}(\\rho \\| \\hat{\\rho}_j^{(l)}) \\\\\n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} \\rho\\log\\frac{\\rho}{\\hat{\\rho}_j^{(l)}} + (1-\\rho)\\log\\frac{1-\\rho}{1-\\hat{\\rho}_j^{(l)}}\n\\end{aligned}\n$$\nThe KL divergence between a Bernoulli distribution with mean $\\rho=0.25$ and a Bernoulli distribution with mean $0 \\leq \\hat{\\rho} \\leq 1$.\n$k$-Sparse Autoencoder\nIn $k$-Sparse Autoencoder (\nMakhzani and Frey, 2013\n), the sparsity is enforced by only keeping the top k highest activations in the bottleneck layer with linear activation function.\nFirst we run feedforward through the encoder network to get the compressed code: $\\mathbf{z} = g(\\mathbf{x})$.\nSort the values  in the code vector $\\mathbf{z}$. Only the k largest values are kept while other neurons are set to 0. This can be done in a ReLU layer with an adjustable threshold too. Now we have a sparsified code: $\\mathbf{z}’ = \\text{Sparsify}(\\mathbf{z})$.\nCompute the output and the loss from the sparsified code, $L = |\\mathbf{x} - f(\\mathbf{z}’) |_2^2$.\nAnd, the back-propagation only goes through the top k activated hidden units!\nFilters of the k-sparse autoencoder for different sparsity levels k, learnt from MNIST with 1000 hidden units.. (Image source:\nMakhzani and Frey, 2013\n)\nContractive Autoencoder\n#\nSimilar to sparse autoencoder,\nContractive Autoencoder\n(\nRifai, et al, 2011\n) encourages the learned representation to stay in a contractive space for better robustness.\nIt adds a term in the loss function to penalize the representation being too sensitive to the input,  and thus improve the robustness to small perturbations around the training data points. The sensitivity is measured by the Frobenius norm of the Jacobian matrix of the encoder activations with respect to the input:\n$$\n\\|J_f(\\mathbf{x})\\|_F^2 = \\sum_{ij} \\Big( \\frac{\\partial h_j(\\mathbf{x})}{\\partial x_i} \\Big)^2\n$$\nwhere $h_j$ is one unit output in the compressed code $\\mathbf{z} = f(x)$.\nThis penalty term is the sum of squares of all partial derivatives of the learned encoding with respect to input dimensions. The authors claimed that empirically this penalty was found to  carve a representation that corresponds to a lower-dimensional non-linear manifold, while staying more invariant to majority directions orthogonal to the manifold.\nVAE: Variational Autoencoder\n#\nThe idea of\nVariational Autoencoder\n(\nKingma & Welling, 2014\n), short for\nVAE\n, is actually less similar to all the autoencoder models above, but deeply rooted in the methods of variational bayesian and graphical model.\nInstead of mapping the input into a\nfixed\nvector, we want to map it into a distribution. Let’s label this distribution as $p_\\theta$, parameterized by $\\theta$.  The relationship between the data input $\\mathbf{x}$ and the latent encoding vector $\\mathbf{z}$ can be fully defined by:\nPrior $p_\\theta(\\mathbf{z})$\nLikelihood $p_\\theta(\\mathbf{x}\\vert\\mathbf{z})$\nPosterior $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$\nAssuming that we know the real parameter $\\theta^{*}$ for this distribution. In order to generate a sample that looks like a real data point $\\mathbf{x}^{(i)}$, we follow these steps:\nFirst, sample a $\\mathbf{z}^{(i)}$ from a prior distribution $p_{\\theta^*}(\\mathbf{z})$.\nThen a value $\\mathbf{x}^{(i)}$ is generated from a conditional distribution $p_{\\theta^*}(\\mathbf{x} \\vert \\mathbf{z} = \\mathbf{z}^{(i)})$.\nThe optimal parameter $\\theta^{*}$ is the one that maximizes the probability of generating real data samples:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\prod_{i=1}^n p_\\theta(\\mathbf{x}^{(i)})\n$$\nCommonly we use the log probabilities to convert the product on RHS to a sum:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\sum_{i=1}^n \\log p_\\theta(\\mathbf{x}^{(i)})\n$$\nNow let’s update the equation to better demonstrate the data generation process so as to involve the encoding vector:\n$$\np_\\theta(\\mathbf{x}^{(i)}) = \\int p_\\theta(\\mathbf{x}^{(i)}\\vert\\mathbf{z}) p_\\theta(\\mathbf{z}) d\\mathbf{z} \n$$\nUnfortunately it is not easy to compute $p_\\theta(\\mathbf{x}^{(i)})$ in this way, as it is very expensive to check all the possible values of $\\mathbf{z}$ and sum them up. To narrow down the value space to facilitate faster search, we would like to introduce a new approximation function to output what is a likely code given an input $\\mathbf{x}$, $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$, parameterized by $\\phi$.\nThe graphical model involved in Variational Autoencoder.  Solid lines denote the generative distribution $p\\_\\theta(.)$ and dashed lines denote the distribution $q\\_\\phi (\\mathbf{z}\\vert\\mathbf{x})$ to approximate the intractable posterior $p\\_\\theta (\\mathbf{z}\\vert\\mathbf{x})$.\nNow the structure looks a lot like an autoencoder:\nThe conditional probability $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ defines a generative model, similar to the decoder $f_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ introduced above. $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ is also known as\nprobabilistic decoder\n.\nThe approximation function $q_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ is the\nprobabilistic encoder\n, playing a similar role as $g_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ above.\nLoss Function: ELBO\n#\nThe estimated posterior $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ should be very close to the real one $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$. We can use\nKullback-Leibler divergence\nto quantify the distance between these two distributions. KL divergence $D_\\text{KL}(X|Y)$ measures how much information is lost if the distribution Y is used to represent X.\nIn our case we want to minimize $D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) | p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )$ with respect to $\\phi$.\nBut why use $D_\\text{KL}(q_\\phi | p_\\theta)$ (reversed KL) instead of $D_\\text{KL}(p_\\theta | q_\\phi)$ (forward KL)? Eric Jang has a great explanation in his\npost\non Bayesian Variational methods. As a quick recap:\nForward and reversed KL divergence have different demands on how to match two distributions. (Image source:\nblog.evjang.com/2016/08/variational-bayes.html\n)\nForward KL divergence: $D_\\text{KL}(P|Q) = \\mathbb{E}_{z\\sim P(z)} \\log\\frac{P(z)}{Q(z)}$; we have to ensure that Q(z)>0 wherever P(z)>0. The optimized variational distribution $q(z)$ has to cover over the entire $p(z)$.\nReversed KL divergence: $D_\\text{KL}(Q|P) = \\mathbb{E}_{z\\sim Q(z)} \\log\\frac{Q(z)}{P(z)}$; minimizing the reversed KL divergence squeezes the $Q(z)$ under $P(z)$.\nLet’s now expand the equation:\n$$\n\\begin{aligned}\n& D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z} \\vert \\mathbf{x})} d\\mathbf{z} & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})p_\\theta(\\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z \\vert x) = p(z, x) / p(x)} \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\big( \\log p_\\theta(\\mathbf{x}) + \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} \\big) d\\mathbf{z} & \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }\\int q(z \\vert x) dz = 1}\\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{x}\\vert\\mathbf{z})p_\\theta(\\mathbf{z})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z, x) = p(x \\vert z) p(z)} \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}[\\log \\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z})} - \\log p_\\theta(\\mathbf{x} \\vert \\mathbf{z})] &\\\\\n&=\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) &\n\\end{aligned}\n$$\nSo we have:\n$$\nD_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) =\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})\n$$\nOnce rearrange the left and right hand side of the equation,\n$$\n\\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) = \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}))\n$$\nThe LHS of the equation is exactly what we want to maximize when learning the true distributions: we want to maximize the (log-)likelihood of generating real data (that is $\\log p_\\theta(\\mathbf{x})$) and also minimize the difference between the real and estimated posterior distributions (the term $D_\\text{KL}$ works like a regularizer).  Note that $p_\\theta(\\mathbf{x})$ is fixed with respect to $q_\\phi$.\nThe negation of the above defines our loss function:\n$$\n\\begin{aligned}\nL_\\text{VAE}(\\theta, \\phi) \n&= -\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )\\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}) ) \\\\\n\\theta^{*}, \\phi^{*} &= \\arg\\min_{\\theta, \\phi} L_\\text{VAE}\n\\end{aligned}\n$$\nIn Variational Bayesian methods, this loss function is known as the\nvariational lower bound\n, or\nevidence lower bound\n. The “lower bound” part in the name comes from the fact that KL divergence is always non-negative and thus $-L_\\text{VAE}$ is the lower bound of $\\log p_\\theta (\\mathbf{x})$.\n$$\n-L_\\text{VAE} = \\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) \\leq \\log p_\\theta(\\mathbf{x})\n$$\nTherefore by minimizing the loss, we are maximizing the lower bound of the probability of generating real data samples.\nReparameterization Trick\n#\nThe expectation term in the loss function invokes generating samples from $\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$. Sampling is a stochastic process and therefore we cannot backpropagate the gradient. To make it trainable, the reparameterization trick is introduced: It is often possible to express the random variable $\\mathbf{z}$ as a deterministic variable $\\mathbf{z} = \\mathcal{T}_\\phi(\\mathbf{x}, \\boldsymbol{\\epsilon})$, where $\\boldsymbol{\\epsilon}$ is an auxiliary independent random variable, and the transformation function $\\mathcal{T}_\\phi$ parameterized by $\\phi$ converts $\\boldsymbol{\\epsilon}$ to $\\mathbf{z}$.\nFor example, a common choice of the form of $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ is a multivariate Gaussian with a diagonal covariance structure:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x}^{(i)}) = \\mathcal{N}(\\mathbf{z}; \\boldsymbol{\\mu}^{(i)}, \\boldsymbol{\\sigma}^{2(i)}\\boldsymbol{I}) & \\\\\n\\mathbf{z} &= \\boldsymbol{\\mu} + \\boldsymbol{\\sigma} \\odot \\boldsymbol{\\epsilon} \\text{, where } \\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I}) & \\scriptstyle{\\text{; Reparameterization trick.}}\n\\end{aligned}\n$$\nwhere $\\odot$ refers to element-wise product.\nIllustration of how the reparameterization trick makes the $\\mathbf{z}$ sampling process trainable.(Image source: Slide 12 in Kingma’s NIPS 2015 workshop\ntalk\n)\nThe reparameterization trick works for other types of distributions too, not only Gaussian.\nIn the multivariate Gaussian case, we make the model trainable by learning the mean and variance of the distribution, $\\mu$ and $\\sigma$, explicitly using the reparameterization trick, while the stochasticity remains in the random variable $\\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I})$.\nIllustration of variational autoencoder model with the multivariate Gaussian assumption.\nBeta-VAE\n#\nIf each variable in the inferred latent representation $\\mathbf{z}$ is only sensitive to one single generative factor and relatively invariant to other factors, we will say this representation is disentangled or factorized. One benefit that often comes with disentangled representation is\ngood interpretability\nand easy generalization to a variety of tasks.\nFor example, a model trained on photos of human faces might capture the gentle, skin color, hair color, hair length, emotion, whether wearing a pair of glasses and many other relatively independent factors in separate dimensions. Such a disentangled representation is very beneficial to facial image generation.\nβ-VAE (\nHiggins et al., 2017\n) is a modification of Variational Autoencoder with a special emphasis to discover disentangled latent factors. Following the same incentive in VAE, we want to maximize the probability of generating real data, while keeping the distance between the real and estimated posterior distributions small (say, under a small constant $\\delta$):\n$$\n\\begin{aligned}\n&\\max_{\\phi, \\theta} \\mathbb{E}_{\\mathbf{x}\\sim\\mathcal{D}}[\\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})]\\\\\n&\\text{subject to } D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) < \\delta\n\\end{aligned}\n$$\nWe can rewrite it as a Lagrangian with a Lagrangian multiplier $\\beta$ under the\nKKT condition\n. The above optimization problem with only one inequality constraint is equivalent to maximizing the following equation $\\mathcal{F}(\\theta, \\phi, \\beta)$:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta, \\phi, \\beta) &= \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta(D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) - \\delta) & \\\\\n& = \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) + \\beta \\delta & \\\\\n& \\geq \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) & \\scriptstyle{\\text{; Because }\\beta,\\delta\\geq 0}\n\\end{aligned}\n$$\nThe loss function of $\\beta$-VAE is defined as:\n$$\nL_\\text{BETA}(\\phi, \\beta) = - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z}))\n$$\nwhere the Lagrangian multiplier $\\beta$ is considered as a hyperparameter.\nSince the negation of $L_\\text{BETA}(\\phi, \\beta)$ is the lower bound of the Lagrangian $\\mathcal{F}(\\theta, \\phi, \\beta)$. Minimizing the loss is equivalent to maximizing the Lagrangian and thus works for our initial optimization problem.\nWhen $\\beta=1$, it is same as VAE. When $\\beta > 1$, it applies a stronger constraint on the latent bottleneck and limits the representation capacity of $\\mathbf{z}$. For some conditionally independent generative factors, keeping them disentangled is the most efficient representation. Therefore a higher $\\beta$ encourages more efficient latent encoding and further encourages the disentanglement. Meanwhile, a higher $\\beta$ may create a trade-off between reconstruction quality and the extent of disentanglement.\nBurgess, et al. (2017)\ndiscussed the distentangling in $\\beta$-VAE in depth with an inspiration by the\ninformation bottleneck theory\nand further proposed a modification to $\\beta$-VAE to better control the encoding representation capacity.\nVQ-VAE and VQ-VAE-2\n#\nThe\nVQ-VAE\n(“Vector Quantised-Variational AutoEncoder”;\nvan den Oord, et al. 2017\n) model learns a discrete latent variable by the encoder, since discrete representations may be a more natural fit for problems like language, speech, reasoning, etc.\nVector quantisation (VQ) is a method to map $K$-dimensional vectors into a finite set of “code” vectors. The process is very much similar to\nKNN\nalgorithm. The optimal centroid code vector that a sample should be mapped to is the one with minimum euclidean distance.\nLet $\\mathbf{e} \\in \\mathbb{R}^{K \\times D}, i=1, \\dots, K$ be the latent embedding space (also known as “codebook”) in VQ-VAE, where $K$ is the number of latent variable categories and $D$ is the embedding size. An individual embedding vector is $\\mathbf{e}_i \\in \\mathbb{R}^{D}, i=1, \\dots, K$.\nThe encoder output $E(\\mathbf{x}) = \\mathbf{z}_e$ goes through a nearest-neighbor lookup to match to one of $K$ embedding vectors and then this matched code vector becomes the input for the decoder $D(.)$:\n$$\n\\mathbf{z}_q(\\mathbf{x}) = \\text{Quantize}(E(\\mathbf{x})) = \\mathbf{e}_k \\text{ where } k = \\arg\\min_i \\|E(\\mathbf{x}) - \\mathbf{e}_i \\|_2\n$$\nNote that the discrete latent variables can have different shapes in differnet applications; for example, 1D for speech, 2D for image and 3D for video.\nThe architecture of VQ-VAE (Image source:\nvan den Oord, et al. 2017\n)\nBecause argmin() is non-differentiable on a discrete space, the gradients $\\nabla_z L$ from decoder input $\\mathbf{z}_q$ is copied to the encoder output $\\mathbf{z}_e$. Other than reconstruction loss, VQ-VAE also optimizes:\nVQ loss\n: The L2 error between the embedding space and the encoder outputs.\nCommitment loss\n: A measure to encourage the encoder output to stay close to the embedding space and to prevent it from fluctuating too frequently from one code vector to another.\n$$\nL = \\underbrace{\\|\\mathbf{x} - D(\\mathbf{e}_k)\\|_2^2}_{\\textrm{reconstruction loss}} + \n\\underbrace{\\|\\text{sg}[E(\\mathbf{x})] - \\mathbf{e}_k\\|_2^2}_{\\textrm{VQ loss}} + \n\\underbrace{\\beta \\|E(\\mathbf{x}) - \\text{sg}[\\mathbf{e}_k]\\|_2^2}_{\\textrm{commitment loss}}\n$$\nwhere $\\text{sg}[.]$ is the\nstop_gradient\noperator.\nThe embedding vectors in the codebook is updated through EMA (exponential moving average). Given a code vector $\\mathbf{e}_i$, say we have $n_i$ encoder output vectors, $\\{\\mathbf{z}_{i,j}\\}_{j=1}^{n_i}$, that are quantized to $\\mathbf{e}_i$:\n$$\nN_i^{(t)} = \\gamma N_i^{(t-1)} + (1-\\gamma)n_i^{(t)}\\;\\;\\;\n\\mathbf{m}_i^{(t)} = \\gamma \\mathbf{m}_i^{(t-1)} + (1-\\gamma)\\sum_{j=1}^{n_i^{(t)}}\\mathbf{z}_{i,j}^{(t)}\\;\\;\\;\n\\mathbf{e}_i^{(t)} = \\mathbf{m}_i^{(t)} / N_i^{(t)}\n$$\nwhere $(t)$ refers to batch sequence in time. $N_i$ and $\\mathbf{m}_i$ are accumulated vector count and volume, respectively.\nVQ-VAE-2 (\nAli Razavi, et al. 2019\n) is a two-level hierarchical VQ-VAE combined with self-attention autoregressive model.\nStage 1 is to\ntrain a hierarchical VQ-VAE\n: The design of hierarchical latent variables intends to separate local patterns (i.e., texture) from global information (i.e., object shapes). The training of the larger bottom level codebook is conditioned on the smaller top level code too, so that it does not have to learn everything from scratch.\nStage 2 is to\nlearn a prior over the latent discrete codebook\nso that we sample from it and generate images. In this way, the decoder can receive input vectors sampled from a similar distribution as the one in training. A powerful autoregressive model enhanced with multi-headed self-attention layers is used to capture the prior distribution (like\nPixelSNAIL; Chen et al 2017\n).\nConsidering that VQ-VAE-2 depends on discrete latent variables configured in a simple hierarchical setting, the quality of its generated images are pretty amazing.\nArchitecture of hierarchical VQ-VAE and multi-stage image generation. (Image source:\nAli Razavi, et al. 2019\n)\nThe VQ-VAE-2 algorithm. (Image source:\nAli Razavi, et al. 2019\n)\nTD-VAE\n#\nTD-VAE\n(“Temporal Difference VAE”;\nGregor et al., 2019\n) works with sequential data. It relies on three main ideas, described below.\nState-space model as a Markov Chain model.\n1. State-Space Models\nIn (latent) state-space models, a sequence of unobserved hidden states $\\mathbf{z} = (z_1, \\dots, z_T)$ determine the observation states $\\mathbf{x} = (x_1, \\dots, x_T)$. Each time step in the Markov chain model in Fig. 13 can be trained in a similar manner as in Fig. 6, where the intractable posterior $p(z \\vert x)$ is approximated by a function $q(z \\vert x)$.\n2. Belief State\nAn agent should learn to encode all the past states to reason about the future, named as\nbelief state\n, $b_t = belief(x_1, \\dots, x_t) = belief(b_{t-1}, x_t)$. Given this, the distribution of future states conditioned on the past can be written as $p(x_{t+1}, \\dots, x_T \\vert x_1, \\dots, x_t) \\approx p(x_{t+1}, \\dots, x_T \\vert b_t)$. The hidden states in a recurrent policy are used as the agent’s belief state in TD-VAE. Thus we have $b_t = \\text{RNN}(b_{t-1}, x_t)$.\n3. Jumpy Prediction\nFurther, an agent is expected to imagine distant futures based on all the information gathered so far, suggesting the capability of making jumpy predictions, that is, predicting states several steps further into the future.\nRecall what we have learned from the variance lower bound\nabove\n:\n$$\n\\begin{aligned}\n\\log p(x) \n&\\geq \\log p(x) - D_\\text{KL}(q(z|x)\\|p(z|x)) \\\\\n&= \\mathbb{E}_{z\\sim q} \\log p(x|z) - D_\\text{KL}(q(z|x)\\|p(z)) \\\\\n&= \\mathbb{E}_{z \\sim q} \\log p(x|z) - \\mathbb{E}_{z \\sim q} \\log \\frac{q(z|x)}{p(z)} \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x|z) -\\log q(z|x) + \\log p(z)] \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)] \\\\\n\\log p(x) \n&\\geq \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)]\n\\end{aligned}\n$$\nNow let’s model the distribution of the state $x_t$ as a probability function conditioned on all the past states $x_{<t}$ and two latent variables, $z_t$ and $z_{t-1}$, at current time step and one step back:\n$$\n\\log p(x_t|x_{<{t}}) \\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})]\n$$\nContinue expanding the equation:\n$$\n\\begin{aligned}\n& \\log p(x_t|x_{<{t}}) \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|\\color{red}{z_{t-1}}, z_{t}, \\color{red}{x_{<{t}}}) + \\color{blue}{\\log p(z_{t-1}, z_{t}|x_{<{t}})} -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\color{blue}{\\log p(z_{t-1}|x_{<{t}})} + \\color{blue}{\\log p(z_{t}|z_{t-1})} - \\color{green}{\\log q(z_{t-1}, z_t|x_{\\leq t})}] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\log p(z_{t-1}|x_{<{t}}) + \\log p(z_{t}|z_{t-1}) - \\color{green}{\\log q(z_t|x_{\\leq t})} - \\color{green}{\\log q(z_{t-1}|z_t, x_{\\leq t})}]\n\\end{aligned}\n$$\nNotice two things:\nThe\nred\nterms can be ignored according to Markov assumptions.\nThe\nblue\nterm is expanded according to Markov assumptions.\nThe\ngreen\nterm is expanded to include an one-step prediction back to the past as a smoothing distribution.\nPrecisely, there are four types of distributions to learn:\n$p_D(.)$ is the\ndecoder\ndistribution:\n$p(x_t \\mid z_t)$ is the encoder by the common definition;\n$p(x_t \\mid z_t) \\to p_D(x_t \\mid z_t)$;\n$p_T(.)$ is the\ntransition\ndistribution:\n$p(z_t \\mid z_{t-1})$ captures the sequential dependency between latent variables;\n$p(z_t \\mid z_{t-1}) \\to p_T(z_t \\mid z_{t-1})$;\n$p_B(.)$ is the\nbelief\ndistribution:\nBoth $p(z_{t-1} \\mid x_{<t})$ and $q(z_t \\mid x_{\\leq t})$ can use the belief states to predict the latent variables;\n$p(z_{t-1} \\mid x_{<t}) \\to p_B(z_{t-1} \\mid b_{t-1})$;\n$q(z_{t} \\mid x_{\\leq t}) \\to p_B(z_t \\mid b_t)$;\n$p_S(.)$ is the\nsmoothing\ndistribution:\nThe back-to-past smoothing term $q(z_{t-1} \\mid z_t, x_{\\leq t})$ can be rewritten to be dependent of belief states too;\n$q(z_{t-1} \\mid z_t, x_{\\leq t}) \\to  p_S(z_{t-1} \\mid z_t, b_{t-1}, b_t)$;\nTo incorporate the idea of jumpy prediction, the sequential ELBO has to not only work on $t, t+1$, but also two distant timestamp $t_1 < t_2$. Here is the final TD-VAE objective function to maximize:\n$$\nJ_{t_1, t_2} = \\mathbb{E}[\n  \\log p_D(x_{t_2}|z_{t_2}) \n  + \\log p_B(z_{t_1}|b_{t_1}) \n  + \\log p_T(z_{t_2}|z_{t_1}) \n  - \\log p_B(z_{t_2}|b_{t_2}) \n  - \\log p_S(z_{t_1}|z_{t_2}, b_{t_1}, b_{t_2})]\n$$\nA detailed overview of TD-VAE architecture, very nicely done. (Image source:\nTD-VAE paper\n)\nCited as:\n@article{weng2018VAE,\n  title   = \"From Autoencoder to Beta-VAE\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-08-12-vae/\"\n}\nReferences\n#\n[1] Geoffrey E. Hinton, and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nScience 313.5786 (2006): 504-507.\n[2] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[3] Pascal Vincent, et al.\n“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”\n. Journal of machine learning research 11.Dec (2010): 3371-3408.\n[4] Geoffrey E. Hinton, Nitish Srivastava, Alex Krizhevsky, Ilya Sutskever, and Ruslan R. Salakhutdinov. “Improving neural networks by preventing co-adaptation of feature detectors.” arXiv preprint arXiv:1207.0580 (2012).\n[5]\nSparse Autoencoder\nby Andrew Ng.\n[6] Alireza Makhzani, Brendan Frey (2013).\n“k-sparse autoencoder”\n. ICLR 2014.\n[7] Salah Rifai, et al.\n“Contractive auto-encoders: Explicit invariance during feature extraction.”\nICML, 2011.\n[8] Diederik P. Kingma, and Max Welling.\n“Auto-encoding variational bayes.”\nICLR 2014.\n[9]\nTutorial - What is a variational autoencoder?\non jaan.io\n[10] Youtube tutorial:\nVariational Autoencoders\nby Arxiv Insights\n[11]\n“A Beginner’s Guide to Variational Methods: Mean-Field Approximation”\nby Eric Jang.\n[12] Carl Doersch.\n“Tutorial on variational autoencoders.”\narXiv:1606.05908, 2016.\n[13] Irina Higgins, et al.\n\"$\\beta$-VAE: Learning basic visual concepts with a constrained variational framework.\"\nICLR 2017.\n[14] Christopher P. Burgess, et al.\n“Understanding disentangling in beta-VAE.”\nNIPS 2017.\n[15] Aaron van den Oord, et al.\n“Neural Discrete Representation Learning”\nNIPS 2017.\n[16] Ali Razavi, et al.\n“Generating Diverse High-Fidelity Images with VQ-VAE-2”\n. arXiv preprint arXiv:1906.00446 (2019).\n[17] Xi Chen, et al.\n“PixelSNAIL: An Improved Autoregressive Generative Model.”\narXiv preprint arXiv:1712.09763 (2017).\n[18] Karol Gregor, et al.\n“Temporal Difference Variational Auto-Encoder.”\nICLR 2019.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:30Z",
            "title": "From Autoencoder to Beta-VAE | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/cd59f7ee3fdb/code/body-000.txt",
                "chars": 217,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "bytes": 2880250,
                "reused": true,
                "local_path": "papers/repair/d99773f380c6f82310b0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.5663",
                "bytes": 706768,
                "reused": true,
                "local_path": "papers/repair/e1b2d4f9537bfbb215c7.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "bytes": 267801,
                "reused": true,
                "local_path": "papers/repair/6d5b1a69e0c9e22de627.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6114",
                "bytes": 3926758,
                "reused": true,
                "local_path": "papers/repair/24a95827202f9fab26f8.pdf"
              },
              {
                "status": "http_404",
                "url": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "retried_at": "2026-10-20T17:54:22Z"
              },
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "bytes": 259807,
                "reused": true,
                "local_path": "papers/repair/ae05bcdf53e441d54399.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599.pdf",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/ed1564965a62d0f95223.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "bytes": 3122746,
                "reused": true,
                "local_path": "papers/repair/dff42138c902f52546e6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00446",
                "bytes": 6893777,
                "reused": true,
                "local_path": "papers/repair/68bf92a125a336073fe6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.09763",
                "bytes": 1060212,
                "reused": true,
                "local_path": "papers/repair/19837883f1a7b093c101.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03107",
                "bytes": 1744116,
                "reused": true,
                "local_path": "papers/repair/7421e1d74410b7ee80f1.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "retried_at": "2026-10-20T17:54:23Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": true,
                "local_path": "papers/repair/ba774392059407ff35bb.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "bytes": 1392544,
                "reused": true,
                "local_path": "papers/repair/13ac6bde4ea85d886602.pdf"
              },
              {
                "status": "ok",
                "url": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "bytes": 596707,
                "reused": true,
                "local_path": "papers/repair/7c5b86e9a0f9c9cfd6a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.05908",
                "bytes": 880152,
                "reused": true,
                "local_path": "papers/repair/673de34731baf973c156.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/cecf133ac21e33fa774b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00937",
                "bytes": 3174661,
                "reused": true,
                "local_path": "papers/repair/6daef1429a7c6c36146a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33692,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404",
            "raw_html": "attachments/cd59f7ee3fdb/pages/source.html",
            "local_html": "attachments/cd59f7ee3fdb/pages/article.html",
            "body_base_path": "attachments/cd59f7ee3fdb/pages/",
            "body_markdown_path": "attachments/cd59f7ee3fdb/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Autoencoder",
                "label": "the 1980s",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.459.3788&rep=rep1&type=pdf",
                "label": "Hinton & Salakhutdinov, 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dimensionality_reduction",
                "label": "dimensionality reduction",
                "type": "a"
              },
              {
                "href": "https://ai.googleblog.com/2016/09/image-compression-with-neural-networks.html",
                "label": "decompression",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "label": "Hinton, et al. 2012",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/neural-networks-1/",
                "label": "activation functions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.5663",
                "label": "Makhzani and Frey, 2013",
                "type": "a"
              },
              {
                "href": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "label": "Rifai, et al, 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.6114",
                "label": "Kingma & Welling, 2014",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback-Leibler divergence",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2016/08/variational-bayes.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=Sy2fzU9gl",
                "label": "Higgins et al., 2017",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "label": "KKT condition",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.03599.pdf",
                "label": "Burgess, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "information bottleneck theory",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "label": "van den Oord, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "KNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00446",
                "label": "Ali Razavi, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.09763",
                "label": "PixelSNAIL; Chen et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03107",
                "label": "Gregor et al., 2019",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "label": "“Reducing the dimensionality of data with neural networks.”",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "“Extracting and composing robust features with denoising autoencoders.”",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "label": "“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "label": "Sparse Autoencoder",
                "type": "a"
              },
              {
                "href": "https://jaan.io/what-is-variational-autoencoder-vae-tutorial/",
                "label": "Tutorial - What is a variational autoencoder?",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "label": "Variational Autoencoders",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.05908",
                "label": "“Tutorial on variational autoencoders.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.03599",
                "label": "“Understanding disentangling in beta-VAE.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00937",
                "label": "“Neural Discrete Representation Learning”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
          "status": "ok",
          "article_id": "45444954e783",
          "local_path": "series-follow/1600/repair/0adb702ae2c07335adbf.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
              "bytes": 221077,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/aa28a4cc1b3516c1be46.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
              "bytes": 157401,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4199969ec35e7360ae98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
              "bytes": 101972,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/95c24c614030b59aff01.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
              "bytes": 447186,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c2ebec0990753f6d5a87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
              "bytes": 736874,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f32623608491cb056216.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
              "bytes": 529052,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/54028801a0ddfc354538.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
              "bytes": 86758,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/501aa5d6dea1582e9385.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
              "bytes": 32150,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7301ab34ef06aa0e487d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
              "bytes": 313647,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/bacb4aa725276c994c68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
              "bytes": 3106088,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f670e3a31b7940e1d8ef.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "From GAN to WGAN",
            "keywords": "GAN,WGAN,生成模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "publish_date": "2017-08",
            "corpus_stage": "预训练/SFT",
            "notes": "GAN到WGAN的演进综述",
            "id": "45444954e783",
            "collected_at": "2026-10-02T14:13:27",
            "title": "From GAN to WGAN | Lil'Log",
            "body_markdown": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in\nKorean\n!]\n[Updated on 2019-04-18: this post is also available on\narXiv\n.]\nGenerative adversarial network\n(GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.\nHere I would like to explain the maths behind the generative adversarial network framework,  why it is hard to be trained, and finally introduce a modified version of GAN intended to solve the training difficulties.\nKullback–Leibler and Jensen–Shannon Divergence\n#\nBefore we start examining GANs closely, let us first review two metrics for quantifying the similarity between two probability distributions.\n(1)\nKL (Kullback–Leibler) divergence\nmeasures how one probability distribution $p$ diverges from a second expected probability distribution $q$.\n$$\nD_{KL}(p \\| q) = \\int_x p(x) \\log \\frac{p(x)}{q(x)} dx\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nIt is noticeable according to the formula that KL divergence is asymmetric. In cases where $p(x)$ is close to zero, but $q(x)$ is significantly non-zero, the $q$’s effect is disregarded. It could cause buggy results when we just want to measure the similarity between two equally important distributions.\n(2)\nJensen–Shannon Divergence\nis another measure of similarity between two probability distributions, bounded by $[0, 1]$. JS divergence is symmetric (yay!) and more smooth. Check this\nQuora post\nif you are interested in reading more about the comparison between KL divergence and JS divergence.\n$$\nD_{JS}(p \\| q) = \\frac{1}{2} D_{KL}(p \\| \\frac{p + q}{2}) + \\frac{1}{2} D_{KL}(q \\| \\frac{p + q}{2})\n$$\nGiven two Gaussian distribution, $p$ with mean=0 and std=1 and $q$ with mean=1 and std=1. The average of two distributions is labelled as $m=(p+q)/2$. KL divergence $D_{KL}$ is asymmetric but JS divergence $D_{JS}$ is symmetric.\nSome believe (\nHuszar, 2015\n) that one reason behind GANs’ big success is switching the loss function from asymmetric KL divergence in traditional maximum-likelihood approach to symmetric JS divergence. We will discuss more on this point in the next section.\nGenerative Adversarial Network (GAN)\n#\nGAN consists of two models:\nA discriminator $D$ estimates the probability of a given sample coming from the real dataset. It works as a critic and is optimized to tell the fake samples from the real ones.\nA generator $G$ outputs synthetic samples given a noise variable input $z$ ($z$ brings in potential output diversity). It is trained to capture the real data distribution so that its generative samples can be as real as possible, or in other words, can trick the discriminator to offer a high probability.\nArchitecture of a generative adversarial network. (Image source:\nwww.kdnuggets.com/2017/01/generative-...-learning.html\n)\nThese two models compete against each other during the training process: the generator $G$ is trying hard to trick the discriminator, while the critic model $D$ is trying hard not to be cheated. This interesting zero-sum game between two models motivates both to improve their functionalities.\nGiven,\nSymbol\nMeaning\nNotes\n$p_{z}$\nData distribution over noise input $z$\nUsually, just uniform.\n$p_{g}$\nThe generator’s distribution over data $x$\n$p_{r}$\nData distribution over real sample $x$\nOn one hand, we want to make sure the discriminator $D$’s decisions over real data are accurate by maximizing $\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$. Meanwhile, given a fake sample $G(z), z \\sim p_z(z)$, the discriminator is expected to output a probability, $D(G(z))$, close to zero by maximizing $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nOn the other hand, the generator is trained to increase the chances of $D$ producing a high probability for a fake example, thus to minimize $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nWhen combining both aspects together, $D$ and $G$ are playing a\nminimax game\nin which we should optimize the following loss function:\n$$\n\\begin{aligned}\n\\min_G \\max_D L(D, G) \n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{z \\sim p_z(z)} [\\log(1 - D(G(z)))] \\\\\n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{x \\sim p_g(x)} [\\log(1 - D(x)]\n\\end{aligned}\n$$\n($\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$ has no impact on $G$ during gradient descent updates.)\nWhat is the optimal value for D?\n#\nNow we have a well-defined loss function. Let’s first examine what is the best value for $D$.\n$$\nL(G, D) = \\int_x \\bigg( p_{r}(x) \\log(D(x)) + p_g (x) \\log(1 - D(x)) \\bigg) dx\n$$\nSince we are interested in what is the best value of $D(x)$ to maximize $L(G, D)$, let us label\n$$\n\\tilde{x} = D(x), \nA=p_{r}(x), \nB=p_g(x)\n$$\nAnd then what is inside the integral (we can safely ignore the integral because $x$ is sampled over all the possible values) is:\n$$\n\\begin{aligned}\nf(\\tilde{x}) \n& = A log\\tilde{x} + B log(1-\\tilde{x}) \\\\\n\\frac{d f(\\tilde{x})}{d \\tilde{x}}\n& = A \\frac{1}{ln10} \\frac{1}{\\tilde{x}} - B \\frac{1}{ln10} \\frac{1}{1 - \\tilde{x}} \\\\\n& = \\frac{1}{ln10} (\\frac{A}{\\tilde{x}} - \\frac{B}{1-\\tilde{x}}) \\\\\n& = \\frac{1}{ln10} \\frac{A - (A + B)\\tilde{x}}{\\tilde{x} (1 - \\tilde{x})} \\\\\n\\end{aligned}\n$$\nThus, set $\\frac{d f(\\tilde{x})}{d \\tilde{x}} = 0$, we get the best value of the discriminator: $D^*(x) = \\tilde{x}^* = \\frac{A}{A + B} = \\frac{p_{r}(x)}{p_{r}(x) + p_g(x)} \\in [0, 1]$.\nOnce the generator is trained to its optimal, $p_g$ gets very close to $p_{r}$. When $p_g = p_{r}$, $D^*(x)$ becomes $1/2$.\nWhat is the global optimal?\n#\nWhen both $G$ and $D$ are at their optimal values, we have $p_g = p_{r}$ and $D^*(x) = 1/2$ and the loss function becomes:\n$$\n\\begin{aligned}\nL(G, D^*) \n&= \\int_x \\bigg( p_{r}(x) \\log(D^*(x)) + p_g (x) \\log(1 - D^*(x)) \\bigg) dx \\\\\n&= \\log \\frac{1}{2} \\int_x p_{r}(x) dx + \\log \\frac{1}{2} \\int_x p_g(x) dx \\\\\n&= -2\\log2\n\\end{aligned}\n$$\nWhat does the loss function represent?\n#\nAccording to the formula listed in the\nprevious section\n, JS divergence between $p_{r}$ and $p_g$ can be computed as:\n$$\n\\begin{aligned}\nD_{JS}(p_{r} \\| p_g) \n=& \\frac{1}{2} D_{KL}(p_{r} || \\frac{p_{r} + p_g}{2}) + \\frac{1}{2} D_{KL}(p_{g} || \\frac{p_{r} + p_g}{2}) \\\\\n=& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_{r}(x) \\log \\frac{p_{r}(x)}{p_{r} + p_g(x)} dx \\bigg) + \\\\& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_g(x) \\log \\frac{p_g(x)}{p_{r} + p_g(x)} dx \\bigg) \\\\\n=& \\frac{1}{2} \\bigg( \\log4 + L(G, D^*) \\bigg)\n\\end{aligned}\n$$\nThus,\n$$\nL(G, D^*) = 2D_{JS}(p_{r} \\| p_g) - 2\\log2\n$$\nEssentially the loss function of GAN quantifies the similarity between the generative data distribution $p_g$ and the real sample distribution $p_{r}$ by JS divergence when the discriminator is optimal. The best $G^*$ that replicates the real data distribution leads to the minimum $L(G^*, D^*) = -2\\log2$ which is aligned with equations above.\nOther Variations of GAN\n: There are many variations of GANs in different contexts or designed for different tasks. For example, for semi-supervised learning, one idea is to update the discriminator to output real class labels, $1, \\dots, K-1$, as well as one fake class label $K$. The generator model aims to trick the discriminator to output a classification label smaller than $K$.\nTensorflow Implementation\n:\ncarpedm20/DCGAN-tensorflow\nProblems in GANs\n#\nAlthough GAN has shown great success in the realistic image generation, the training is not easy; The process is known to be slow and unstable.\nHard to achieve Nash equilibrium\n#\nSalimans et al. (2016)\ndiscussed the problem with GAN’s gradient-descent-based training procedure. Two models are trained simultaneously to find a\nNash equilibrium\nto a two-player non-cooperative game. However, each model updates its cost independently with no respect to another player in the game. Updating the gradient of both models concurrently cannot guarantee a convergence.\nLet’s check out a simple example to better understand why it is difficult to find a Nash equilibrium in an non-cooperative game. Suppose one player takes control of $x$ to minimize $f_1(x) = xy$, while at the same time the other player constantly updates $y$ to minimize $f_2(y) = -xy$.\nBecause $\\frac{\\partial f_1}{\\partial x} = y$ and $\\frac{\\partial f_2}{\\partial y} = -x$, we update $x$ with $x-\\eta \\cdot y$ and $y$ with $y+ \\eta \\cdot x$ simulitanously in one iteration, where $\\eta$ is the learning rate. Once $x$ and $y$ have different signs, every following gradient update causes huge oscillation and the instability gets worse in time, as shown in\nA simulation of our example for updating $x$ to minimize $xy$ and updating $y$ to minimize $-xy$. The learning rate $\\eta = 0.1$. With more iterations, the oscillation grows more and more unstable.\nLow dimensional supports\n#\nTerm\nExplanation\nManifold\nA topological space that locally resembles Euclidean space near each point. Precisely, when this Euclidean space is of\ndimension $n$\n, the manifold is referred as\n$n$-manifold\n.\nSupport\nA real-valued function $f$ is the subset of the domain containing those elements which are not mapped to\nzero\n.\nArjovsky and Bottou (2017)\ndiscussed the problem of the\nsupports\nof $p_r$ and $p_g$ lying on low dimensional\nmanifolds\nand how it contributes to the instability of GAN training thoroughly in a very theoretical paper\n“Towards principled methods for training generative adversarial networks”\n.\nThe dimensions of many real-world datasets, as represented by $p_r$, only appear to be\nartificially high\n. They have been found to concentrate in a lower dimensional manifold. This is actually the fundamental assumption for\nManifold Learning\n. Thinking of the real world images, once the theme or the contained object is fixed, the images have a lot of restrictions to follow, i.e., a dog should have two ears and a tail, and a skyscraper should have a straight and tall body, etc. These restrictions keep images aways from the possibility of having a high-dimensional free form.\n$p_g$ lies in a low dimensional manifolds, too. Whenever the generator is asked to a much larger image like 64x64 given a small dimension, such as 100, noise variable input $z$, the distribution of colors over these 4096 pixels has been defined by the small 100-dimension random number vector and can hardly fill up the whole high dimensional space.\nBecause both $p_g$ and $p_r$ rest in low dimensional manifolds, they are almost certainly gonna be disjoint (See Fig. 4). When they have disjoint supports, we are always capable of finding a perfect discriminator that separates real and fake samples 100% correctly. Check the\npaper\nif you are curious about the proof.\nLow dimensional manifolds in high dimension space can hardly have overlaps. (Left) Two lines in a three-dimension space. (Right) Two surfaces in a three-dimension space.\nVanishing gradient\n#\nWhen the discriminator is perfect, we are guaranteed with $D(x) = 1, \\forall x \\in p_r$ and $D(x) = 0, \\forall x \\in p_g$. Therefore the loss function $L$ falls to zero and we end up with no gradient to update the loss during learning iterations. Fig. 5 demonstrates an experiment when the discriminator gets better, the gradient vanishes fast.\nFirst, a DCGAN is trained for 1, 10 and 25 epochs. Then, with the **generator fixed**, a discriminator is trained from scratch and measure the gradients with the original cost function. We see the gradient norms **decay quickly** (in log scale), in the best case 5 orders of magnitude after 4000 discriminator iterations. (Image source:\nArjovsky and Bottou, 2017\n)\nAs a result, training a GAN faces a\ndilemma\n:\nIf the discriminator behaves badly, the generator does not have accurate feedback and the loss function cannot represent the reality.\nIf the discriminator does a great job, the gradient of the loss function drops down to close to zero and the learning becomes super slow or even jammed.\nThis dilemma clearly is capable to make the GAN training very tough.\nMode collapse\n#\nDuring the training, the generator may collapse to a setting where it always produces same outputs. This is a common failure case for GANs, commonly referred to as\nMode Collapse\n. Even though the generator might be able to trick the corresponding discriminator, it fails to learn to represent the complex real-world data distribution and gets stuck in a small space with extremely low variety.\nA DCGAN model is trained with an MLP network with 4 layers, 512 units and ReLU activation function, configured to lack a strong inductive bias for image generation. The results shows a significant degree of mode collapse. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nLack of a proper evaluation metric\n#\nGenerative adversarial networks are not born with a good objection function that can inform us the training progress. Without a good evaluation metric, it is like working in the dark. No good sign to tell when to stop; No good indicator to compare the performance of multiple models.\nImproved GAN Training\n#\nThe following suggestions are proposed to help stabilize and improve the training of GANs.\nFirst five methods are practical techniques to achieve faster convergence of GAN training, proposed in\n“Improve Techniques for Training GANs”\n.\nThe last two are proposed in\n“Towards principled methods for training generative adversarial networks”\nto solve the problem of disjoint distributions.\n(1)\nFeature Matching\nFeature matching suggests to optimize the discriminator to inspect whether the generator’s output matches expected statistics of the real samples. In such a scenario, the new loss function is defined as $| \\mathbb{E}_{x \\sim p_r} f(x) - \\mathbb{E}_{z \\sim p_z(z)}f(G(z)) |_2^2 $, where $f(x)$ can be any computation of statistics of features, such as mean or median.\n(2)\nMinibatch Discrimination\nWith minibatch discrimination, the discriminator is able to digest the relationship between training data points in one batch, instead of processing each point independently.\nIn one minibatch, we approximate the closeness between every pair of samples, $c(x_i, x_j)$, and get the overall summary of one data point by summing up how close it is to other samples in the same batch, $o(x_i) = \\sum_{j} c(x_i, x_j)$. Then $o(x_i)$ is explicitly added to the input of the model.\n(3)\nHistorical Averaging\nFor both models, add $ | \\Theta - \\frac{1}{t} \\sum_{i=1}^t \\Theta_i |^2 $ into the loss function, where $\\Theta$ is the model parameter and $\\Theta_i$ is how the parameter is configured at the past training time $i$. This addition piece penalizes the training speed when $\\Theta$ is changing too dramatically in time.\n(4)\nOne-sided Label Smoothing\nWhen feeding the discriminator, instead of providing 1 and 0 labels, use soften values such as 0.9 and 0.1. It is shown to reduce the networks’ vulnerability.\n(5)\nVirtual Batch Normalization\n(VBN)\nEach data sample is normalized based on a fixed batch (\n“reference batch”\n) of data rather than within its minibatch. The reference batch is chosen once at the beginning and stays the same through the training.\nTheano Implementation\n:\nopenai/improved-gan\n(6)\nAdding Noises\n.\nBased on the discussion in the\nprevious section\n, we now know $p_r$ and $p_g$ are disjoint in a high dimensional space and it causes the problem of vanishing gradient. To artificially “spread out” the distribution and to create higher chances for two probability distributions to have overlaps, one solution is to add continuous noises onto the inputs of the discriminator $D$.\n(7)\nUse Better Metric of Distribution Similarity\nThe loss function of the vanilla GAN measures the JS divergence between the distributions of $p_r$ and $p_g$. This metric fails to provide a meaningful value when two distributions are disjoint.\nWasserstein metric\nis proposed to replace JS divergence because it has a much smoother value space. See more in the next section.\nWasserstein GAN (WGAN)\n#\nWhat is Wasserstein distance?\n#\nWasserstein Distance\nis a measure of the distance between two probability distributions.\nIt is also called\nEarth Mover’s distance\n, short for EM distance, because informally it can be interpreted as the minimum energy cost of moving and transforming a pile of dirt in the shape of one probability distribution to the shape of the other distribution. The cost is quantified by: the amount of dirt moved x the moving distance.\nLet us first look at a simple case where the probability domain is\ndiscrete\n. For example, suppose we have two distributions $P$ and $Q$, each has four piles of dirt and both have ten shovelfuls of dirt in total. The numbers of shovelfuls in each dirt pile are assigned as follows:\n$$\n\\begin{aligned}\n& P_1 = 3, P_2 = 2, P_3 = 1, P_4 = 4\\\\\n& Q_1 = 1, Q_2 = 2, Q_3 = 4, Q_4 = 3\n\\end{aligned}\n$$\nIn order to change $P$ to look like $Q$, as illustrated in Fig. 7, we:\nFirst move 2 shovelfuls from $P_1$ to $P_2$ => $(P_1, Q_1)$ match up.\nThen move 2 shovelfuls from $P_2$ to $P_3$ => $(P_2, Q_2)$ match up.\nFinally move 1 shovelfuls from $Q_3$ to $Q_4$ => $(P_3, Q_3)$ and $(P_4, Q_4)$ match up.\nIf we label the cost to pay to make $P_i$ and $Q_i$ match as $\\delta_i$, we would have $\\delta_{i+1} = \\delta_i + P_i - Q_i$ and in the example:\n$$\n\\begin{aligned}\n\\delta_0 &= 0\\\\\n\\delta_1 &= 0 + 3 - 1 = 2\\\\\n\\delta_2 &= 2 + 2 - 2 = 2\\\\\n\\delta_3 &= 2 + 1 - 4 = -1\\\\\n\\delta_4 &= -1 + 4 - 3 = 0\n\\end{aligned}\n$$\nFinally the Earth Mover’s distance is $W = \\sum \\vert \\delta_i \\vert = 5$.\nStep-by-step plan of moving dirt between piles in $P$ and $Q$ to make them match.\nWhen dealing with the continuous probability domain, the distance formula becomes:\n$$\nW(p_r, p_g) = \\inf_{\\gamma \\sim \\Pi(p_r, p_g)} \\mathbb{E}_{(x, y) \\sim \\gamma}[\\| x-y \\|]\n$$\nIn the formula above, $\\Pi(p_r, p_g)$ is the set of all possible joint probability distributions between $p_r$ and $p_g$. One joint distribution $\\gamma \\in \\Pi(p_r, p_g)$ describes one dirt transport plan, same as the discrete example above, but in the continuous probability space. Precisely $\\gamma(x, y)$ states the percentage of dirt should be transported from point $x$ to $y$ so as to make $x$ follows the same probability distribution of $y$. That’s why the marginal distribution over $x$ adds up to $p_g$, $\\sum_{x} \\gamma(x, y) = p_g(y)$ (Once we finish moving the planned amount of dirt from every possible $x$ to the target $y$, we end up with exactly what $y$ has according to $p_g$.) and vice versa $\\sum_{y} \\gamma(x, y) = p_r(x)$.\nWhen treating $x$ as the starting point and $y$ as the destination, the total amount of dirt moved is $\\gamma(x, y)$ and the travelling distance is $| x-y |$ and thus the cost is $\\gamma(x, y) \\cdot | x-y |$. The expected cost averaged across all the $(x,y)$ pairs can be easily computed as:\n$$\n\\sum_{x, y} \\gamma(x, y) \\| x-y \\| \n= \\mathbb{E}_{x, y \\sim \\gamma} \\| x-y \\|\n$$\nFinally, we take the minimum one among the costs of all dirt moving solutions as the EM distance. In the definition of Wasserstein distance, the $\\inf$ (\ninfimum\n, also known as\ngreatest lower bound\n) indicates that we are only interested in the smallest cost.\nWhy Wasserstein is better than JS or KL divergence?\n#\nEven when two distributions are located in lower dimensional manifolds without overlaps, Wasserstein distance can still provide a meaningful and smooth representation of the distance in-between.\nThe WGAN paper exemplified the idea with a simple example.\nSuppose we have two probability distributions, $P$ and $Q$:\n$$\n\\forall (x, y) \\in P, x = 0 \\text{ and } y \\sim U(0, 1)\\\\\n\\forall (x, y) \\in Q, x = \\theta, 0 \\leq \\theta \\leq 1 \\text{ and } y \\sim U(0, 1)\\\\\n$$\nThere is no overlap between $P$ and $Q$ when $\\theta \\neq 0$.\nWhen $\\theta \\neq 0$:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{KL}(Q \\| P) &= \\sum_{x=\\theta, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{JS}(P, Q) &= \\frac{1}{2}(\\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2} + \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2}) = \\log 2\\\\\nW(P, Q) &= |\\theta|\n\\end{aligned}\n$$\nBut when $\\theta = 0$, two distributions are fully overlapped:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= D_{KL}(Q \\| P) = D_{JS}(P, Q) = 0\\\\\nW(P, Q) &= 0 = \\lvert \\theta \\rvert\n\\end{aligned}\n$$\n$D_{KL}$ gives us inifity when two distributions are disjoint. The value of $D_{JS}$ has sudden jump, not differentiable at $\\theta = 0$. Only Wasserstein metric provides a smooth measure, which is super helpful for a stable learning process using gradient descents.\nUse Wasserstein distance as GAN loss function\n#\nIt is intractable to exhaust all the possible joint distributions in $\\Pi(p_r, p_g)$ to compute $\\inf_{\\gamma \\sim \\Pi(p_r, p_g)}$. Thus the authors proposed a smart transformation of the formula based on the Kantorovich-Rubinstein duality to:\n$$\nW(p_r, p_g) = \\frac{1}{K} \\sup_{\\| f \\|_L \\leq K} \\mathbb{E}_{x \\sim p_r}[f(x)] - \\mathbb{E}_{x \\sim p_g}[f(x)]\n$$\nwhere $\\sup$ (\nsupremum\n) is the opposite of $inf$ (infimum); we want to measure the least upper bound or, in even simpler words, the maximum value.\nLipschitz continuity?\nThe function $f$ in the new form of Wasserstein metric is demanded to satisfy $| f |_L \\leq K$, meaning it should be\nK-Lipschitz continuous\n.\nA real-valued function $f: \\mathbb{R} \\rightarrow \\mathbb{R}$ is called $K$-Lipschitz continuous if there exists a real constant $K \\geq 0$ such that, for all $x_1, x_2 \\in \\mathbb{R}$,\n$$\n\\lvert f(x_1) - f(x_2) \\rvert \\leq K \\lvert x_1 - x_2 \\rvert\n$$\nHere $K$ is known as a Lipschitz constant for function $f(.)$. Functions that are everywhere continuously differentiable is Lipschitz continuous, because the derivative, estimated as $\\frac{\\lvert f(x_1) - f(x_2) \\rvert}{\\lvert x_1 - x_2 \\rvert}$, has bounds. However, a Lipschitz continuous function may not be everywhere differentiable, such as $f(x) = \\lvert x \\rvert$.\nExplaining how the transformation happens on the Wasserstein distance formula is worthy of a long post by itself, so I skip the details here. If you are interested in how to compute Wasserstein metric using linear programming, or how to transfer Wasserstein metric into its dual form according to the Kantorovich-Rubinstein Duality, read this\nawesome post\n.\nSuppose this function $f$ comes from a family of K-Lipschitz continuous functions, $\\{ f_w \\}_{w \\in W}$, parameterized by $w$. In the modified Wasserstein-GAN, the “discriminator” model is used to learn $w$ to find a good $f_w$ and the loss function is configured as measuring the Wasserstein distance between $p_r$ and $p_g$.\n$$\nL(p_r, p_g) = W(p_r, p_g) = \\max_{w \\in W} \\mathbb{E}_{x \\sim p_r}[f_w(x)] - \\mathbb{E}_{z \\sim p_r(z)}[f_w(g_\\theta(z))]\n$$\nThus the “discriminator” is not a direct critic of telling the fake samples apart from the real ones anymore. Instead, it is trained to learn a $K$-Lipschitz continuous function to help compute Wasserstein distance. As the loss function decreases in the training, the Wasserstein distance gets smaller and the generator model’s output grows closer to the real data distribution.\nOne big problem is to maintain the $K$-Lipschitz continuity of $f_w$ during the training in order to make everything work out. The paper presents a simple but very practical trick: After every gradient update, clamp the weights $w$ to a small window, such as $[-0.01, 0.01]$, resulting in a compact parameter space $W$ and thus $f_w$ obtains its lower and upper bounds to preserve the Lipschitz continuity.\nAlgorithm of Wasserstein generative adversarial network. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nCompared to the original GAN algorithm, the WGAN undertakes the following changes:\nAfter every gradient update on the critic function, clamp the weights to a small fixed range, $[-c, c]$.\nUse a new loss function derived from the Wasserstein distance, no logarithm anymore. The “discriminator” model does not play as a direct critic but a helper for estimating the Wasserstein metric between real and generated data distribution.\nEmpirically the authors recommended\nRMSProp\noptimizer on the critic, rather than a momentum based optimizer such as\nAdam\nwhich could cause instability in the model training. I haven’t seen clear theoretical explanation on this point through.\nSadly, Wasserstein GAN is not perfect. Even the authors of the original WGAN paper mentioned that\n“Weight clipping is a clearly terrible way to enforce a Lipschitz constraint”\n(Oops!). WGAN still suffers from unstable training, slow convergence after weight clipping (when clipping window is too large), and vanishing gradients (when clipping window is too small).\nSome improvement, precisely replacing weight clipping with\ngradient penalty\n, has been discussed in\nGulrajani et al. 2017\n. I will leave this to a future post.\nExample: Create New Pokemons!\n#\nJust for fun, I tried out\ncarpedm20/DCGAN-tensorflow\non a tiny dataset,\nPokemon sprites\n. The dataset only has 900-ish pokemon images, including different levels of same pokemon species.\nLet’s check out what types of new pokemons the model is able to create.\nUnfortunately due to the tiny training data, the new pokemons only have rough shapes without details. The shapes and colors do look better with more training epoches! Hooray!\nTrain\ncarpedm20/DCGAN-tensorflow\non a set of Pokemon sprite images. The sample outputs are listed after training epoches = 7, 21, 49.\nIf you are interested in a commented version of\ncarpedm20/DCGAN-tensorflow\nand how to modify it to train WGAN and WGAN with gradient penalty, check\nlilianweng/unified-gan-tensorflow\n.\nCited as:\n@article{weng2017gan,\n  title   = \"From GAN to WGAN\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-08-20-gan/\"\n}\nOR\n@misc{weng2019gan,\n    title={From GAN to WGAN},\n    author={Lilian Weng},\n    year={2019},\n    eprint={1904.08994},\n    archivePrefix={arXiv},\n    primaryClass={cs.LG}\n}\nReferences\n#\n[1] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.\n[2] Tim Salimans, et al.\n“Improved techniques for training gans.”\nNIPS 2016.\n[3] Martin Arjovsky and Léon Bottou.\n“Towards principled methods for training generative adversarial networks.”\narXiv preprint arXiv:1701.04862 (2017).\n[4] Martin Arjovsky, Soumith Chintala, and Léon Bottou.\n“Wasserstein GAN.”\narXiv preprint arXiv:1701.07875 (2017).\n[5] Ishaan Gulrajani, Faruk Ahmed, Martin Arjovsky, Vincent Dumoulin, Aaron Courville.\nImproved training of wasserstein gans.\narXiv preprint arXiv:1704.00028 (2017).\n[6]\nComputing the Earth Mover’s Distance under Transformations\n[7]\nWasserstein GAN and the Kantorovich-Rubinstein Duality\n[8]\nzhuanlan.zhihu.com/p/25071913\n[9] Ferenc Huszár.\n“How (not) to Train your Generative Model: Scheduled Sampling, Likelihood, Adversary?.”\narXiv preprint arXiv:1511.05101 (2015).",
            "metadata": {
              "title": "From GAN to WGAN | Lil'Log",
              "description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "keywords": "gan, long-read, generative-model, image-generation, math-heavy",
              "author": "Lilian Weng",
              "og:title": "From GAN to WGAN",
              "og:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
              "twitter:card": "summary",
              "twitter:title": "From GAN to WGAN",
              "twitter:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "article:section": "posts",
              "article:published_time": "2017-08-20T00:00:00+00:00",
              "article:modified_time": "2017-08-20T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/45444954e783/code/body-000.txt",
                "chars": 205,
                "language": "text"
              },
              {
                "file": "attachments/45444954e783/code/body-001.txt",
                "chars": 171,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "bytes": 221077,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-aa28a4cc1b3516c1be46.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "bytes": 157401,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-4199969ec35e7360ae98.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "bytes": 101972,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-95c24c614030b59aff01.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "bytes": 447186,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-c2ebec0990753f6d5a87.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "bytes": 736874,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f32623608491cb056216.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "bytes": 529052,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-54028801a0ddfc354538.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "bytes": 86758,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-501aa5d6dea1582e9385.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "bytes": 32150,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-7301ab34ef06aa0e487d.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "bytes": 313647,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-bacb4aa725276c994c68.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "bytes": 3106088,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f670e3a31b7940e1d8ef.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/yjucho1/articles/blob/master/fromGANtoWGAN/readme.md",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.08994",
                "label": "arXiv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL (Kullback–Leibler) divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence",
                "label": "Jensen–Shannon Divergence",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/Why-isnt-the-Jensen-Shannon-divergence-used-more-often-than-the-Kullback-Leibler-since-JS-is-symmetric-thus-possibly-a-better-indicator-of-distance",
                "label": "Quora post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.05101.pdf",
                "label": "Huszar, 2015",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "www.kdnuggets.com/2017/01/generative-...-learning.html",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "previous section",
                "type": "a"
              },
              {
                "href": "https://github.com/carpedm20/DCGAN-tensorflow",
                "label": "carpedm20/DCGAN-tensorflow",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "label": "Salimans et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nash_equilibrium",
                "label": "Nash equilibrium",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Manifold",
                "label": "Manifold",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Support_(mathematics)",
                "label": "Support",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.04862.pdf",
                "label": "Arjovsky and Bottou (2017)",
                "type": "a"
              },
              {
                "href": "http://scikit-learn.org/stable/modules/manifold.html",
                "label": "Manifold Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07875.pdf",
                "label": "Arjovsky, Chintala, & Bottou, 2017.",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/improved-gan",
                "label": "openai/improved-gan",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wasserstein_metric",
                "label": "Wasserstein metric",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Infimum_and_supremum",
                "label": "infimum",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lipschitz_continuity",
                "label": "K-Lipschitz continuous",
                "type": "a"
              },
              {
                "href": "https://vincentherrmann.github.io/blog/wasserstein/",
                "label": "awesome post",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "label": "RMSProp",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6980v8",
                "label": "Adam",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1704.00028.pdf",
                "label": "Gulrajani et al. 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/PokeAPI/sprites/",
                "label": "Pokemon sprites",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/unified-gan-tensorflow",
                "label": "lilianweng/unified-gan-tensorflow",
                "type": "a"
              },
              {
                "href": "http://robotics.stanford.edu/~scohen/research/emdg/emdg.html",
                "label": "Computing the Earth Mover’s Distance under Transformations",
                "type": "a"
              },
              {
                "href": "https://zhuanlan.zhihu.com/p/25071913",
                "label": "zhuanlan.zhihu.com/p/25071913",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.08994",
                "bytes": 2372969,
                "reused": false,
                "local_path": "papers/repair/a08caad93b55901c5b6f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": false,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05101.pdf",
                "bytes": 505788,
                "reused": false,
                "local_path": "papers/repair/057d39e637c6097bcd7a.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "bytes": 2639054,
                "reused": false,
                "local_path": "papers/repair/762153e376c22f644d34.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.04862.pdf",
                "bytes": 566179,
                "reused": false,
                "local_path": "papers/repair/e9832d130ee863bb324f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07875.pdf",
                "bytes": 8834587,
                "reused": false,
                "local_path": "papers/repair/941e1ba609c7c19a8af8.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "bytes": 546843,
                "reused": false,
                "local_path": "papers/repair/7b52598737bfafc8deab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6980v8",
                "bytes": 619544,
                "reused": false,
                "local_path": "papers/repair/0a612e9d0294ad8485d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00028.pdf",
                "bytes": 6187582,
                "reused": false,
                "local_path": "papers/repair/e6aa0075133ef9410890.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 27088,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/45444954e783/pages/source.html",
            "local_html": "attachments/45444954e783/pages/article.html",
            "body_base_path": "attachments/45444954e783/pages/",
            "body_markdown_path": "attachments/45444954e783/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
          "status": "partial",
          "article_id": "a8dc6bf17c71",
          "local_path": "series-follow/1600/repair/3d08c3e2cf07a50c284b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
              "bytes": 1548239,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/23d602a28b9d9dda6fe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
              "bytes": 665187,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/11419d5ec12fba3fb7f9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
              "bytes": 730525,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/34f37f1d8bf391fe9f42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
              "bytes": 808103,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/851555a6cfa04864e872.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
              "bytes": 184486,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1195100b0c6841a237dd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
              "bytes": 194344,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c47eeb17ebb22f866942.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
              "bytes": 273207,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9ae2425c1e62b530a443.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
              "bytes": 174582,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cb826c25071414ad89e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
              "bytes": 405772,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0167fe1ca07386abf1d2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
              "bytes": 1245251,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ae1778af670dfaca75e8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
              "bytes": 397702,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/9baa7ed8723c2cae889a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
              "bytes": 102014,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f1b0701dad5bcf83ef5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
              "bytes": 195622,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/7f2ae4aa3936d2a466d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
              "bytes": 286187,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d947284bd0373951e25d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
              "bytes": 124913,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/830017a377b95ff33b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
              "bytes": 1295521,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d0137fe96ca3220fcf1f.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Meta-Learning: Learning to Learn Fast",
            "keywords": "元学习,小样本,MAML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "publish_date": "2018-11",
            "corpus_stage": "预训练/SFT",
            "notes": "元学习综述",
            "id": "a8dc6bf17c71",
            "collected_at": "2026-10-02T14:13:37",
            "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
            "body_markdown": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in\nChinese\n!]\nA good machine learning model often requires training with a large number of samples. Humans, in contrast, learn new concepts and skills much faster and more efficiently. Kids who have seen cats and birds only a few times can quickly tell them apart. People who know how to ride a bike are likely to discover the way to ride a motorcycle fast with little or even no demonstration. Is it possible to design a machine learning model with similar properties — learning new concepts and skills fast with a few training examples? That’s essentially what\nmeta-learning\naims to solve.\nWe expect a good meta-learning model capable of well adapting or generalizing to new tasks and new environments that have never been encountered during training time. The adaptation process, essentially a mini learning session, happens during test but with a limited exposure to the new task configurations. Eventually, the adapted model can complete new tasks. This is why meta-learning is also known as\nlearning to learn\n.\nThe tasks can be any well-defined family of machine learning problems: supervised learning, reinforcement learning, etc. For example, here are a couple concrete meta-learning tasks:\nA classifier trained on non-cat images can tell whether a given image contains a cat after seeing a handful of cat pictures.\nA game bot is able to quickly master a new game.\nA mini robot completes the desired task on an uphill surface during test even through it was only trained in a flat surface environment.\nDefine the Meta-Learning Problem\n#\nIn this post, we focus on the case when each desired task is a supervised learning problem like image classification. There is a lot of interesting literature on meta-learning with reinforcement learning problems (aka “Meta Reinforcement Learning”), but we would not cover them here.\nA Simple View\n#\nA good meta-learning model should be trained over a variety of learning tasks and optimized for the best performance on a distribution of tasks, including potentially unseen tasks. Each task is associated with a dataset $\\mathcal{D}$, containing both feature vectors and true labels. The optimal model parameters are:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\mathcal{D}\\sim p(\\mathcal{D})} [\\mathcal{L}_\\theta(\\mathcal{D})]\n$$\nIt looks very similar to a normal learning task, but\none dataset\nis considered as\none data sample\n.\nFew-shot classification\nis an instantiation of meta-learning in the field of supervised learning. The dataset $\\mathcal{D}$ is often split into two parts, a support set $S$ for learning and a prediction set $B$ for training or testing, $\\mathcal{D}=\\langle S, B\\rangle$. Often we consider a\nK-shot N-class classification\ntask: the support set contains K labelled examples for each of N classes.\nAn example of 4-shot 2-class image classification. (Image thumbnails are from\nPinterest\n)\nTraining in the Same Way as Testing\n#\nA dataset $\\mathcal{D}$ contains pairs of feature vectors and labels, $\\mathcal{D} = \\{(\\mathbf{x}_i, y_i)\\}$ and each label belongs to a known label set $\\mathcal{L}^\\text{label}$.  Let’s say, our classifier $f_\\theta$ with parameter $\\theta$ outputs a probability of a data point belonging to the class $y$ given the feature vector $\\mathbf{x}$, $P_\\theta(y\\vert\\mathbf{x})$.\nThe optimal parameters should maximize the probability of true labels across multiple training batches $B \\subset \\mathcal{D}$:\n$$\n\\begin{aligned}\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{(\\mathbf{x}, y)\\in \\mathcal{D}}[P_\\theta(y \\vert \\mathbf{x})] &\\\\\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{B\\subset \\mathcal{D}}[\\sum_{(\\mathbf{x}, y)\\in B}P_\\theta(y \\vert \\mathbf{x})] & \\scriptstyle{\\text{; trained with mini-batches.}}\n\\end{aligned}\n$$\nIn few-shot classification, the goal is to reduce the prediction error on data samples with unknown labels given a small support set for “fast learning” (think of how “fine-tuning” works). To make the training process mimics what happens during inference, we would like to “fake” datasets with a subset of labels to avoid exposing all the labels to the model and modify the optimization procedure accordingly to encourage fast learning:\nSample a subset of labels, $L\\subset\\mathcal{L}^\\text{label}$.\nSample a support set $S^L \\subset \\mathcal{D}$ and a training batch $B^L \\subset \\mathcal{D}$. Both of them only contain data points with labels belonging to the sampled label set $L$, $y \\in L, \\forall (x, y) \\in S^L, B^L$.\nThe support set is part of the model input.\nThe final optimization uses the mini-batch $B^L$ to compute the loss and update the model parameters through backpropagation, in the same way as how we use it in the supervised learning.\nYou may consider each pair of sampled dataset $(S^L, B^L)$ as one data point. The model is trained such that it can generalize to other datasets.  Symbols in red are added for meta-learning in addition to the supervised learning objective.\n$$\n\\theta = \\arg\\max_\\theta \\color{red}{E_{L\\subset\\mathcal{L}}[} E_{\\color{red}{S^L \\subset\\mathcal{D}, }B^L \\subset\\mathcal{D}} [\\sum_{(x, y)\\in B^L} P_\\theta(x, y\\color{red}{, S^L})] \\color{red}{]}\n$$\nThe idea is to some extent similar to using a pre-trained model in image classification (ImageNet) or language modeling (big text corpora) when only a limited set of task-specific data samples are available. Meta-learning takes this idea one step further, rather than fine-tuning according to one down-steam task, it optimizes the model to be good at many, if not all.\nLearner and Meta-Learner\n#\nAnother popular view of meta-learning decomposes the model update into two stages:\nA classifier $f_\\theta$ is the “learner” model, trained for operating a given task;\nIn the meantime, a optimizer $g_\\phi$ learns how to update the learner model’s parameters via the support set $S$, $\\theta’ = g_\\phi(\\theta, S)$.\nThen in final optimization step, we need to update both $\\theta$ and $\\phi$ to maximize:\n$$\n\\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})]]\n$$\nCommon Approaches\n#\nThere are three common approaches to meta-learning: metric-based, model-based, and optimization-based. Oriol Vinyals has a nice summary in his\ntalk\nat meta-learning symposium @ NIPS 2018:\n| ————- | ————- | ————- | ————- |\nModel-based\nMetric-based\nOptimization-based\nKey idea\nRNN; memory\nMetric learning\nGradient descent\nHow $P_\\theta(y \\vert \\mathbf{x})$ is modeled?\n$f_\\theta(\\mathbf{x}, S)$\n$\\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i$ (*)\n$P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})$\n(*) $k_\\theta$ is a kernel function measuring the similarity between $\\mathbf{x}_i$ and $\\mathbf{x}$.\nNext we are gonna review classic models in each approach.\nMetric-Based\n#\nThe core idea in metric-based meta-learning is similar to nearest neighbors algorithms (i.e.,\nk-NN\nclassificer and\nk-means\nclustering) and\nkernel density estimation\n. The predicted probability over a set of known labels $y$ is a weighted sum of labels of support set samples. The weight is generated by a kernel function $k_\\theta$, measuring the similarity between two data samples.\n$$\nP_\\theta(y \\vert \\mathbf{x}, S) = \\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i \n$$\nTo learn a good kernel is crucial to the success of a metric-based meta-learning model.\nMetric learning\nis well aligned with this intention, as it aims to learn a metric or distance function over objects. The notion of a good metric is problem-dependent. It should represent the relationship between inputs in the task space and facilitate problem solving.\nAll the models introduced below learn embedding vectors of input data explicitly and use them to design proper kernel functions.\nConvolutional Siamese Neural Network\n#\nThe\nSiamese Neural Network\nis composed of two twin networks and their outputs are jointly trained on top with a function to learn the relationship between pairs of input data samples. The twin networks are identical, sharing the same weights and network parameters. In other words, both refer to the same embedding network that learns an efficient embedding to reveal relationship between pairs of data points.\nKoch, Zemel & Salakhutdinov (2015)\nproposed a method to use the siamese neural network to do one-shot image classification. First, the siamese network is trained for a verification task for telling whether two input images are in the same class. It outputs the probability of two images belonging to the same class. Then, during test time, the siamese network processes all the image pairs between a test image and every image in the support set. The final prediction is the class of the support image with the highest probability.\nThe architecture of convolutional siamese neural network for few-show image classification.\nFirst, convolutional siamese network learns to encode two images into feature vectors via a embedding function $f_\\theta$ which contains a couple of convolutional layers.\nThe L1-distance between two embeddings is $\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert$.\nThe distance is converted to a probability $p$ by a linear feedforward layer and sigmoid. It is the probability of whether two images are drawn from the same class.\nIntuitively the loss is cross entropy because the label is binary.\n$$\n\\begin{aligned}\np(\\mathbf{x}_i, \\mathbf{x}_j) &= \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert) \\\\\n\\mathcal{L}(B) &= \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} \\mathbf{1}_{y_i=y_j}\\log p(\\mathbf{x}_i, \\mathbf{x}_j) + (1-\\mathbf{1}_{y_i=y_j})\\log (1-p(\\mathbf{x}_i, \\mathbf{x}_j))\n\\end{aligned}\n$$\nImages in the training batch $B$ can be augmented with distortion. Of course, you can replace the L1 distance with other distance metric, L2, cosine, etc. Just make sure they are differential and then everything else works the same.\nGiven a support set $S$ and a test image $\\mathbf{x}$, the final predicted class is:\n$$\n\\hat{c}_S(\\mathbf{x}) = c(\\arg\\max_{\\mathbf{x}_i \\in S} P(\\mathbf{x}, \\mathbf{x}_i))\n$$\nwhere $c(\\mathbf{x})$ is the class label of an image $\\mathbf{x}$ and $\\hat{c}(.)$ is the predicted label.\nThe assumption is that the learned embedding can be generalized to be useful for measuring the distance between images of unknown categories. This is the same assumption behind transfer learning via the adoption of a pre-trained model; for example, the convolutional features learned in the model pre-trained with ImageNet are expected to help other image tasks. However, the benefit of a pre-trained model decreases when the new task diverges from the original task that the model was trained on.\nMatching Networks\n#\nThe task of\nMatching Networks\n(\nVinyals et al., 2016\n) is to learn a classifier $c_S$ for any given (small) support set $S=\\{x_i, y_i\\}_{i=1}^k$ (\nk-shot\nclassification). This classifier defines a probability distribution over output labels $y$ given a test example $\\mathbf{x}$. Similar to other metric-based models, the classifier output is defined as a sum of labels of support samples weighted by attention kernel $a(\\mathbf{x}, \\mathbf{x}_i)$ - which should be proportional to the similarity between $\\mathbf{x}$ and $\\mathbf{x}_i$.\nThe architecture of Matching Networks. (Image source:\noriginal paper\n)\n$$\nc_S(\\mathbf{x}) = P(y \\vert \\mathbf{x}, S) = \\sum_{i=1}^k a(\\mathbf{x}, \\mathbf{x}_i) y_i\n\\text{, where }S=\\{(\\mathbf{x}_i, y_i)\\}_{i=1}^k\n$$\nThe attention kernel depends on two embedding functions, $f$ and $g$, for encoding the test sample and the support set samples respectively. The attention weight between two data points is the cosine similarity, $\\text{cosine}(.)$, between their embedding vectors, normalized by softmax:\n$$\na(\\mathbf{x}, \\mathbf{x}_i) = \\frac{\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_i))}{\\sum_{j=1}^k\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_j))}\n$$\nSimple Embedding\n#\nIn the simple version, an embedding function is a neural network with a single data sample as input. Potentially we can set $f=g$.\nFull Context Embeddings\n#\nThe embedding vectors are critical inputs for building a good classifier. Taking a single data point as input might not be enough to efficiently gauge the entire feature space. Therefore, the Matching Network model further proposed to enhance the embedding functions by taking as input the whole support set $S$ in addition to the original input, so that the learned embedding can be adjusted based on the relationship with other support samples.\n$g_\\theta(\\mathbf{x}_i, S)$ uses a bidirectional LSTM to encode $\\mathbf{x}_i$ in the context of the entire support set $S$.\n$f_\\theta(\\mathbf{x}, S)$ encodes the test sample $\\mathbf{x}$ visa an LSTM with read attention over the support set $S$.\nFirst the test sample goes through a simple neural network, such as a CNN, to extract basic features, $f’(\\mathbf{x})$.\nThen an LSTM is trained with a read attention vector over the support set as part of the hidden state:\n$$\n  \\begin{aligned}\n  \\hat{\\mathbf{h}}_t, \\mathbf{c}_t &= \\text{LSTM}(f'(\\mathbf{x}), [\\mathbf{h}_{t-1}, \\mathbf{r}_{t-1}], \\mathbf{c}_{t-1}) \\\\\n  \\mathbf{h}_t &= \\hat{\\mathbf{h}}_t + f'(\\mathbf{x}) \\\\\n  \\mathbf{r}_{t-1} &= \\sum_{i=1}^k a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) g(\\mathbf{x}_i) \\\\\n  a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) &= \\text{softmax}(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i)) = \\frac{\\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i))}{\\sum_{j=1}^k \\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_j))}\n  \\end{aligned}\n  $$\nEventually $f(\\mathbf{x}, S)=\\mathbf{h}_K$ if we do K steps of “read”.\nThis embedding method is called “Full Contextual Embeddings (FCE)”. Interestingly it does help improve the performance on a hard task (few-shot classification on mini ImageNet), but makes no difference on a simple task (Omniglot).\nThe training process in Matching Networks is designed to match inference at test time, see the details in the earlier\nsection\n. It is worthy of mentioning that the Matching Networks paper refined the idea that training and testing conditions should match.\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_\\theta(y\\vert\\mathbf{x}, S^L)]]\n$$\nRelation Network\n#\nRelation Network (RN)\n(\nSung et al., 2018\n) is similar to\nsiamese network\nbut with a few differences:\nThe relationship is not captured by a simple L1 distance in the feature space, but predicted by a CNN classifier $g_\\phi$. The relation score between a pair of inputs, $\\mathbf{x}_i$ and $\\mathbf{x}_j$, is $r_{ij} = g_\\phi([\\mathbf{x}_i, \\mathbf{x}_j])$ where $[.,.]$ is concatenation.\nThe objective function is MSE loss instead of cross-entropy, because conceptually RN focuses more on predicting relation scores which is more like regression, rather than binary classification, $\\mathcal{L}(B) = \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} (r_{ij} - \\mathbf{1}_{y_i=y_j})^2$.\nRelation Network architecture for a 5-way 1-shot problem with one query example. (Image source:\noriginal paper\n)\n(Note: There is another\nRelation Network\nfor relational reasoning, proposed by DeepMind. Don’t get confused.)\nPrototypical Networks\n#\nPrototypical Networks\n(\nSnell, Swersky & Zemel, 2017\n) use an embedding function $f_\\theta$ to encode each input into a $M$-dimensional feature vector. A\nprototype\nfeature vector is defined for every class $c \\in \\mathcal{C}$, as the mean vector of the embedded support data samples in this class.\n$$\n\\mathbf{v}_c = \\frac{1}{|S_c|} \\sum_{(\\mathbf{x}_i, y_i) \\in S_c} f_\\theta(\\mathbf{x}_i)\n$$\nPrototypical networks in the few-shot and zero-shot scenarios. (Image source:\noriginal paper\n)\nThe distribution over classes for a given test input $\\mathbf{x}$ is a softmax over the inverse of distances between the test data embedding and prototype vectors.\n$$\nP(y=c\\vert\\mathbf{x})=\\text{softmax}(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c)) = \\frac{\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c))}{\\sum_{c' \\in \\mathcal{C}}\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_{c'}))}\n$$\nwhere $d_\\varphi$ can be any distance function as long as $\\varphi$ is differentiable. In the paper, they used the squared euclidean distance.\nThe loss function is the negative log-likelihood: $\\mathcal{L}(\\theta) = -\\log P_\\theta(y=c\\vert\\mathbf{x})$.\nModel-Based\n#\nModel-based meta-learning models make no assumption on the form of $P_\\theta(y\\vert\\mathbf{x})$. Rather it depends on a model designed specifically for fast learning — a model that updates its parameters rapidly with a few training steps. This rapid parameter update can be achieved by its internal architecture or controlled by another meta-learner model.\nMemory-Augmented Neural Networks\n#\nA family of model architectures use external memory storage to facilitate the learning process of neural networks, including\nNeural Turing Machines\nand\nMemory Networks\n. With an explicit storage buffer, it is easier for the network to rapidly incorporate new information and not to forget in the future. Such a model is known as\nMANN\n, short for “\nMemory-Augmented Neural Network\n”.  Note that recurrent neural networks with only\ninternal memory\nsuch as vanilla RNN or LSTM are not MANNs.\nBecause MANN is expected to encode new information fast and thus to adapt to new tasks after only a few samples, it fits well for meta-learning. Taking the Neural Turing Machine (NTM) as the base model,\nSantoro et al. (2016)\nproposed a set of modifications on the training setup and the memory retrieval mechanisms (or “addressing mechanisms”, deciding how to assign attention weights to memory vectors). Please go through\nthe NTM section\nin my other post first if you are not familiar with this matter before reading forward.\nAs a quick recap, NTM couples a controller neural network with external memory storage. The controller learns to read and write memory rows by soft attention, while the memory serves as a knowledge repository. The attention weights are generated by its addressing mechanism: content-based + location based.\nThe architecture of Neural Turing Machine (NTM). The memory at time t, $\\mathbf{M}\\_t$ is a matrix of size $N \\times M$, containing N vector rows and each has M dimensions.\nMANN for Meta-Learning\n#\nTo use MANN for meta-learning tasks, we need to train it in a way that the memory can encode and capture information of new tasks fast and, in the meantime, any stored representation is easily and stably accessible.\nThe training described in\nSantoro et al., 2016\nhappens in an interesting way so that the memory is forced to hold information for longer until the appropriate labels are presented later. In each training episode, the truth label $y_t$ is presented with\none step offset\n, $(\\mathbf{x}_{t+1}, y_t)$: it is the true label for the input at the previous time step t, but presented as part of the input at time step t+1.\nTask setup in MANN for meta-learning (Image source:\noriginal paper\n).\nIn this way, MANN is motivated to memorize the information of a new dataset, because the memory has to hold the current input until the label is present later and then retrieve the old information to make a prediction accordingly.\nNext let us see how the memory is updated for efficient information retrieval and storage.\nAddressing Mechanism for Meta-Learning\n#\nAside from the training process, a new pure content-based addressing mechanism is utilized to make the model better suitable for meta-learning.\n» How to read from memory?\nThe read attention is constructed purely based on the content similarity.\nFirst, a key feature vector $\\mathbf{k}_t$ is produced at the time step t by the controller as a function of the input $\\mathbf{x}$. Similar to NTM, a read weighting vector $\\mathbf{w}_t^r$ of N elements is computed as the cosine similarity between the key vector and every memory vector row, normalized by softmax. The read vector $\\mathbf{r}_t$ is a sum of memory records weighted by such weightings:\n$$\n\\mathbf{r}_i = \\sum_{i=1}^N w_t^r(i)\\mathbf{M}_t(i)\n\\text{, where } w_t^r(i) = \\text{softmax}(\\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})\n$$\nwhere $M_t$ is the memory matrix at time t and $M_t(i)$ is the i-th row in this matrix.\n» How to write into memory?\nThe addressing mechanism for writing newly received information into memory operates a lot like the\ncache replacement\npolicy. The\nLeast Recently Used Access (LRUA)\nwriter is designed for MANN to better work in the scenario of meta-learning. A LRUA write head prefers to write new content to either the\nleast used\nmemory location or the\nmost recently used\nmemory location.\nRarely used locations: so that we can preserve frequently used information (see\nLFU\n);\nThe last used location: the motivation is that once a piece of information is retrieved once, it probably won’t be called again for a while (see\nMRU\n).\nThere are many cache replacement algorithms and each of them could potentially replace the design here with better performance in different use cases. Furthermore, it would be a good idea to learn the memory usage pattern and addressing strategies rather than arbitrarily set it.\nThe preference of LRUA is carried out in a way that everything is differentiable:\nThe usage weight $\\mathbf{w}^u_t$ at time t is a sum of current read and write vectors, in addition to the decayed last usage weight, $\\gamma \\mathbf{w}^u_{t-1}$, where $\\gamma$ is a decay factor.\nThe write vector is an interpolation between the previous read weight (prefer “the last used location”) and the previous least-used weight (prefer “rarely used location”). The interpolation parameter is the sigmoid of a hyperparameter $\\alpha$.\nThe least-used weight $\\mathbf{w}^{lu}$ is scaled according to usage weights $\\mathbf{w}_t^u$, in which any dimension remains at 1 if smaller than the n-th smallest element in the vector and 0 otherwise.\n$$\n\\begin{aligned}\n\\mathbf{w}_t^u &= \\gamma \\mathbf{w}_{t-1}^u + \\mathbf{w}_t^r + \\mathbf{w}_t^w \\\\\n\\mathbf{w}_t^r &= \\text{softmax}(\\text{cosine}(\\mathbf{k}_t, \\mathbf{M}_t(i))) \\\\\n\\mathbf{w}_t^w &= \\sigma(\\alpha)\\mathbf{w}_{t-1}^r + (1-\\sigma(\\alpha))\\mathbf{w}^{lu}_{t-1}\\\\\n\\mathbf{w}_t^{lu} &= \\mathbf{1}_{w_t^u(i) \\leq m(\\mathbf{w}_t^u, n)}\n\\text{, where }m(\\mathbf{w}_t^u, n)\\text{ is the }n\\text{-th smallest element in vector }\\mathbf{w}_t^u\\text{.}\n\\end{aligned}\n$$\nFinally, after the least used memory location, indicated by $\\mathbf{w}_t^{lu}$, is set to zero, every memory row is updated:\n$$\n\\mathbf{M}_t(i) = \\mathbf{M}_{t-1}(i) + w_t^w(i)\\mathbf{k}_t, \\forall i\n$$\nMeta Networks\n#\nMeta Networks\n(\nMunkhdalai & Yu, 2017\n), short for\nMetaNet\n, is a meta-learning model with architecture and training process designed for\nrapid\ngeneralization across tasks.\nFast Weights\n#\nThe rapid generalization of MetaNet relies on “fast weights”. There are a handful of papers on this topic, but I haven’t read all of them in detail and I failed to find a very concrete definition, only a vague agreement on the concept. Normally weights in the neural networks are updated by stochastic gradient descent in an objective function and this process is known to be slow. One faster way to learn is to utilize one neural network to predict the parameters of another neural network and the generated weights are called\nfast weights\n. In comparison, the ordinary SGD-based weights are named\nslow weights\n.\nIn MetaNet, loss gradients are used as\nmeta information\nto populate models that learn fast weights. Slow and fast weights are combined to make predictions in neural networks.\nCombining slow and fast weights in a MLP. $\\bigoplus$ is element-wise sum. (Image source:\noriginal paper\n).\nModel Components\n#\nDisclaimer: Below you will find my annotations are different from those in the paper. imo, the paper is poorly written, but the idea is still interesting. So I’m presenting the idea in my own language.\nKey components of MetaNet are:\nAn embedding function $f_\\theta$, parameterized by $\\theta$, encodes raw inputs into feature vectors. Similar to\nSiamese Neural Network\n, these embeddings are trained to be useful for telling whether two inputs are of the same class (verification task).\nA base learner model $g_\\phi$, parameterized by weights $\\phi$, completes the actual learning task.\nIf we stop here, it looks just like\nRelation Network\n. MetaNet, in addition, explicitly models the fast weights of both functions and then aggregates them back into the model (See Fig. 8).\nTherefore we need additional two functions to output fast weights for $f$ and $g$ respectively.\n$F_w$: a LSTM parameterized by $w$ for learning fast weights $\\theta^+$ of the embedding function $f$. It takes as input gradients of $f$’s embedding loss for verification task.\n$G_v$: a neural network parameterized by $v$ learning fast weights $\\phi^+$ for the base learner $g$ from its loss gradients. In MetaNet, the learner’s loss gradients are viewed as the\nmeta information\nof the task.\nOk, now let’s see how meta networks are trained. The training data contains multiple pairs of datasets: a support set $S=\\{\\mathbf{x}’_i, y’_i\\}_{i=1}^K$ and a test set  $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$. Recall that we have four networks and four sets of model parameters to learn, $(\\theta, \\phi, w, v)$.\nFig.9. The MetaNet architecture.\nTraining Process\n#\nSample a random pair of inputs at each time step t from the support set $S$, $(\\mathbf{x}’_i, y’_i)$ and $(\\mathbf{x}’_j, y_j)$. Let $\\mathbf{x}_{(t,1)}=\\mathbf{x}’_i$ and $\\mathbf{x}_{(t,2)}=\\mathbf{x}’_j$.\nfor $t = 1, \\dots, K$:\na. Compute a loss for representation learning; i.e., cross entropy for the verification task:\n$\\mathcal{L}^\\text{emb}_t = \\mathbf{1}_{y’_i=y’_j} \\log P_t + (1 - \\mathbf{1}_{y’_i=y’_j})\\log(1 - P_t)\\text{, where }P_t = \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_{(t,1)}) - f_\\theta(\\mathbf{x}_{(t,2)})\\vert)$\nCompute the task-level fast weights:\n$\\theta^+ = F_w(\\nabla_\\theta \\mathcal{L}^\\text{emb}_1, \\dots, \\mathcal{L}^\\text{emb}_T)$\nNext go through examples in the support set $S$ and compute the example-level fast weights. Meanwhile, update the memory with learned representations.\nfor $i=1, \\dots, K$:\na. The base learner outputs a probability distribution: $P(\\hat{y}_i \\vert \\mathbf{x}_i) = g_\\phi(\\mathbf{x}_i)$ and the loss can be cross-entropy or MSE: $\\mathcal{L}^\\text{task}_i = y’_i \\log g_\\phi(\\mathbf{x}’_i) + (1- y’_i) \\log (1 - g_\\phi(\\mathbf{x}’_i))$\nb. Extract meta information (loss gradients) of the task and compute the example-level fast weights:\n$\\phi_i^+ = G_v(\\nabla_\\phi\\mathcal{L}^\\text{task}_i)$\nThen store $\\phi^+_i$ into $i$-th location of the “value” memory $\\mathbf{M}$.\nd. Encode the support sample into a task-specific input representation using both slow and fast weights: $r’_i = f_{\\theta, \\theta^+}(\\mathbf{x}’_i)$\nThen store $r’_i$ into $i$-th location of the “key” memory $\\mathbf{R}$.\nFinally it is the time to construct the training loss using the test set $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$.\nStarts with $\\mathcal{L}_\\text{train}=0$:\nfor $j=1, \\dots, L$:\na. Encode the test sample into a task-specific input representation:\n$r_j = f_{\\theta, \\theta^+}(\\mathbf{x}_j)$\nb. The fast weights are computed by attending to representations of support set samples in memory $\\mathbf{R}$. The attention function is of your choice. Here MetaNet uses cosine similarity:\n$$\n \\begin{aligned}\n a_j &= \\text{cosine}(\\mathbf{R}, r_j) = [\\frac{r'_1\\cdot r_j}{\\|r'_1\\|\\cdot\\|r_j\\|}, \\dots, \\frac{r'_N\\cdot r_j}{\\|r'_N\\|\\cdot\\|r_j\\|}]\\\\\n \\phi^+_j &= \\text{softmax}(a_j)^\\top \\mathbf{M}\n \\end{aligned}\n $$\nc. Update the training loss: $\\mathcal{L}_\\text{train} \\leftarrow \\mathcal{L}_\\text{train} + \\mathcal{L}^\\text{task}(g_{\\phi, \\phi^+}(\\mathbf{x}_i), y_i) $\nUpdate all the parameters $(\\theta, \\phi, w, v)$ using $\\mathcal{L}_\\text{train}$.\nOptimization-Based\n#\nDeep learning models learn through backpropagation of gradients. However, the gradient-based optimization is neither designed to cope with a small number of training samples, nor to converge within a small number of optimization steps. Is there a way to adjust the optimization algorithm so that the model can be good at learning with a few examples? This is what optimization-based approach meta-learning algorithms intend for.\nLSTM Meta-Learner\n#\nThe optimization algorithm can be explicitly modeled.\nRavi & Larochelle (2017)\ndid so and named it “meta-learner”, while the original model for handling the task is called “learner”. The goal of the meta-learner is to efficiently update the learner’s parameters using a small support set so that the learner can adapt to the new task quickly.\nLet’s denote the learner model as $M_\\theta$ parameterized by $\\theta$, the meta-learner as $R_\\Theta$ with parameters $\\Theta$, and the loss function $\\mathcal{L}$.\nWhy LSTM?\n#\nThe meta-learner is modeled as a LSTM, because:\nThere is similarity between the gradient-based update in backpropagation and the cell-state update in LSTM.\nKnowing a history of gradients benefits the gradient update; think about how\nmomentum\nworks.\nThe update for the learner’s parameters at time step t with a learning rate $\\alpha_t$ is:\n$$\n\\theta_t = \\theta_{t-1} - \\alpha_t \\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n$$\nIt has the same form as the cell state update in LSTM, if we set forget gate $f_t=1$, input gate $i_t = \\alpha_t$, cell state $c_t = \\theta_t$, and new cell state $\\tilde{c}_t = -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t$:\n$$\n\\begin{aligned}\nc_t &= f_t \\odot c_{t-1} + i_t \\odot \\tilde{c}_t\\\\\n    &= \\theta_{t-1} - \\alpha_t\\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n\\end{aligned}\n$$\nWhile fixing $f_t=1$ and $i_t=\\alpha_t$ might not be the optimal, both of them can be learnable and adaptable to different datasets.\n$$\n\\begin{aligned}\nf_t &= \\sigma(\\mathbf{W}_f \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, f_{t-1}] + \\mathbf{b}_f) & \\scriptstyle{\\text{; how much to forget the old value of parameters.}}\\\\\ni_t &= \\sigma(\\mathbf{W}_i \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, i_{t-1}] + \\mathbf{b}_i) & \\scriptstyle{\\text{; corresponding to the learning rate at time step t.}}\\\\\n\\tilde{\\theta}_t &= -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t &\\\\\n\\theta_t &= f_t \\odot \\theta_{t-1} + i_t \\odot \\tilde{\\theta}_t &\\\\\n\\end{aligned}\n$$\nModel Setup\n#\nHow the learner $M\\_\\theta$ and the meta-learner $R\\_\\Theta$ are trained. (Image source:\noriginal paper\nwith more annotations)\nThe training process mimics what happens during test, since it has been proved to be beneficial in\nMatching Networks\n. During each training epoch, we first sample a dataset $\\mathcal{D} = (\\mathcal{D}_\\text{train}, \\mathcal{D}_\\text{test}) \\in \\hat{\\mathcal{D}}_\\text{meta-train}$ and then sample mini-batches out of $\\mathcal{D}_\\text{train}$ to update $\\theta$ for $T$ rounds. The final state of the learner parameter $\\theta_T$ is used to train the meta-learner on the test data $\\mathcal{D}_\\text{test}$.\nTwo implementation details to pay extra attention to:\nHow to compress the parameter space in LSTM meta-learner? As the meta-learner is modeling parameters of another neural network, it would have hundreds of thousands of variables to learn. Following the\nidea\nof sharing parameters across coordinates,\nTo simplify the training process, the meta-learner assumes that the loss $\\mathcal{L}_t$ and the gradient $\\nabla_{\\theta_{t-1}} \\mathcal{L}_t$ are independent.\nMAML\n#\nMAML\n, short for\nModel-Agnostic Meta-Learning\n(\nFinn, et al. 2017\n) is a fairly general optimization algorithm, compatible with any model that learns through gradient descent.\nLet’s say our model is $f_\\theta$ with parameters $\\theta$. Given a task $\\tau_i$ and its associated dataset $(\\mathcal{D}^{(i)}_\\text{train}, \\mathcal{D}^{(i)}_\\text{test})$, we can update the model parameters by one or more gradient descent steps (the following example only contains one step):\n$$\n\\theta'_i = \\theta - \\alpha \\nabla_\\theta\\mathcal{L}^{(0)}_{\\tau_i}(f_\\theta)\n$$\nwhere $\\mathcal{L}^{(0)}$ is the loss computed using the mini data batch with id (0).\nDiagram of MAML. (Image source:\noriginal paper\n)\nWell, the above formula only optimizes for one task. To achieve a good generalization across a variety of tasks, we would like to find the optimal $\\theta^*$ so that the task-specific fine-tuning is more efficient. Now, we sample a new data batch with id (1) for updating the meta-objective. The loss, denoted as $\\mathcal{L}^{(1)}$, depends on the mini batch (1). The superscripts in $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ only indicate different data batches, and they refer to the same loss objective for the same task.\n$$\n\\begin{aligned}\n\\theta^* \n&= \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta'_i}) = \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\\\\n\\theta &\\leftarrow \\theta - \\beta \\nabla_{\\theta} \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\scriptstyle{\\text{; updating rule}}\n\\end{aligned}\n$$\nThe general form of MAML algorithm. (Image source:\noriginal paper\n)\nFirst-Order MAML\n#\nThe meta-optimization step above relies on second derivatives. To make the computation less expensive, a modified version of MAML omits second derivatives, resulting in a simplified and cheaper implementation, known as\nFirst-Order MAML (FOMAML)\n.\nLet’s consider the case of performing $k$ inner gradient steps, $k\\geq1$. Starting with the initial model parameter $\\theta_\\text{meta}$:\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)\\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_1)\\\\\n&\\dots\\\\\n\\theta_k &= \\theta_{k-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{k-1})\n\\end{aligned}\n$$\nThen in the outer loop, we sample a new data batch for updating the meta-objective.\n$$\n\\begin{aligned}\n\\theta_\\text{meta} &\\leftarrow \\theta_\\text{meta} - \\beta g_\\text{MAML} & \\scriptstyle{\\text{; update for meta-objective}} \\\\[2mm]\n\\text{where } g_\\text{MAML}\n&= \\nabla_{\\theta} \\mathcal{L}^{(1)}(\\theta_k) &\\\\[2mm]\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot (\\nabla_{\\theta_{k-1}} \\theta_k) \\dots (\\nabla_{\\theta_0} \\theta_1) \\cdot (\\nabla_{\\theta} \\theta_0) & \\scriptstyle{\\text{; following the chain rule}} \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\Big( \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} \\theta_i \\Big) \\cdot I &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} (\\theta_{i-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1})) &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))) &\n\\end{aligned}\n$$\nThe MAML gradient is:\n$$\ng_\\text{MAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha \\color{red}{\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))})\n$$\nThe First-Order MAML ignores the second derivative part in red. It is simplified as follows, equivalent to the derivative of the last inner gradient update result.\n$$\ng_\\text{FOMAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k)\n$$\nReptile\n#\nReptile\n(\nNichol, Achiam & Schulman, 2018\n) is a remarkably simple meta-learning optimization algorithm. It is similar to MAML in many ways, given that both rely on meta-optimization through gradient descent and both are model-agnostic.\nThe Reptile works by repeatedly:\nsampling a task,\ntraining on it by multiple gradient descent steps,\nand then moving the model weights towards the new parameters.\nSee the algorithm below:\n$\\text{SGD}(\\mathcal{L}_{\\tau_i}, \\theta, k)$ performs stochastic gradient update for k steps on the loss $\\mathcal{L}_{\\tau_i}$ starting with initial parameter $\\theta$ and returns the final parameter vector. The batch version samples multiple tasks instead of one within each iteration. The reptile gradient is defined as $(\\theta - W)/\\alpha$, where $\\alpha$ is the stepsize used by the SGD operation.\nThe batched version of Reptile algorithm. (Image source:\noriginal paper\n)\nAt a glance, the algorithm looks a lot like an ordinary SGD. However, because the task-specific optimization can take more than one step. it eventually makes $\\text{SGD}(\\mathbb{E}\n_\\tau[\\mathcal{L}_{\\tau}], \\theta, k)$ diverge from $\\mathbb{E}_\\tau [\\text{SGD}(\\mathcal{L}_{\\tau}, \\theta, k)]$ when k > 1.\nThe Optimization Assumption\n#\nAssuming that a task $\\tau \\sim p(\\tau)$ has a manifold of optimal network configuration, $\\mathcal{W}_{\\tau}^*$. The model $f_\\theta$ achieves the best performance for task $\\tau$ when $\\theta$ lays on the surface of $\\mathcal{W}_{\\tau}^*$. To find a solution that is good across tasks, we would like to find a parameter close to all the optimal manifolds of all tasks:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\tau \\sim p(\\tau)} [\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_\\tau^*)^2]\n$$\nThe Reptile algorithm updates the parameter alternatively to be closer to the optimal manifolds of different tasks. (Image source:\noriginal paper\n)\nLet’s use the L2 distance as $\\text{dist}(.)$ and the distance between a point $\\theta$ and a set $\\mathcal{W}_\\tau^*$ equals to the distance between $\\theta$ and a point $W_{\\tau}^*(\\theta)$ on the manifold that is closest to $\\theta$:\n$$\n\\text{dist}(\\theta, \\mathcal{W}_{\\tau}^*) = \\text{dist}(\\theta, W_{\\tau}^*(\\theta)) \\text{, where }W_{\\tau}^*(\\theta) = \\arg\\min_{W\\in\\mathcal{W}_{\\tau}^*} \\text{dist}(\\theta, W)\n$$\nThe gradient of the squared euclidean distance is:\n$$\n\\begin{aligned}\n\\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2]\n&= \\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\nabla_\\theta[\\frac{1}{2}(\\theta - W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\theta - W_{\\tau_i}^*(\\theta) & \\scriptstyle{\\text{; See notes.}}\n\\end{aligned}\n$$\nNotes: According to the Reptile paper,\n“the gradient of the squared euclidean distance between a point $\\Theta$ and a set $S$ is the vector $2(\\Theta − p)$, where p is the closest point in $S$ to $\\Theta$”\n. Technically the closest point in $S$ is also a function of $\\Theta$, but I’m not sure why the gradient does not need to worry about the derivative of $p$. (Please feel free to leave me a comment or send me an email about this if you have ideas.)\nThus the update rule for one stochastic gradient step is:\n$$\n\\theta = \\theta - \\alpha \\nabla_\\theta[\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2] = \\theta - \\alpha(\\theta - W_{\\tau_i}^*(\\theta)) = (1-\\alpha)\\theta + \\alpha W_{\\tau_i}^*(\\theta)\n$$\nThe closest point on the optimal task manifold $W_{\\tau_i}^*(\\theta)$ cannot be computed exactly, but Reptile approximates it using $\\text{SGD}(\\mathcal{L}_\\tau, \\theta, k)$.\nReptile vs FOMAML\n#\nTo demonstrate the deeper connection between Reptile and MAML, let’s expand the update formula with an example performing two gradient steps, k=2 in $\\text{SGD}(.)$. Same as defined\nabove\n, $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ are losses using different mini-batches of data. For ease of reading, we adopt two simplified annotations: $g^{(i)}_j = \\nabla_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$ and $H^{(i)}_j = \\nabla^2_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$.\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)= \\theta_0 - \\alpha g^{(0)}_0 \\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(1)}(\\theta_1) = \\theta_0 - \\alpha g^{(0)}_0 - \\alpha g^{(1)}_1\n\\end{aligned}\n$$\nAccording to the\nearly section\n, the gradient of FOMAML is the last inner gradient update result. Therefore, when k=1:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) = g^{(1)}_1 \\\\\ng_\\text{MAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) \\cdot (I - \\alpha\\nabla^2_{\\theta} \\mathcal{L}^{(0)}(\\theta_0)) = g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1\n\\end{aligned}\n$$\nThe Reptile gradient is defined as:\n$$\ng_\\text{Reptile} = (\\theta_0 - \\theta_2) / \\alpha = g^{(0)}_0 + g^{(1)}_1\n$$\nUp to now we have:\nReptile versus FOMAML in one loop of meta-optimization. (Image source:\nslides\non Reptile by Yoonho Lee.)\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 \\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\ng_\\text{Reptile} &= g^{(0)}_0 + g^{(1)}_1\n\\end{aligned}\n$$\nNext let’s try further expand $g^{(1)}_1$ using\nTaylor expansion\n. Recall that Taylor expansion of a function $f(x)$ that is differentiable at a number $a$ is:\n$$\nf(x) = f(a) + \\frac{f'(a)}{1!}(x-a) + \\frac{f''(a)}{2!}(x-a)^2 + \\dots = \\sum_{i=0}^\\infty \\frac{f^{(i)}(a)}{i!}(x-a)^i\n$$\nWe can consider $\\nabla_{\\theta}\\mathcal{L}^{(1)}(.)$ as a function and $\\theta_0$ as a value point. The Taylor expansion of $g_1^{(1)}$ at the value point $\\theta_0$ is:\n$$\n\\begin{aligned}\ng_1^{(1)} &= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_1) \\\\\n&= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_0) + \\nabla^2_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0) + \\frac{1}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0)^2 + \\dots & \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + \\frac{\\alpha^2}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0) (g_0^{(0)})^2 + \\dots & \\scriptstyle{\\text{; because }\\theta_1-\\theta_0=-\\alpha g_0^{(0)}} \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nPlug in the expanded form of $g_1^{(1)}$ into the MAML gradients with one step inner gradient update:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 = g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2) - \\alpha H^{(0)}_0 (g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2))\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + \\alpha^2 \\alpha H^{(0)}_0 H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\n\\end{aligned}\n$$\nThe Reptile gradient becomes:\n$$\n\\begin{aligned}\ng_\\text{Reptile} \n&= g^{(0)}_0 + g^{(1)}_1 \\\\\n&= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nSo far we have the formula of three types of gradients:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\\\\\ng_\\text{Reptile}  &= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nDuring training, we often average over multiple data batches. In our example, the mini batches (0) and (1) are interchangeable since both are drawn at random. The expectation $\\mathbb{E}_{\\tau,0,1}$ is averaged over two data batches, ids (0) and (1), for task $\\tau$.\nLet,\n$A = \\mathbb{E}_{\\tau,0,1} [g_0^{(0)}] = \\mathbb{E}_{\\tau,0,1} [g_0^{(1)}]$; it is the average gradient of task loss. We expect to improve the model parameter to achieve better task performance by following this direction pointed by $A$.\n$B = \\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)} + H^{(0)}_0 g_0^{(1)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [\\nabla_\\theta(g^{(0)}_0 g_0^{(1)})]$; it is the direction (gradient) that increases the inner product of gradients of two different mini batches for the same task. We expect to improve the model parameter to achieve better generalization over different data by following this direction pointed by $B$.\nTo conclude, both MAML and Reptile aim to optimize for the same goal, better task performance (guided by A) and better generalization (guided by B), when the gradient update is approximated by first three leading terms.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\tau,1,2}[g_\\text{FOMAML}] &= A - \\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{MAML}] &= A - 2\\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{Reptile}]  &= 2A - \\alpha B + O(\\alpha^2)\n\\end{aligned}\n$$\nIt is not clear to me whether the ignored term $O(\\alpha^2)$ might play a big impact on the parameter learning. But given that FOMAML is able to obtain a similar performance as the full version of MAML, it might be safe to say higher-level derivatives would not be critical during gradient descent update.\nCited as:\n@article{weng2018metalearning,\n  title   = \"Meta-Learning: Learning to Learn Fast\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-11-30-meta-learning/\"\n}\nReference\n#\n[1] Brenden M. Lake, Ruslan Salakhutdinov, and Joshua B. Tenenbaum.\n“Human-level concept learning through probabilistic program induction.”\nScience 350.6266 (2015): 1332-1338.\n[2] Oriol Vinyals’ talk on\n“Model vs Optimization Meta Learning”\n[3] Gregory Koch, Richard Zemel, and Ruslan Salakhutdinov.\n“Siamese neural networks for one-shot image recognition.”\nICML Deep Learning Workshop. 2015.\n[4] Oriol Vinyals, et al.\n“Matching networks for one shot learning.”\nNIPS. 2016.\n[5] Flood Sung, et al.\n“Learning to compare: Relation network for few-shot learning.”\nCVPR. 2018.\n[6] Jake Snell, Kevin Swersky, and Richard Zemel.\n“Prototypical Networks for Few-shot Learning.”\nCVPR. 2018.\n[7] Adam Santoro, et al.\n“Meta-learning with memory-augmented neural networks.”\nICML. 2016.\n[8] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).\n[9] Tsendsuren Munkhdalai and Hong Yu.\n“Meta Networks.”\nICML. 2017.\n[10] Sachin Ravi and Hugo Larochelle.\n“Optimization as a Model for Few-Shot Learning.”\nICLR. 2017.\n[11] Chelsea Finn’s BAIR blog on\n“Learning to Learn”\n.\n[12] Chelsea Finn, Pieter Abbeel, and Sergey Levine.\n“Model-agnostic meta-learning for fast adaptation of deep networks.”\nICML 2017.\n[13] Alex Nichol, Joshua Achiam, John Schulman.\n“On First-Order Meta-Learning Algorithms.”\narXiv preprint arXiv:1803.02999 (2018).\n[14]\nSlides on Reptile\nby Yoonho Lee.",
            "metadata": {
              "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
              "description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "keywords": "meta-learning, long-read",
              "author": "Lilian Weng",
              "og:title": "Meta-Learning: Learning to Learn Fast",
              "og:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
              "twitter:card": "summary",
              "twitter:title": "Meta-Learning: Learning to Learn Fast",
              "twitter:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "article:section": "posts",
              "article:published_time": "2018-11-30T00:00:00+00:00",
              "article:modified_time": "2018-11-30T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/a8dc6bf17c71/code/body-000.txt",
                "chars": 245,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "bytes": 1548239,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-23d602a28b9d9dda6fe1.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "bytes": 665187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-11419d5ec12fba3fb7f9.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "bytes": 730525,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-34f37f1d8bf391fe9f42.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "bytes": 808103,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-851555a6cfa04864e872.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "bytes": 184486,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-1195100b0c6841a237dd.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-c47eeb17ebb22f866942.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "bytes": 273207,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9ae2425c1e62b530a443.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "bytes": 174582,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-cb826c25071414ad89e4.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "bytes": 405772,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-0167fe1ca07386abf1d2.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "bytes": 1245251,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-ae1778af670dfaca75e8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "bytes": 397702,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9baa7ed8723c2cae889a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "bytes": 102014,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-f1b0701dad5bcf83ef5a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "bytes": 195622,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-7f2ae4aa3936d2a466d8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "bytes": 286187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d947284bd0373951e25d.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "bytes": 124913,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-830017a377b95ff33b98.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "bytes": 1295521,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d0137fe96ca3220fcf1f.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://wei-tianhao.github.io/blog/2019/09/17/meta-learning.html",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "label": "learning to learn",
                "type": "a"
              },
              {
                "href": "https://www.pinterest.com/",
                "label": "Pinterest",
                "type": "a"
              },
              {
                "href": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "k-NN",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-means_clustering",
                "label": "k-means",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_density_estimation",
                "label": "kernel density estimation",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Similarity_learning",
                "label": "Metric learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "label": "Siamese Neural Network",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "label": "Koch, Zemel & Salakhutdinov (2015)",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "label": "Sung et al., 2018",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/neural-approach-relational-reasoning/",
                "label": "Relation Network",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "label": "Snell, Swersky & Zemel, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "Neural Turing Machines",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.3916",
                "label": "Memory Networks",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "label": "Santoro et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cache_replacement_policies",
                "label": "cache replacement",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Least_frequently_used",
                "label": "LFU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.00837",
                "label": "Munkhdalai & Yu, 2017",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll",
                "label": "Ravi & Larochelle (2017)",
                "type": "a"
              },
              {
                "href": "http://ruder.io/optimizing-gradient-descent/index.html",
                "label": "momentum",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll)",
                "label": "original paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04474",
                "label": "idea",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol, Achiam & Schulman, 2018",
                "type": "a"
              },
              {
                "href": "https://www.slideshare.net/YoonhoLee4/on-firstorder-metalearning-algorithms",
                "label": "slides",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Taylor_series",
                "label": "Taylor expansion",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "“Neural turing machines.”",
                "type": "a"
              },
              {
                "href": "https://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "“Learning to Learn”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:39Z",
            "source_url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "bytes": 1826353,
                "reused": false,
                "local_path": "papers/repair/da4e56c26698557aa61c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='metalearning-symposium.ml', port=80): Max retries exceeded with url: /files/vinyals.pdf (Caused by NameResolutionError(\"HTTPConnection(host='metalearning-s",
                "retried_at": "2026-10-20T22:24:44Z"
              },
              {
                "status": "http_404",
                "url": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "retried_at": "2026-10-20T18:04:05Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "bytes": 766340,
                "reused": false,
                "local_path": "papers/repair/fde088adb2e69f52cd16.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": false,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "bytes": 798122,
                "reused": false,
                "local_path": "papers/repair/1dce78ce43bce934d7c8.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "bytes": 536399,
                "reused": false,
                "local_path": "papers/repair/33350b7fc96a8da3fa63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.3916",
                "bytes": 215900,
                "reused": false,
                "local_path": "papers/repair/e6bb14affb9d1f13f660.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "bytes": 1648270,
                "reused": false,
                "local_path": "papers/repair/b9ba58828decfbd2ad1e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00837",
                "bytes": 455366,
                "reused": false,
                "local_path": "papers/repair/b15e9ef4f202cbfada2c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04474",
                "bytes": 2702892,
                "reused": false,
                "local_path": "papers/repair/76aa0aeb7717cd2e1f8f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": false,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": true,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46235,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/a8dc6bf17c71/pages/source.html",
            "local_html": "attachments/a8dc6bf17c71/pages/article.html",
            "body_base_path": "attachments/a8dc6bf17c71/pages/",
            "body_markdown_path": "attachments/a8dc6bf17c71/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
          "status": "partial",
          "article_id": "9e1d58627b38",
          "local_path": "series-follow/1600/repair/3966b026c35e1e97e15a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
              "bytes": 58269,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/418c8992a5cc9d9deeb1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
              "bytes": 107025,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d53eaab123d7a3b8d561.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
              "bytes": 33772,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1a3ee27cdec9dd4e95e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
              "bytes": 55693,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8b930e0942e1d249d7cd.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
              "bytes": 27143,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/508e643f8751bb71fcf3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
              "bytes": 32728,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/aa4ac628fe85693e0ba3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
              "bytes": 21618,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/8917c12943284b1507b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
              "bytes": 133435,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c1fcc0568374ce65ea91.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
              "bytes": 35850,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/be7712dd68a63d561005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
              "bytes": 128382,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d374974862f12f0f0ada.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
              "bytes": 91431,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/0d8b962a59d7ad31b2ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
              "bytes": 136647,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3ceb5a7713444f264e70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
              "bytes": 61555,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/070437b06f4b4d8a0287.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "A (Long) Peek into Reinforcement Learning",
            "keywords": "强化学习,RL,入门",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "publish_date": "2018-02",
            "corpus_stage": "强化学习/对齐",
            "notes": "强化学习入门经典综述",
            "id": "9e1d58627b38",
            "collected_at": "2026-10-02T14:13:19",
            "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-09-03: Updated the algorithm of\nSARSA\nand\nQ-learning\nso that the difference is more pronounced.\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in\nChinese\n].\nA couple of exciting news in Artificial Intelligence (AI) has just happened in recent years.  AlphaGo defeated the best professional human player in the game of Go. Very soon the extended algorithm AlphaGo Zero beat AlphaGo by 100-0 without supervised learning on human knowledge. Top professional game players lost to the bot developed by OpenAI on DOTA2 1v1 competition. After knowing these, it is pretty hard not to be curious about the magic behind these algorithms — Reinforcement Learning (RL). I’m writing this post to briefly go over the field. We will first introduce several fundamental concepts and then dive into classic approaches to solving RL problems. Hopefully, this post could be a good starting point for newbies, bridging the future study on the cutting-edge research.\nWhat is Reinforcement Learning?\n#\nSay, we have an agent in an unknown environment and this agent can obtain some rewards by interacting with the environment. The agent ought to take actions so as to maximize cumulative rewards. In reality, the scenario could be a bot playing a game to achieve high scores, or a robot trying to complete physical tasks with physical items; and not just limited to these.\nAn agent interacts with the environment, trying to take smart actions to maximize cumulative rewards.\nThe goal of Reinforcement Learning (RL) is to learn a good strategy for the agent from experimental trials and relative simple feedback received. With the optimal strategy, the agent is capable to actively adapt to the environment to maximize future rewards.\nKey Concepts\n#\nNow Let’s formally define a set of key concepts in RL.\nThe agent is acting in an\nenvironment\n. How the environment reacts to certain actions is defined by a\nmodel\nwhich we may or may not know. The agent can stay in one of many\nstates\n($s \\in \\mathcal{S}$) of the environment, and choose to take one of many\nactions\n($a \\in \\mathcal{A}$) to switch from one state to another. Which state the agent will arrive in is decided by transition probabilities between states ($P$). Once an action is taken, the environment delivers a\nreward\n($r \\in \\mathcal{R}$) as feedback.\nThe model defines the reward function and transition probabilities. We may or may not know how the model works and this differentiate two circumstances:\nKnow the model\n: planning with perfect information; do model-based RL. When we fully know the environment, we can find the optimal solution by\nDynamic Programming\n(DP). Do you still remember “longest increasing subsequence” or “traveling salesmen problem” from your Algorithms 101 class? LOL. This is not the focus of this post though.\nDoes not know the model\n: learning with incomplete information; do model-free RL or try to learn the model explicitly as part of the algorithm. Most of the following content serves the scenarios when the model is unknown.\nThe agent’s\npolicy\n$\\pi(s)$ provides the guideline on what is the optimal action to take in a certain state with\nthe goal to maximize the total rewards\n. Each state is associated with a\nvalue\nfunction $V(s)$ predicting the expected amount of future rewards we are able to receive in this state by acting the corresponding policy. In other words, the value function quantifies how good a state is. Both policy and value functions are what we try to learn in reinforcement learning.\nSummary of approaches in RL based on whether we want to model the value, policy, or the environment. (Image source: reproduced from David Silver's RL course\nlecture 1\n.)\nThe interaction between the agent and the environment involves a sequence of actions and observed rewards in time, $t=1, 2, \\dots, T$. During the process, the agent accumulates the knowledge about the environment, learns the optimal policy, and makes decisions on which action to take next so as to efficiently learn the best policy. Let’s label the state, action, and reward at time step t as $S_t$, $A_t$, and $R_t$, respectively. Thus the interaction sequence is fully described by one\nepisode\n(also known as “trial” or “trajectory”) and the sequence ends at the terminal state $S_T$:\n$$\nS_1, A_1, R_2, S_2, A_2, \\dots, S_T\n$$\nTerms you will encounter a lot when diving into different categories of RL algorithms:\nModel-based\n: Rely on the model of the environment; either the model is known or the algorithm learns it explicitly.\nModel-free\n: No dependency on the model during learning.\nOn-policy\n: Use the deterministic outcomes or samples from the target policy to train the algorithm.\nOff-policy\n: Training on a distribution of transitions or episodes produced by a different behavior policy rather than that produced by the target policy.\nModel: Transition and Reward\n#\nThe model is a descriptor of the environment. With the model, we can learn or infer how the environment would interact with and provide feedback to the agent. The model has two major parts, transition probability function $P$ and reward function $R$.\nLet’s say when we are in state s, we decide to take action a to arrive in the next state s’ and obtain reward r. This is known as one\ntransition\nstep, represented by a tuple (s, a, s’, r).\nThe transition function P records the probability of transitioning from state s to s’ after taking action a while obtaining reward r. We use $\\mathbb{P}$ as a symbol of “probability”.\n$$\nP(s', r \\vert s, a)  = \\mathbb{P} [S_{t+1} = s', R_{t+1} = r \\vert S_t = s, A_t = a]\n$$\nThus the state-transition function can be defined as a function of $P(s’, r \\vert s, a)$:\n$$\nP_{ss'}^a = P(s' \\vert s, a)  = \\mathbb{P} [S_{t+1} = s' \\vert S_t = s, A_t = a] = \\sum_{r \\in \\mathcal{R}} P(s', r \\vert s, a)\n$$\nThe reward function R predicts the next reward triggered by one action:\n$$\nR(s, a) = \\mathbb{E} [R_{t+1} \\vert S_t = s, A_t = a] = \\sum_{r\\in\\mathcal{R}} r \\sum_{s' \\in \\mathcal{S}} P(s', r \\vert s, a)\n$$\nPolicy\n#\nPolicy, as the agent’s behavior function $\\pi$, tells us which action to take in state s. It is a mapping from state s to action a and can be either deterministic or stochastic:\nDeterministic: $\\pi(s) = a$.\nStochastic: $\\pi(a \\vert s) = \\mathbb{P}_\\pi [A=a \\vert S=s]$.\nValue Function\n#\nValue function measures the goodness of a state or how rewarding a state or an action is by a prediction of future reward. The future reward, also known as\nreturn\n, is a total sum of discounted rewards going forward. Let’s compute the return $G_t$ starting from time t:\n$$\nG_t = R_{t+1} + \\gamma R_{t+2} + \\dots = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}\n$$\nThe discounting factor $\\gamma \\in [0, 1]$ penalize the rewards in the future, because:\nThe future rewards may have higher uncertainty; i.e. stock market.\nThe future rewards do not provide immediate benefits; i.e. As human beings, we might prefer to have fun today rather than 5 years later ;).\nDiscounting provides mathematical convenience; i.e., we don’t need to track future steps forever to compute return.\nWe don’t need to worry about the infinite loops in the state transition graph.\nThe\nstate-value\nof a state s is the expected return if we are in this state at time t, $S_t = s$:\n$$\nV_{\\pi}(s) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s]\n$$\nSimilarly, we define the\naction-value\n(“Q-value”; Q as “Quality” I believe?) of a state-action pair as:\n$$\nQ_{\\pi}(s, a) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s, A_t = a]\n$$\nAdditionally, since we follow the target policy $\\pi$, we can make use of the probility distribution over possible actions and the Q-values to recover the state-value:\n$$\nV_{\\pi}(s) = \\sum_{a \\in \\mathcal{A}} Q_{\\pi}(s, a) \\pi(a \\vert s)\n$$\nThe difference between action-value and state-value is the action\nadvantage\nfunction (“A-value”):\n$$\nA_{\\pi}(s, a) = Q_{\\pi}(s, a) - V_{\\pi}(s)\n$$\nOptimal Value and Policy\n#\nThe optimal value function produces the maximum return:\n$$\nV_{*}(s) = \\max_{\\pi} V_{\\pi}(s),\nQ_{*}(s, a) = \\max_{\\pi} Q_{\\pi}(s, a)\n$$\nThe optimal policy achieves optimal value functions:\n$$\n\\pi_{*} = \\arg\\max_{\\pi} V_{\\pi}(s),\n\\pi_{*} = \\arg\\max_{\\pi} Q_{\\pi}(s, a)\n$$\nAnd of course, we have $V_{\\pi_{*}}(s)=V_{*}(s)$ and $Q_{\\pi_{*}}(s, a) = Q_{*}(s, a)$.\nMarkov Decision Processes\n#\nIn more formal terms, almost all the RL problems can be framed as\nMarkov Decision Processes\n(MDPs). All states in MDP has “Markov” property, referring to the fact that the future only depends on the current state, not the history:\n$$\n\\mathbb{P}[ S_{t+1} \\vert S_t ] = \\mathbb{P} [S_{t+1} \\vert S_1, \\dots, S_t]\n$$\nOr in other words, the future and the past are\nconditionally independent\ngiven the present, as the current state encapsulates all the statistics we need to decide the future.\nThe agent-environment interaction in a Markov decision process. (Image source: Sec. 3.1 Sutton & Barto (2017).)\nA Markov deicison process consists of five elements $\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, P, R, \\gamma \\rangle$, where the symbols carry the same meanings as key concepts in the\nprevious\nsection, well aligned with RL problem settings:\n$\\mathcal{S}$ - a set of states;\n$\\mathcal{A}$ - a set of actions;\n$P$ - transition probability function;\n$R$ - reward function;\n$\\gamma$ - discounting factor for future rewards.\nIn an unknown environment, we do not have perfect knowledge about $P$ and $R$.\nA fun example of Markov decision process: a typical work day. (Image source:\nrandomant.net/reinforcement-learning-concepts\n)\nBellman Equations\n#\nBellman equations refer to a set of equations that decompose the value function into the immediate reward plus the discounted future values.\n$$\n\\begin{aligned}\nV(s) &= \\mathbb{E}[G_t \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma R_{t+2} + \\gamma^2 R_{t+3} + \\dots \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma (R_{t+2} + \\gamma R_{t+3} + \\dots) \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma G_{t+1} \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\vert S_t = s]\n\\end{aligned}\n$$\nSimilarly for Q-value,\n$$\n\\begin{aligned}\nQ(s, a) \n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\mid S_t = s, A_t = a] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma \\mathbb{E}_{a\\sim\\pi} Q(S_{t+1}, a) \\mid S_t = s, A_t = a]\n\\end{aligned}\n$$\nBellman Expectation Equations\n#\nThe recursive update process can be further decomposed to be equations built on both state-value and action-value functions. As we go further in future action steps, we extend V and Q alternatively by following the policy $\\pi$.\nIllustration of how Bellman expection equations update state-value and action-value functions.\n$$\n\\begin{aligned}\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) Q_{\\pi}(s, a) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\\\\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\big) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\sum_{a' \\in \\mathcal{A}} \\pi(a' \\vert s') Q_{\\pi} (s', a')\n\\end{aligned}\n$$\nBellman Optimality Equations\n#\nIf we are only interested in the optimal values, rather than computing the expectation following a policy, we could jump right into the maximum returns during the alternative updates without using a policy. RECAP: the optimal values $V_*$ and $Q_*$ are the best returns we can obtain, defined\nhere\n.\n$$\n\\begin{aligned}\nV_*(s) &= \\max_{a \\in \\mathcal{A}} Q_*(s,a)\\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\\\\nV_*(s) &= \\max_{a \\in \\mathcal{A}} \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\big) \\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\max_{a' \\in \\mathcal{A}} Q_*(s', a')\n\\end{aligned}\n$$\nUnsurprisingly they look very similar to Bellman expectation equations.\nIf we have complete information of the environment, this turns into a planning problem, solvable by DP. Unfortunately, in most scenarios, we do not know $P_{ss’}^a$ or $R(s, a)$, so we cannot solve MDPs by directly applying Bellmen equations, but it lays the theoretical foundation for many RL algorithms.\nCommon Approaches\n#\nNow it is the time to go through the major approaches and classic algorithms for solving RL problems. In future posts, I plan to dive into each approach further.\nDynamic Programming\n#\nWhen the model is fully known, following Bellman equations, we can use\nDynamic Programming\n(DP) to iteratively evaluate value functions and improve policy.\nPolicy Evaluation\n#\nPolicy Evaluation is to compute the state-value $V_\\pi$ for a given policy $\\pi$:\n$$\nV_{t+1}(s) \n= \\mathbb{E}_\\pi [r + \\gamma V_t(s') | S_t = s]\n= \\sum_a \\pi(a \\vert s) \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_t(s'))\n$$\nPolicy Improvement\n#\nBased on the value functions, Policy Improvement generates a better policy $\\pi’ \\geq \\pi$ by acting greedily.\n$$\nQ_\\pi(s, a) \n= \\mathbb{E} [R_{t+1} + \\gamma V_\\pi(S_{t+1}) \\vert S_t=s, A_t=a]\n= \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_\\pi(s'))\n$$\nPolicy Iteration\n#\nThe\nGeneralized Policy Iteration (GPI)\nalgorithm refers to an iterative procedure to improve the policy when combining policy evaluation and improvement.\n$$\n\\pi_0 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_0} \\xrightarrow[]{\\text{improve}}\n\\pi_1 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_1} \\xrightarrow[]{\\text{improve}}\n\\pi_2 \\xrightarrow[]{\\text{evaluation}} \\dots \\xrightarrow[]{\\text{improve}}\n\\pi_* \\xrightarrow[]{\\text{evaluation}} V_*\n$$\nIn GPI, the value function is approximated repeatedly to be closer to the true value of the current policy and in the meantime, the policy is improved repeatedly to approach optimality. This policy iteration process works and always converges to the optimality, but why this is the case?\nSay, we have a policy $\\pi$ and then generate an improved version $\\pi’$ by greedily taking actions, $\\pi’(s) = \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)$. The value of this improved $\\pi’$ is guaranteed to be better because:\n$$\n\\begin{aligned}\nQ_\\pi(s, \\pi'(s))\n&= Q_\\pi(s, \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)) \\\\\n&= \\max_{a \\in \\mathcal{A}} Q_\\pi(s, a) \\geq Q_\\pi(s, \\pi(s)) = V_\\pi(s)\n\\end{aligned}\n$$\nMonte-Carlo Methods\n#\nFirst, let’s recall that $V(s) = \\mathbb{E}[ G_t \\vert S_t=s]$. Monte-Carlo (MC) methods uses a simple idea: It learns from episodes of raw experience without modeling the environmental dynamics and computes the observed mean return as an approximation of the expected return. To compute the empirical return $G_t$, MC methods need to learn from\ncomplete\nepisodes $S_1, A_1, R_2, \\dots, S_T$ to compute $G_t = \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1}$ and all the episodes must eventually terminate.\nThe empirical mean return for state s is:\n$$\nV(s) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s]}\n$$\nwhere $\\mathbb{1}[S_t = s]$ is a binary indicator function. We may count the visit of state s every time so that there could exist multiple visits of one state in one episode (“every-visit”), or only count it the first time we encounter a state in one episode (“first-visit”). This way of approximation can be easily extended to action-value functions by counting (s, a) pair.\n$$\nQ(s, a) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}\n$$\nTo learn the optimal policy by MC, we iterate it by following a similar idea to\nGPI\n.\nImprove the policy greedily with respect to the current value function: $\\pi(s) = \\arg\\max_{a \\in \\mathcal{A}} Q(s, a)$.\nGenerate a new episode with the new policy $\\pi$ (i.e. using algorithms like\nε-greedy\nhelps us balance between exploitation and exploration.)\nEstimate Q using the new episode: $q_\\pi(s, a) = \\frac{\\sum_{t=1}^T \\big( \\mathbb{1}[S_t = s, A_t = a] \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1} \\big)}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}$\nTemporal-Difference Learning\n#\nSimilar to Monte-Carlo methods, Temporal-Difference (TD) Learning is model-free and learns from episodes of experience. However, TD learning can learn from\nincomplete\nepisodes and hence we don’t need to track the episode up to termination. TD learning is so important that Sutton & Barto (2017) in their RL book describes it as “one idea … central and novel to reinforcement learning”.\nBootstrapping\n#\nTD learning methods update targets with regard to existing estimates rather than exclusively relying on actual rewards and complete returns as in MC methods. This approach is known as\nbootstrapping\n.\nValue Estimation\n#\nThe key idea in TD learning is to update the value function $V(S_t)$ towards an estimated return $R_{t+1} + \\gamma V(S_{t+1})$ (known as “\nTD target\n”). To what extent we want to update the value function is controlled by the learning rate hyperparameter α:\n$$\n\\begin{aligned}\nV(S_t) &\\leftarrow (1- \\alpha) V(S_t) + \\alpha G_t \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (G_t - V(S_t)) \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (R_{t+1} + \\gamma V(S_{t+1}) - V(S_t))\n\\end{aligned}\n$$\nSimilarly, for action-value estimation:\n$$\nQ(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t))\n$$\nNext, let’s dig into the fun part on how to learn optimal policy in TD learning (aka “TD control”). Be prepared, you are gonna see many famous names of classic algorithms in this section.\nSARSA: On-Policy TD control\n#\n“SARSA” refers to the procedure of updaing Q-value by following a sequence of $\\dots, S_t, A_t, R_{t+1}, S_{t+1}, A_{t+1}, \\dots$. The idea follows the same route of\nGPI\n. Within one episode, it works as follows:\nInitialize $t=0$.\nStart with $S_0$ and choose action $A_0 = \\arg\\max_{a \\in \\mathcal{A}} Q(S_0, a)$, where\n$\\epsilon$-greedy\nis commonly applied.\nAt time $t$, after applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nThen pick the next action in the same way as in step 2: $A_{t+1} = \\arg\\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a)$.\nUpdate the Q-value function: $ Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t)) $.\nSet $t = t+1$ and repeat from step 3.\nIn each step of SARSA, we need to choose the\nnext\naction according to the\ncurrent\npolicy.\nQ-Learning: Off-policy TD control\n#\nThe development of Q-learning (\nWatkins & Dayan, 1992\n) is a big breakout in the early days of Reinforcement Learning. Within one episode, it works as follows:\nInitialize $t=0$.\nStarts with $S_0$.\nAt time step $t$, we pick the action according to Q values, $A_t = \\arg\\max_{a \\in \\mathcal{A}} Q(S_t, a)$ and $\\epsilon$-greedy is commonly applied.\nAfter applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nUpdate the Q-value function: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma \\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a) - Q(S_t, A_t))$.\n$t = t+1$ and repeat from step 3.\nThe key difference from SARSA is that Q-learning does not follow the current policy to pick the second action $A_{t+1}$. It estimates $Q^*$ out of the best Q values, but which action (denoted as $a^*$) leads to this maximal Q does not matter and in the next step Q-learning may not follow $a^*$.\nThe backup diagrams for Q-learning and SARSA. (Image source: Replotted based on Figure 6.5 in Sutton & Barto (2017))\nDeep Q-Network\n#\nTheoretically, we can memorize $Q_*(.)$ for all state-action pairs in Q-learning, like in a gigantic table. However, it quickly becomes computationally infeasible when the state and action space are large. Thus people use functions (i.e. a machine learning model) to approximate Q values and this is called\nfunction approximation\n. For example, if we use a function with parameter $\\theta$ to calculate Q values, we can label Q value function as $Q(s, a; \\theta)$.\nUnfortunately Q-learning may suffer from instability and divergence when combined with an nonlinear Q-value function approximation and\nbootstrapping\n(See\nProblems #2\n).\nDeep Q-Network (“DQN”; Mnih et al. 2015) aims to greatly improve and stabilize the training procedure of Q-learning by two innovative mechanisms:\nExperience Replay\n: All the episode steps $e_t = (S_t, A_t, R_t, S_{t+1})$ are stored in one replay memory $D_t = \\{ e_1, \\dots, e_t \\}$. $D_t$ has experience tuples over many episodes. During Q-learning updates, samples are drawn at random from the replay memory and thus one sample could be used multiple times. Experience replay improves data efficiency, removes correlations in the observation sequences, and smooths over changes in the data distribution.\nPeriodically Updated Target\n: Q is optimized towards target values that are only periodically updated. The Q network is cloned and kept frozen as the optimization target every C steps (C is a hyperparameter). This modification makes the training more stable as it overcomes the short-term oscillations.\nThe loss function looks like this:\n$$\n\\mathcal{L}(\\theta) = \\mathbb{E}_{(s, a, r, s') \\sim U(D)} \\Big[ \\big( r + \\gamma \\max_{a'} Q(s', a'; \\theta^{-}) - Q(s, a; \\theta) \\big)^2 \\Big]\n$$\nwhere $U(D)$ is a uniform distribution over the replay memory D; $\\theta^{-}$ is the parameters of the frozen target Q-network.\nIn addition, it is also found to be helpful to clip the error term to be between [-1, 1]. (I always get mixed feeling with parameter clipping, as many studies have shown that it works empirically but it makes the math much less pretty. :/)\nAlgorithm for DQN with experience replay and occasionally frozen optimization target. The prepossessed sequence is the output of some processes running on the input images of Atari games. Don't worry too much about it; just consider them as input feature vectors. (Image source: Mnih et al. 2015)\nThere are many extensions of DQN to improve the original design, such as DQN with dueling architecture (Wang et al. 2016) which estimates state-value function V(s) and advantage function A(s, a) with shared network parameters.\nCombining TD and MC Learning\n#\nIn the previous\nsection\non value estimation in TD learning, we only trace one step further down the action chain when calculating the TD target. One can easily extend it to take multiple steps to estimate the return.\nLet’s label the estimated return following n steps as $G_t^{(n)}, n=1, \\dots, \\infty$, then:\n$n$\n$G_t$\nNotes\n$n=1$\n$G_t^{(1)} = R_{t+1} + \\gamma V(S_{t+1})$\nTD learning\n$n=2$\n$G_t^{(2)} = R_{t+1} + \\gamma R_{t+2} + \\gamma^2 V(S_{t+2})$\n…\n$n=n$\n$ G_t^{(n)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1} R_{t+n} + \\gamma^n V(S_{t+n}) $\n…\n$n=\\infty$\n$G_t^{(\\infty)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{T-t-1} R_T + \\gamma^{T-t} V(S_T) $\nMC estimation\nThe generalized n-step TD learning still has the\nsame\nform for updating the value function:\n$$\nV(S_t) \\leftarrow V(S_t) + \\alpha (G_t^{(n)} - V(S_t))\n$$\nWe are free to pick any $n$ in TD learning as we like. Now the question becomes what is the best $n$? Which $G_t^{(n)}$ gives us the best return approximation? A common yet smart solution is to apply a weighted sum of all possible n-step TD targets rather than to pick a single best n. The weights decay by a factor λ with n, $\\lambda^{n-1}$; the intuition is similar to\nwhy\nwe want to discount future rewards when computing the return: the more future we look into the less confident we would be. To make all the weight (n → ∞) sum up to 1, we multiply every weight by (1-λ), because:\n$$\n\\begin{aligned}\n\\text{let } S &= 1 + \\lambda + \\lambda^2 + \\dots \\\\\nS &= 1 + \\lambda(1 + \\lambda + \\lambda^2 + \\dots) \\\\\nS &= 1 + \\lambda S \\\\\nS &= 1 / (1-\\lambda)\n\\end{aligned}\n$$\nThis weighted sum of many n-step returns is called λ-return $G_t^{\\lambda} = (1-\\lambda) \\sum_{n=1}^{\\infty} \\lambda^{n-1} G_t^{(n)}$. TD learning that adopts λ-return for value updating is labeled as\nTD(λ)\n. The original version we introduced\nabove\nis equivalent to\nTD(0)\n.\nComparison of the backup diagrams of Monte-Carlo, Temporal-Difference learning, and Dynamic Programming for state value functions. (Image source: David Silver's RL course\nlecture 4\n: \"Model-Free Prediction\")\nPolicy Gradient\n#\nAll the methods we have introduced above aim to learn the state/action value function and then to select actions accordingly. Policy Gradient methods instead learn the policy directly with a parameterized function respect to $\\theta$, $\\pi(a \\vert s; \\theta)$. Let’s define the reward function (opposite of loss function) as\nthe expected return\nand train the algorithm with the goal to maximize the reward function. My\nnext post\ndescribed why the policy gradient theorem works (proof) and introduced a number of policy gradient algorithms.\nIn discrete space:\n$$\n\\mathcal{J}(\\theta) = V_{\\pi_\\theta}(S_1) = \\mathbb{E}_{\\pi_\\theta}[V_1]\n$$\nwhere $S_1$ is the initial starting state.\nOr in continuous space:\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) V_{\\pi_\\theta}(s) = \\sum_{s \\in \\mathcal{S}} \\Big( d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s, \\theta) Q_\\pi(s, a) \\Big)\n$$\nwhere $d_{\\pi_\\theta}(s)$ is stationary distribution of Markov chain for $\\pi_\\theta$. If you are unfamiliar with the definition of a “stationary distribution,” please check this\nreference\n.\nUsing\ngradient ascent\nwe can find the best θ that produces the highest return. It is natural to expect policy-based methods are more useful in continuous space, because there is an infinite number of actions and/or states to estimate the values for in continuous space and hence value-based approaches are computationally much more expensive.\nPolicy Gradient Theorem\n#\nComputing the gradient\nnumerically\ncan be done by perturbing θ by a small amount ε in the k-th dimension. It works even when $J(\\theta)$ is not differentiable (nice!), but unsurprisingly very slow.\n$$\n\\frac{\\partial \\mathcal{J}(\\theta)}{\\partial \\theta_k} \\approx \\frac{\\mathcal{J}(\\theta + \\epsilon u_k) - \\mathcal{J}(\\theta)}{\\epsilon}\n$$\nOr\nanalytically\n,\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [r] = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) R(s, a)\n$$\nActually we have nice theoretical support for (replacing $d(.)$ with $d_\\pi(.)$):\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\propto \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a)\n$$\nCheck Sec 13.1 in Sutton & Barto (2017) for why this is the case.\nThen,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n\\nabla \\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\nabla \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n&= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\frac{\\nabla \\pi(a \\vert s; \\theta)}{\\pi(a \\vert s; \\theta)} Q_\\pi(s, a) \\\\\n& = \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n& = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a)]\n\\end{aligned}\n$$\nThis result is named “Policy Gradient Theorem” which lays the theoretical foundation for various policy gradient algorithms:\n$$\n\\nabla \\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s, \\theta) Q_\\pi(s, a)]\n$$\nREINFORCE\n#\nREINFORCE, also known as Monte-Carlo policy gradient, relies on $Q_\\pi(s, a)$, an estimated return by\nMC\nmethods using episode samples, to update the policy parameter $\\theta$.\nA commonly used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to reduce the variance of gradient estimation while keeping the bias unchanged. For example, a common baseline is state-value, and if applied, we would use $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update.\nInitialize θ at random\nGenerate one episode $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$\nFor t=1, 2, … , T:\nEstimate the the return G_t since the time step t.\n$\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla \\ln \\pi(A_t \\vert S_t, \\theta)$.\nActor-Critic\n#\nIf the value function is learned in addition to the policy, we would get Actor-Critic algorithm.\nCritic\n: updates value function parameters w and depending on the algorithm it could be action-value $Q(a \\vert s; w)$ or state-value $V(s; w)$.\nActor\n: updates policy parameters θ, in the direction suggested by the critic, $\\pi(a \\vert s; \\theta)$.\nLet’s see how it works in an action-value actor-critic algorithm.\nInitialize s, θ, w at random; sample $a \\sim \\pi(a \\vert s; \\theta)$.\nFor t = 1… T:\nSample reward $r_t  \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$.\nThen sample the next action $a’ \\sim \\pi(s’, a’; \\theta)$.\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q(s, a; w) \\nabla_\\theta \\ln \\pi(a \\vert s; \\theta)$.\nCompute the correction for action-value at time t:\n$G_{t:t+1} = r_t + \\gamma Q(s’, a’; w) - Q(s, a; w)$\nand use it to update value function parameters:\n$w \\leftarrow w + \\alpha_w G_{t:t+1} \\nabla_w Q(s, a; w) $.\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\n$\\alpha_\\theta$ and $\\alpha_w$ are two learning rates for policy and value function parameter updates, respectively.\nA3C\n#\nAsynchronous Advantage Actor-Critic\n(Mnih et al., 2016), short for A3C, is a classic policy gradient method with the special focus on parallel training.\nIn A3C, the critics learn the state-value function, $V(s; w)$, while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is good for parallel training by default, i.e. on one machine with multi-core CPU.\nThe loss function for state-value is to minimize the mean squared error, $\\mathcal{J}_v (w) = (G_t - V(s; w))^2$ and we use gradient descent to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, θ and w; similar thread-specific parameters, θ’ and w'.\nInitialize the time step t = 1\nWhile T <= T_MAX:\nReset gradient: dθ = 0 and dw = 0.\nSynchronize thread-specific parameters with global ones: θ’ = θ and w’ = w.\n$t_\\text{start}$ = t and get $s_t$.\nWhile ($s_t \\neq \\text{TERMINAL}$) and ($t - t_\\text{start} <= t_\\text{max}$):\nPick the action $a_t \\sim \\pi(a_t \\vert s_t; \\theta’)$ and receive a new reward $r_t$ and a new state $s_{t+1}$.\nUpdate t = t + 1 and T = T + 1.\nInitialize the variable that holds the return estimation $$R = \\begin{cases}\n0 & \\text{if } s_t \\text{ is TERMINAL} \\\nV(s_t; w’) & \\text{otherwise}\n\\end{cases}$$.\nFor $i = t-1, \\dots, t_\\text{start}$:\n$R \\leftarrow r_i + \\gamma R$; here R is a MC measure of $G_i$.\nAccumulate gradients w.r.t. θ’: $d\\theta \\leftarrow d\\theta + \\nabla_{\\theta’} \\log \\pi(a_i \\vert s_i; \\theta’)(R - V(s_i; w’))$;\nAccumulate gradients w.r.t. w’: $dw \\leftarrow dw + \\nabla_{w’} (R - V(s_i; w’))^2$.\nUpdate synchronously θ using dθ, and w using dw.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a reformation of minibatch-based stochastic gradient update: the values of w or θ get corrected by a little bit in the direction of each training thread independently.\nEvolution Strategies\n#\nEvolution Strategies\n(ES) is a type of model-agnostic optimization approach. It learns the optimal solution by imitating Darwin’s theory of the evolution of species by natural selection. Two prerequisites for applying ES: (1) our solutions can freely interact with the environment and see whether they can solve the problem; (2) we are able to compute a\nfitness\nscore of how good each solution is. We don’t have to know the environment configuration to solve the problem.\nSay, we start with a population of random solutions. All of them are capable of interacting with the environment and only candidates with high fitness scores can survive (\nonly the fittest can survive in a competition for limited resources\n). A new generation is then created by recombining the settings (\ngene mutation\n) of high-fitness survivors. This process is repeated until the new solutions are good enough.\nVery different from the popular MDP-based approaches as what we have introduced above, ES aims to learn the policy parameter $\\theta$ without value approximation. Let’s assume the distribution over the parameter $\\theta$ is an\nisotropic\nmultivariate Gaussian with mean $\\mu$ and fixed covariance $\\sigma^2I$. The gradient of $F(\\theta)$ is calculated:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} F(\\theta) \\\\\n=& \\nabla_\\theta \\int_\\theta F(\\theta) \\Pr(\\theta) && \\text{Pr(.) is the Gaussian density function.} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\frac{\\nabla_\\theta \\Pr(\\theta)}{\\Pr(\\theta)} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\nabla_\\theta \\log \\Pr(\\theta) \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} [F(\\theta) \\nabla_\\theta \\log \\Pr(\\theta)] && \\text{Similar to how we do policy gradient update.} \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\log \\Big( \\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(\\theta - \\mu)^2}{2 \\sigma^2 }} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\Big( -\\log \\sqrt{2\\pi\\sigma^2} - \\frac{(\\theta - \\mu)^2}{2 \\sigma^2} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\frac{\\theta - \\mu}{\\sigma^2} \\Big]\n\\end{aligned}\n$$\nWe can rewrite this formula in terms of a “mean” parameter $\\theta$ (different from the $\\theta$ above; this $\\theta$ is the base gene for further mutation), $\\epsilon \\sim N(0, I)$ and therefore $\\theta + \\epsilon \\sigma \\sim N(\\theta, \\sigma^2)$. $\\epsilon$ controls how much Gaussian noises should be added to create mutation:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\epsilon \\sim N(0, I)} F(\\theta + \\sigma \\epsilon) = \\frac{1}{\\sigma} \\mathbb{E}_{\\epsilon \\sim N(0, I)} [F(\\theta + \\sigma \\epsilon) \\epsilon]\n$$\nA simple parallel evolution-strategies-based RL algorithm. Parallel workers share the random seeds so that they can reconstruct the Gaussian noises with tiny communication bandwidth. (Image source: Salimans et al. 2017.)\nES, as a black-box optimization algorithm, is another approach to RL problems (\nIn my original writing, I used the phrase “a nice alternative”;\nSeita\npointed me to this\ndiscussion\nand thus I updated my wording.\n). It has a couple of good characteristics (Salimans et al., 2017) keeping it fast and easy to train:\nES does not need value function approximation;\nES does not perform gradient back-propagation;\nES is invariant to delayed or long-term rewards;\nES is highly parallelizable with very little data communication.\nKnown Problems\n#\nExploration-Exploitation Dilemma\n#\nThe problem of exploration vs exploitation dilemma has been discussed in my previous\npost\n. When the RL problem faces an unknown environment, this issue is especially a key to finding a good solution: without enough exploration, we cannot learn the environment well enough; without enough exploitation, we cannot complete our reward optimization task.\nDifferent RL algorithms balance between exploration and exploitation in different ways. In\nMC\nmethods,\nQ-learning\nor many on-policy algorithms, the exploration is commonly implemented by\nε-greedy\n; In\nES\n, the exploration is captured by the policy parameter perturbation. Please keep this into consideration when developing a new RL algorithm.\nDeadly Triad Issue\n#\nWe do seek the efficiency and flexibility of TD methods that involve bootstrapping. However, when off-policy, nonlinear function approximation, and bootstrapping are combined in one RL algorithm, the training could be unstable and hard to converge. This issue is known as the\ndeadly triad\n(Sutton & Barto, 2017). Many architectures using deep learning models were proposed to resolve the problem, including DQN to stabilize the training with experience replay and occasionally frozen target network.\nCase Study: AlphaGo Zero\n#\nThe game of\nGo\nhas been an extremely hard problem in the field of Artificial Intelligence for decades until recent years. AlphaGo and AlphaGo Zero are two programs developed by a team at DeepMind. Both involve deep Convolutional Neural Networks (\nCNN\n) and Monte Carlo Tree Search (MCTS) and both have been approved to achieve the level of professional human Go players. Different from AlphaGo that relied on supervised learning from expert human moves, AlphaGo Zero used only reinforcement learning and self-play without human knowledge beyond the basic rules.\nThe board of Go. Two players play black and white stones alternatively on the vacant intersections of a board with 19 x 19 lines. A group of stones must have at least one open point (an intersection, called a \"liberty\") to remain on the board and must have at least two or more enclosed liberties (called \"eyes\") to stay \"alive\". No stone shall repeat a previous position.\nWith all the knowledge of RL above, let’s take a look at how AlphaGo Zero works. The main component is a deep\nCNN\nover the game board configuration (precisely, a\nResNet\nwith batch normalization and ReLU). This network outputs two values:\n$$\n(p, v) = f_\\theta(s)\n$$\n$s$: the game board configuration, 19 x 19 x 17 stacked feature planes; 17 features for each position, 8 past configurations (including current) for the current player + 8 past configurations for the opponent + 1 feature indicating the color (1=black, 0=white). We need to code the color specifically because the network is playing with itself and the colors of current player and opponents are switching between steps.\n$p$: the probability of selecting a move over 19^2 + 1 candidates (19^2 positions on the board, in addition to passing).\n$v$: the winning probability given the current setting.\nDuring self-play, MCTS further improves the action probability distribution $\\pi \\sim p(.)$ and then the action $a_t$ is sampled from this improved policy. The reward $z_t$ is a binary value indicating whether the current player\neventually\nwins the game. Each move generates an episode tuple $(s_t, \\pi_t, z_t)$ and it is saved into the replay memory. The details on MCTS are skipped for the sake of space in this post; please read the original\npaper\nif you are interested.\nAlphaGo Zero is trained by self-play while MCTS improves the output policy further in every step. (Image source: Figure 1a in Silver et al., 2017).\nThe network is trained with the samples in the replay memory to minimize the loss:\n$$\n\\mathcal{L} = (z - v)^2 - \\pi^\\top \\log p + c \\| \\theta \\|^2\n$$\nwhere $c$ is a hyperparameter controlling the intensity of L2 penalty to avoid overfitting.\nAlphaGo Zero simplified AlphaGo by removing supervised learning and merging separated policy and value networks into one. It turns out that AlphaGo Zero achieved largely improved performance with a much shorter training time! I strongly recommend reading these\ntwo\npapers\nside by side and compare the difference, super fun.\nI know this is a long read, but hopefully worth it.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com].\nSee you in the next post! :)\nCited as:\n@article{weng2018bandit,\n  title   = \"A (Long) Peek into Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-02-19-rl-overview/\"\n}\nReferences\n#\n[1] Yuxi Li.\nDeep reinforcement learning: An overview.\narXiv preprint arXiv:1701.07274. 2017.\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] Volodymyr Mnih, et al.\nAsynchronous methods for deep reinforcement learning.\nICML. 2016.\n[4] Tim Salimans, et al.\nEvolution strategies as a scalable alternative to reinforcement learning.\narXiv preprint arXiv:1703.03864 (2017).\n[5] David Silver, et al.\nMastering the game of go without human knowledge\n. Nature 550.7676 (2017): 354.\n[6] David Silver, et al.\nMastering the game of Go with deep neural networks and tree search.\nNature 529.7587 (2016): 484-489.\n[7] Volodymyr Mnih, et al.\nHuman-level control through deep reinforcement learning.\nNature 518.7540 (2015): 529.\n[8] Ziyu Wang, et al.\nDueling network architectures for deep reinforcement learning.\nICML. 2016.\n[9]\nReinforcement Learning lectures\nby David Silver on YouTube.\n[10] OpenAI Blog:\nEvolution Strategies as a Scalable Alternative to Reinforcement Learning\n[11] Frank Sehnke, et al.\nParameter-exploring policy gradients.\nNeural Networks 23.4 (2010): 551-559.\n[12] Csaba Szepesvári.\nAlgorithms for reinforcement learning.\n1st Edition. Synthesis lectures on artificial intelligence and machine learning 4.1 (2010): 1-103.\nIf you notice mistakes and errors in this post, please don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be super happy to correct them right away!",
            "metadata": {
              "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
              "description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "A (Long) Peek into Reinforcement Learning",
              "og:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
              "twitter:card": "summary",
              "twitter:title": "A (Long) Peek into Reinforcement Learning",
              "twitter:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "article:section": "posts",
              "article:published_time": "2018-02-19T00:00:00+00:00",
              "article:modified_time": "2018-02-19T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/9e1d58627b38/code/body-000.txt",
                "chars": 241,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "bytes": 58269,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-418c8992a5cc9d9deeb1.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "bytes": 107025,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d53eaab123d7a3b8d561.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "bytes": 33772,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-1a3ee27cdec9dd4e95e7.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "bytes": 55693,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8b930e0942e1d249d7cd.jpg",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "bytes": 27143,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-508e643f8751bb71fcf3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "bytes": 32728,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-aa4ac628fe85693e0ba3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "bytes": 21618,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8917c12943284b1507b6.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "bytes": 133435,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-c1fcc0568374ce65ea91.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "bytes": 35850,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-be7712dd68a63d561005.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "bytes": 128382,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d374974862f12f0f0ada.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "bytes": 91431,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-0d8b962a59d7ad31b2ef.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "bytes": 136647,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-3ceb5a7713444f264e70.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "bytes": 61555,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-070437b06f4b4d8a0287.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=2pWv7GOvuf0",
                "src": "https://youtu.be/2pWv7GOvuf0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/9e1d58627b38/videos/repair-2pWv7GOvuf0.mp4",
                "bytes": 397520008,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5292.421000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "src": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "status": "playlist_discovery_failed",
                "kind": "playlist",
                "reason": "播放列表返回空或不完整结果，保留原记录并等待重试",
                "error": "WARNING: [youtube:tab] YouTube said: The playlist does not exist.\nERROR: [youtube:tab] PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT: YouTube said: The playlist does not exist.\n",
                "retried_at": "2026-10-20T22:23:33Z"
              }
            ],
            "links": [
              {
                "href": "https://paperexplained.cn/articles/article/detail/33/",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dynamic_programming",
                "label": "Dynamic Programming",
                "type": "a"
              },
              {
                "href": "https://youtu.be/2pWv7GOvuf0",
                "label": "lecture 1",
                "type": "a"
              },
              {
                "href": "https://randomant.net/reinforcement-learning-concepts/",
                "label": "randomant.net/reinforcement-learning-concepts",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "ε-greedy",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "label": "Watkins & Dayan, 1992",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "label": "lecture 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "next post",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "reference",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolution Strategies",
                "type": "a"
              },
              {
                "href": "https://math.stackexchange.com/questions/1991961/gaussian-distribution-is-isotropic",
                "label": "isotropic",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/",
                "label": "Seita",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/r/MachineLearning/comments/6gke6a/d_requesting_openai_to_justify_the_grandiose/dir9wde/",
                "label": "discussion",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Go_(game)",
                "label": "Go",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "CNN",
                "type": "a"
              },
              {
                "href": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "label": "two",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07274.pdf",
                "label": "Deep reinforcement learning: An overview.",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Reinforcement Learning: An Introduction; 2nd Edition",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "label": "Asynchronous methods for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.03864.pdf",
                "label": "Evolution strategies as a scalable alternative to reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "label": "Human-level control through deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.06581.pdf",
                "label": "Dueling network architectures for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "label": "Reinforcement Learning lectures",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/evolution-strategies/",
                "label": "Evolution Strategies as a Scalable Alternative to Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "label": "Parameter-exploring policy gradients.",
                "type": "a"
              },
              {
                "href": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "label": "Algorithms for reinforcement learning.",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:33Z",
            "source_url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "papers": [
              {
                "status": "invalid_file_type",
                "url": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:14Z"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "retried_at": "2026-10-20T17:36:31Z"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07274.pdf",
                "bytes": 1380080,
                "reused": false,
                "local_path": "papers/repair/b6ffc91d59527939bdfc.pdf"
              },
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": true,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "bytes": 2455923,
                "reused": false,
                "local_path": "papers/repair/de6e461fa7ff09fc7981.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864.pdf",
                "bytes": 277340,
                "reused": false,
                "local_path": "papers/repair/d7a6ba3d9a896a29908d.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "bytes": 4600582,
                "reused": false,
                "local_path": "papers/repair/a86f4e3a12fbcea87e0c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06581.pdf",
                "bytes": 688509,
                "reused": false,
                "local_path": "papers/repair/f1c991f0c8eda83cb980.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "bytes": 1623436,
                "reused": false,
                "local_path": "papers/repair/fbf59542cdbde527181b.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 40855,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404；invalid_file_type；playlist_discovery_failed",
            "raw_html": "attachments/9e1d58627b38/pages/source.html",
            "local_html": "attachments/9e1d58627b38/pages/article.html",
            "body_base_path": "attachments/9e1d58627b38/pages/",
            "body_markdown_path": "attachments/9e1d58627b38/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
          "status": "ok",
          "article_id": "4ceb83900555",
          "local_path": "series-follow/1600/repair/e7cc4652c4afc9c11bf9.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
              "bytes": 205910,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2795fb5ace8ffbc1b24d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
              "bytes": 483584,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/1ad2438e764ecf66f44b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
              "bytes": 88034,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c8c63c3f68a56e1637ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
              "bytes": 791396,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/cfd79c5354e69b23974e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
              "bytes": 464686,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/3c61bc54c452df857d49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
              "bytes": 412094,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/896ff9901d3559eccc2a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
              "bytes": 208079,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a68ed63975ef71160d3c.png"
            }
          ],
          "article": {
            "id": "4ceb83900555",
            "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "bytes": 205910,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-2795fb5ace8ffbc1b24d.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "bytes": 483584,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-1ad2438e764ecf66f44b.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "bytes": 88034,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-c8c63c3f68a56e1637ef.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "bytes": 791396,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-cfd79c5354e69b23974e.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "bytes": 464686,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-3c61bc54c452df857d49.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "bytes": 412094,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-896ff9901d3559eccc2a.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "bytes": 208079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-a68ed63975ef71160d3c.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=DKe8FumoD4E",
                "src": "https://www.youtube.com/embed/DKe8FumoD4E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4ceb83900555/videos/repair-DKe8FumoD4E.mp4",
                "bytes": 37082109,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "434.721000",
                "reused": false
              }
            ],
            "body_markdown": "In Robotics, one of the hardest problems is how to make your model transfer to the real world. Due to the sample inefficiency of deep RL algorithms and the cost of data collection on real robots, we often need to train models in a simulator which theoretically provides an infinite amount of data. However, the reality gap between the simulator and the physical world often leads to failure when working with physical robots. The gap is triggered by an inconsistency between physical parameters (i.e. friction, kp, damping, mass, density) and, more fatally, the incorrect physical modeling (i.e. collision between soft surfaces).\nTo close the sim2real gap, we need to improve the simulator and make it closer to reality. A couple of approaches:\nSystem identification\nSystem identification\nis to build a mathematical model for a physical system; in the context of RL, the mathematical model is the simulator. To make the simulator more realistic, careful calibration is necessary.\nUnfortunately, calibration is expensive. Furthermore, many physical parameters of the same machine might vary significantly due to temperature, humidity, positioning or its wear-and-tear in time.\nDomain adaptation\nDomain adaptation (DA)\nrefers to a set of transfer learning techniques developed to update the data distribution in sim to match the real one through a mapping or regularization enforced by the task model.\nMany DA models, especially for image classification or end-to-end image-based RL task, are built on adversarial loss or\nGAN\n.\nDomain randomization\nWith\ndomain randomization (DR)\n, we are able to create a variety of simulated environments with randomized properties and train a model that works across all of them.\nLikely this model can adapt to the real-world environment, as the real system is expected to be one sample in that rich distribution of training variations.\nBoth DA and DR are unsupervised. Compared to DA which requires a decent amount of real data samples to capture the distribution, DR may need\nonly a little or no\nreal data. DR is the focus of this post.\nConceptual illustrations of three approaches for sim2real transfer.\nWhat is Domain Randomization?\n#\nTo make the definition more general, let us call the environment that we have full access to (i.e. simulator)\nsource domain\nand the environment that we would like to transfer the model to\ntarget domain\n(i.e. physical world). Training happens in the source domain. We can control a set of $N$ randomization parameters in the source domain $e_\\xi$ with a configuration $\\xi$, sampled from a randomization space, $\\xi \\in \\Xi \\subset \\mathbb{R}^N$.\nDuring policy training, episodes are collected from source domain with randomization applied. Thus the policy is exposed to a variety of environments and learns to generalize. The policy parameter $\\theta$ is trained to maximize the expected reward $R(.)$ average across a distribution of configurations:\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{\\xi \\sim \\Xi} [\\mathbb{E}_{\\pi_\\theta, \\tau \\sim e_\\xi} [R(\\tau)]]\n$$\nwhere $\\tau_\\xi$ is a trajectory collected in source domain randomized with $\\xi$. In a way,\n“discrepancies between the source and target domains are modeled as variability in the source domain.”\n(quote from\nPeng et al. 2018\n).\nUniform Domain Randomization\n#\nIn the original form of DR (\nTobin et al, 2017\n;\nSadeghi et al. 2016\n), each randomization parameter $\\xi_i$ is bounded by an interval, $\\xi_i \\in [\\xi_i^\\text{low}, \\xi_i^\\text{high}], i=1,\\dots,N$ and each parameter is uniformly sampled within the range.\nThe randomization parameters can control appearances of the scene, including but not limited to the followings (see Fig. 2). A model trained on simulated and randomized images is able to transfer to real non-randomized images.\nPosition, shape, and color of objects,\nMaterial texture,\nLighting condition,\nRandom noise added to images,\nPosition, orientation, and field of view of the camera in the simulator.\nImages captured in the training environment are randomized. (Image source:\nTobin et al, 2017\n)\nPhysical dynamics in the simulator can also be randomized (\nPeng et al. 2018\n). Studies have showed that a\nrecurrent\npolicy can adapt to different physical dynamics including the partially observable reality. A set of physical dynamics features include but are not limited to:\nMass and dimensions of objects,\nMass and dimensions of robot bodies,\nDamping, kp, friction of the joints,\nGains for the PID controller (P term),\nJoint limit,\nAction delay,\nObservation noise.\nWith visual and dynamics DR, at OpenAI Robotics, we were able to learn a policy that works on real dexterous robot hand (\nOpenAI, 2018\n). Our manipulation task is to teach the robot hand to rotate an object continously to achieve 50 successive random target orientations. The sim2real gap in this task is very large, due to (a) a high number of simultaneous contacts between the robot and the object and (b) imperfect simulation of object collision and other motions. At first, the policy could barely survive for more than 5 seconds without dropping the object. But with the help of DR, the policy evolved to work surprisingly well in reality eventually.\nWhy does Domain Randomization Work?\n#\nNow you may ask, why does domain randomization work so well? The idea sounds really simple. Here are two non-exclusive explanations I found most convincing.\nDR as Optimization\n#\nOne idea (\nVuong, et al, 2019\n) is to view learning randomization parameters in DR as a\nbilevel optimization\n. Assuming we have access to the real environment $e_\\text{real}$ and the randomization config is sampled from a distribution parameterized by $\\phi$, $\\xi \\sim P_\\phi(\\xi)$, we would like to learn a distribution on which a policy $\\pi_\\theta$ is trained on can achieve maximal performance in $e_\\text{real}$:\n$$\n\\begin{aligned}\n&\\phi^* = \\arg\\min_{\\phi} \\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real}) \\\\\n\\text{where } &\\theta^*(\\phi) = \\arg\\min_\\theta \\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)}[\\mathcal{L}(\\pi_\\theta; e_\\xi)]\n\\end{aligned}\n$$\nwhere $\\mathcal{L}(\\pi; e)$ is the loss function of policy $\\pi$ evaluated in the environment $e$.\nAlthough randomization ranges are hand-picked in uniform DR, it often involves domain knowledge and a couple rounds of trial-and-error adjustment based on the transfer performance. Essentially this is a manual optimization process on tuning $\\phi$ for the optimal $\\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real})$.\nGuided domain randomization in the next section is largely inspired by this view, aiming to do bilevel optimization and learn the best parameter distribution automatically.\nDR as Meta-Learning\n#\nIn our learning dexterity project (\nOpenAI, 2018\n), we trained an LSTM policy to generalize across different environmental dynamics. We observed that once a robot achieved the first rotation, the time it needed for the following successes was much shorter. Also, a FF policy without memory was found not able to transfer to a physical robot. Both are evidence of the policy dynamically learning and adapting to a new environment.\nIn some ways, domain randomization composes a collection of different tasks. Memory in the recurrent network empowers the policy to achieve\nmeta-learning\nacross tasks and further work on a real-world setting.\nGuided Domain Randomization\n#\nThe vanilla DR assumes no access to the real data, and thus the randomization config is sampled as broadly and uniformly as possible in sim, hoping that the real environment could be covered under this broad distribution. It is reasonable to think of a more sophisticated strategy — replacing uniform sampling with guidance from\ntask performance\n,\nreal data\n, or\nsimulator\n.\nOne motivation for guided DR is to save computation resources by avoiding training models in unrealistic environments. Another is to avoid infeasible solutions that might arise from overly wide randomization distributions and thus might hinder successful policy learning.\nOptimization for Task Performance\n#\nSay we train a family of policies with different randomization parameters $\\xi \\sim P_\\phi(\\xi)$, where $P_\\xi$ is the distribution for $\\xi$ parameterized by $\\phi$. Later we decide to try every one of them on the downstream task in the target domain (i.e. control a robot in reality or evaluate on a validation set) to collect feedback. This feedback tells us how good a configuration $\\xi$ is and provides signals for optimizing $\\phi$.\nInspired by\nNAS\n,\nAutoAugment\n(\nCubuk, et al. 2018\n) frames the problem of learning best data augmentation operations (i.e.  shearing, rotation, invert, etc.) for image classification as an RL problem. Note that AutoAugment is not proposed for sim2real transfer, but falls in the bucket of DR guided by task performance. Individual augmentation configuration is tested on the evaluation set and the performance improvement is used as a reward to train a PPO policy. This policy outputs different augmentation strategies for different datasets; for example, for CIFAR-10 AutoAugment mostly  picks color-based transformations, while ImageNet prefers geometric based.\nRuiz (2019)\nconsidered the\ntask feedback\nas\nreward\nin RL problem and proposed a RL-based method, named “learning to simulate”, for adjusting $\\xi$. A policy is trained to predict $\\xi$ using performance metrics on the validation data of the main task as rewards, which is modeled as a multivariate Gaussian. Overall the idea is similar to AutoAugment, applying NAS on data generation. According to their experiments, even if the main task model is not converged, it still can provide a reasonable signal to the data generation policy.\nAn overview of the \"learning to simulate\" approach. (Image source:\nRuiz (2019)\n)\nEvolutionary algorithm is another way to go, where the\nfeedback\nis treated as\nfitness\nfor guiding evolution (\nYu et al, 2019\n). In this study, they used\nCMA-ES\n(covariance matrix adaptation evolution strategy) while fitness is the performance of a $\\xi$-conditional policy in target environment. In the appendix, they compared CMA-ES with other ways of modeling the dynamics of $\\xi$, including Bayesian optimization or a neural network. The main claim was those methods are not as stable or sample efficient as CMA-ES. Interestly, when modeling $P(\\xi)$ as a neural network, LSTM is found to notably outperform FF.\nSome believe that sim2real gap is a combination of appearance gap and content gap; i.e. most GAN-inspired DA models focus on appearance gap.\nMeta-Sim\n(\nKar, et al. 2019\n) aims to close the content gap by generating task-specific synthetic datasets. Meta-Sim uses self-driving car training as an example and thus the scene could be very complicated. In this case, the synthetic scenes are parameterized by a hierarchy of objects with properties (i.e., location, color) as well as relationships between objects. The hierarchy is specified by a probabilistic scene grammar akin to structure domain randomization (\nSDR\n;\nPrakash et al., 2018\n) and it is assumed to be known beforehand. A model $G$ is trained to augment the distribution of scene properties $s$ by following:\nLearn the prior first: pre-train $G$ to learn the identity function $G(s) = s$.\nMinimize MMD loss between the real and sim data distributions. This involves backpropagation through non-differentiable renderer. The paper computes it numerically by perturbing the attributes of $G(s)$.\nMinimize REINFORCE task loss when trained on synthetic data but evaluated on real data. Again, very similar to AutoAugment.\nUnfortunately, this family of methods are not suitable for sim2real case. Either an RL policy or an EA model requires a large number of real samples. And it is really expensive to include real-time feedback collection on a physical robot into the training loop. Whether you want to trade less computation resource for real data collection would depend on your task.\nMatch Real Data Distribution\n#\nUsing real data to guide domain randomization feels a lot like doing system identification or DA. The core idea behind DA is to improve the synthetic data to match the real data distribution. In the case of real-data-guided DR, we would like to learn the randomization parameters $\\xi$ that bring the state distribution in simulator close to the state distribution in the real world.\nThe\nSimOpt\nmodel (\nChebotar et al, 2019\n) is trained under an initial randomization distribution $P_\\phi(\\xi)$ first, getting a policy $\\pi_{\\theta, P_\\phi}$. Then this policy is deployed on both simulator and physical robot to collect trajectories $\\tau_\\xi$ and $\\tau_\\text{real}$ respectively. The optimization objective is to minimize the discrepancy between sim and real trajectories:\n$$\n\\phi^* = \\arg\\min_{\\phi}\\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)} [\\mathbb{E}_{\\pi_{\\theta, P_\\phi}} [D(\\tau_\\text{sim}, \\tau_\\text{real})]]\n$$\nwhere $D(.)$ is a trajectory-based discrepancy measure. Like the “Learning to simulate” paper, SimOpt also has to solve the tricky problem of how to propagate gradient through non-differentiable simulator. It used a method called\nrelative entropy policy search\n, see paper for more details.\nAn overview of the SimOpt framework. (Image source:\nChebotar et al, 2019\n)\nRCAN\n(\nJames et al., 2019\n), short for “Randomized-to-Canonical Adaptation Networks”, is a nice combination of DA and DR for end-to-end RL tasks. An image-conditional GAN (\ncGAN\n) is trained in sim to translate a domain-randomized image into a non-randomized version (aka “canonical version”). Later the same model is used to translate real images into corresponding simulated version so that the agent would consume consistent observation as what it has encountered in training. Still, the underlying assumption is that the distribution of domain-randomized sim images is broad enough to cover real-world samples.\nRCAN is an image-conditional generator that can convert a domain-randomized or real image into its corresponding non-randomized simulator version. (Image source:\nJames et al., 2019\n)\nThe RL model is trained end-to-end in a simulator to do vision-based robot arm grasping. Randomization is applied at each timestep, including the position of tray divider, objects to grasp, random textures, as well as the position, direction, and color of the lighting. The canonical version is the default simulator look. RCAN is trying to learn a generator\n$G$: randomized image $\\to$ {canonical image, segmentation, depth}\nwhere segmentation masks and depth images are used as auxiliary tasks. RCAN had a better zero-shot transfer compared to uniform DR, although both were shown to be worse than the model trained on only real images. Conceptually, RCAN operates in a reverse direction of\nGraspGAN\nwhich translates synthetic images into real ones by domain adaptation.\nGuided by Data in Simulator\n#\nNetwork-driven domain randomization (\nZakharov et al., 2019\n), also known as\nDeceptionNet\n,  is motivated by learning which randomizations are actually useful to bridge the domain gap for image classification tasks.\nRandomization is applied through a set of deception modules with encoder-decoder architecture. The deception modules are specifically designed to transform images; such as change backgrounds, add distortion, change lightings, etc. The other recognition network handles the main task by running classification on transformed images.\nThe training involves two steps:\nWith the recognition network fixed,\nmaximize the difference\nbetween the prediction and the labels by applying reversed gradients during backpropagation.  So that the deception module can learn the most confusing tricks.\nWith the deception modules fixed, train the recognition network with input images altered.\nHow DeceptionNet works. (Image source:\nZakharov et al., 2019\n)\nThe feedback for training deception modules is provided by the downstream classifier. But rather than trying to maximize the task performance like\nthe section\nabove, the randomization modules aim to create harder cases. One big disadvantage is you need to manually design different deception modules for different datasets or tasks, making it not easily scalable. Given the fact that it is zero-shot, the results are still worse than SOTA DA methods on MNIST and LineMOD.\nSimilarly, Active domain randomization (\nADR\n;\nMehta et al., 2019\n) also relies on sim data to create harder training samples. ADR searches for the\nmost informative\nenvironment variations within the given randomization ranges, where the\ninformativeness\nis measured as the discrepancies of policy rollouts in randomized and reference (original, non-randomized) environment instances. Sounds a bit like\nSimOpt\n? Well, noted that SimOpt measures the discrepancy between sim and real rollouts, while ADR measures between randomized and non-randomized sim, avoiding the expensive real data collection part.\nHow active domain randomization (ADR) works. (Image source:\nMehta et al., 2019\n)\nPrecisely the training happens as follows:\nGiven a policy, run it on both reference and randomized envs and collect two sets of trajectories respectively.\nTrain a discriminator model to tell whether a rollout trajectory is randomized apart from reference run. The predicted $\\log p$ (probability of being randomized) is used as reward. The more different randomized and reference rollouts, the easier the prediction, the higher the reward.\nThe intuition is that if an environment is easy, the same policy agent can produce similar trajectories as in the reference one. Then the model should reward and explore hard environments by encouraging different behaviors.\nThe reward by discriminator is fed into\nStein Variational Policy Gradient\n(\nSVPG\n) particles, outputting a diverse set of randomization configurations.\nThe idea of ADR is very appealing with two small concerns. The similarity between trajectories might not be a good way to measure the env difficulty when running a stochastic policy. The sim2real results look unfortunately not as exciting, but the paper pointed out the win being ADR explores a smaller range of randomization parameters.\nCited as:\n@article{weng2019DR,\n  title   = \"Domain Randomization for Sim2Real Transfer\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-05-05-domain-randomization/\"\n}\nOverall, after reading this post, I hope you like domain randomization as much as I do :).\nReferences\n#\n[1] Josh Tobin, et al.\n“Domain randomization for transferring deep neural networks from simulation to the real world.”\nIROS, 2017.\n[2] Fereshteh Sadeghi and Sergey Levine.\n“CAD2RL: Real single-image flight without a single real image.”\narXiv:1611.04201 (2016).\n[3] Xue Bin Peng, et al.\n“Sim-to-real transfer of robotic control with dynamics randomization.”\nICRA, 2018.\n[4] Nataniel Ruiz, et al.\n“Learning to Simulate.”\nICLR 2019\n[5] OpenAI.\n“Learning Dexterous In-Hand Manipulation.”\narXiv:1808.00177 (2018).\n[6] OpenAI Blog.\n“Learning dexterity”\nJuly 30, 2018.\n[7] Quan Vuong, et al.\n“How to pick the domain randomization parameters for sim-to-real transfer of reinforcement learning policies?.”\narXiv:1903.11774 (2019).\n[8] Ekin D. Cubuk, et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv:1805.09501 (2018).\n[9] Wenhao Yu et al.\n“Policy Transfer with Strategy Optimization.”\nICLR 2019\n[10] Yevgen Chebotar et al.\n“Closing the Sim-to-Real Loop: Adapting Simulation Randomization with Real World Experience.”\nArxiv: 1810.05687 (2019).\n[11] Stephen James et al.\n“Sim-to-real via sim-to-sim: Data-efficient robotic grasping via randomized-to-canonical adaptation networks”\nCVPR 2019.\n[12] Bhairav Mehta et al.\n“Active Domain Randomization”\narXiv:1904.04762\n[13] Sergey Zakharov,et al.\n“DeceptionNet: Network-Driven Domain Randomization.”\narXiv:1904.02750 (2019).\n[14] Amlan Kar, et al.\n“Meta-Sim: Learning to Generate Synthetic Datasets.”\narXiv:1904.11621 (2019).\n[15] Aayush Prakash, et al.\n“Structured Domain Randomization: Bridging the Reality Gap by Context-Aware Synthetic Data.”\narXiv:1810.10093 (2018).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:23Z",
            "title": "Domain Randomization for Sim2Real Transfer | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/4ceb83900555/code/body-000.txt",
                "chars": 247,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.06537",
                "bytes": 2845918,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6324fd866141c7ac81b8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ee4f3b9eabf9f86e46ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201.pdf",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/02a398f494ca43a2a527.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00177",
                "bytes": 4590851,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2d8f25b91674702104bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.11774",
                "bytes": 105818,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/456e2e12a35a28b26012.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.02513",
                "bytes": 4665551,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/dfcff6ef3a5e91c549e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11621",
                "bytes": 8958676,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bc0e2f30c9a21cc6e1d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.10093",
                "bytes": 6349645,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/27ba817b06ce2c0c5b10.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.05687",
                "bytes": 5492359,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5666402555506394cf09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.07252",
                "bytes": 11102844,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/26f2a2363d7689f5c25a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.07004",
                "bytes": 9323587,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/4ca4d0d250c09511b628.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.07857",
                "bytes": 6383296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/87d69e708982a5473230.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.02750",
                "bytes": 1752490,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f677145e4aa91af88479.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04762",
                "bytes": 1973875,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7ab63dc695e0b6ed4be5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": true,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907.pdf",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/18370e0f757f8e708185.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/fb94fedd3ee15e2dbb9d.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20048,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/4ceb83900555/pages/source.html",
            "local_html": "attachments/4ceb83900555/pages/article.html",
            "body_base_path": "attachments/4ceb83900555/pages/",
            "body_markdown_path": "attachments/4ceb83900555/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.06537",
                "label": "Peng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06907",
                "label": "Tobin et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.04201.pdf",
                "label": "Sadeghi et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00177",
                "label": "OpenAI, 2018",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/embed/DKe8FumoD4E",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://arxiv.org/abs/1903.11774",
                "label": "Vuong, et al, 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://ai.google/research/pubs/pub45826",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.02513",
                "label": "Ruiz (2019)",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=H1g6osRcFQ",
                "label": "Yu et al, 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11621",
                "label": "Kar, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.10093",
                "label": "Prakash et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.05687",
                "label": "Chebotar et al, 2019",
                "type": "a"
              },
              {
                "href": "https://www.aaai.org/ocs/index.php/AAAI/AAAI10/paper/viewFile/1851/2264",
                "label": "relative entropy policy search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.07252",
                "label": "James et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.07004",
                "label": "cGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.07857",
                "label": "GraspGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.02750",
                "label": "Zakharov et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04762",
                "label": "Mehta et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "SVPG",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06907.pdf",
                "label": "“Domain randomization for transferring deep neural networks from simulation to the real world.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04201",
                "label": "“CAD2RL: Real single-image flight without a single real image.”",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=HJgkx2Aqt7",
                "label": "“Learning to Simulate.”",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/learning-dexterity/",
                "label": "“Learning dexterity”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
          "status": "ok",
          "article_id": "475f6d363978",
          "local_path": "series-follow/1600/repair/878d50dab98b4b51cc5c.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
              "bytes": 176077,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/22a9e6438726d336ffe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
              "bytes": 852559,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/a036ff1cba89bd8ca177.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
              "bytes": 189886,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/18722c930cf5c497d7b4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
              "bytes": 234856,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/68fbdff3da3a7b692d3a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
              "bytes": 405820,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/41e54ee7ec562394ded4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
              "bytes": 147376,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/d6536618f786cd88a98d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
              "bytes": 82152,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/e6b375e7ba5a5bff8ba1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
              "bytes": 157138,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f21c72c925e425e2c413.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
              "bytes": 227348,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/20cc8fbcc63711039176.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
              "bytes": 307054,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/844cb0884d62492c8431.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
              "bytes": 380120,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2beee1783718ce1e1233.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
              "bytes": 136228,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/841034ba340426dcc42f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
              "bytes": 403536,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/608e700d91e7d97d213c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
              "bytes": 359761,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/740a0454d4525705f3c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
              "bytes": 100940,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/c04d9fc97a4006715831.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
              "bytes": 138999,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ebfcd764d9e484649bd7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
              "bytes": 266480,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/ea47ad327c3e525d7680.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
              "bytes": 247091,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/4bfe6aecad730ed414c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
              "bytes": 128766,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/dc1c1909a9278b076020.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
              "bytes": 352267,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f40298ff01af8fc9e4dc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
              "bytes": 127977,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/2453003154b5219dd230.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
              "bytes": 89862,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/94f6d5d4f164d466c4fb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
              "bytes": 144054,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/827f8fb6a1866bbd0478.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
              "bytes": 191620,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/f86a63f93973014347b7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
              "bytes": 582897,
              "reused": true,
              "local_path": "series-follow/1600/repair/assets/52ae3de20af990c921e3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Neural Architecture Search",
            "keywords": "NAS,架构搜索,自动ML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "publish_date": "2020-08",
            "corpus_stage": "预训练/SFT",
            "notes": "神经架构搜索综述",
            "id": "475f6d363978",
            "collected_at": "2026-10-02T14:13:15",
            "title": "Neural Architecture Search | Lil'Log",
            "body_markdown": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.\nAutomatically learning and evolving network topologies is not a new idea (\nStanley & Miikkulainen, 2002\n). In recent years, the pioneering work by\nZoph & Le 2017\nand\nBaker et al. 2017\nhas attracted a lot of attention into the field of Neural Architecture Search (NAS), leading to many interesting ideas for better, faster and more cost-efficient NAS methods.\nAs I started looking into NAS, I found this nice survey very helpful by\nElsken, et al 2019\n. They characterize NAS as a system with three major components, which is clean & concise, and also commonly adopted in other NAS papers.\nSearch space\n: The NAS search space defines a set of operations (e.g. convolution, fully-connected, pooling) and how operations can be connected to form valid network architectures. The design of search space usually involves human expertise, as well as unavoidably human biases.\nSearch algorithm\n: A NAS search algorithm samples a population of network architecture candidates. It receives the child model performance metrics as rewards (e.g. high accuracy, low latency) and optimizes to generate high-performance architecture candidates.\nEvaluation strategy\n: We need to measure, estimate, or predict the performance of a large number of proposed child models in order to obtain feedback for the search algorithm to learn. The process of candidate evaluation could be very expensive and many new methods have been proposed to save time or computation resources.\nThree main components of Neural Architecture Search (NAS) models.  (Image source:\nElsken, et al. 2019\nwith customized annotation in red)\nSearch Space\n#\nThe NAS search space defines a set of basic network operations and how operations can be connected to construct valid network architectures.\nSequential Layer-wise Operations\n#\nThe most naive way to design the search space for neural network architectures is to depict network topologies, either CNN or RNN, with a list of\nsequential layer-wise operations\n, as seen in the early work of\nZoph & Le 2017\n&\nBaker et al. 2017\n. The serialization of network representation requires a decent amount of expert knowledge, since each operation is associated with different layer-specific parameters and such associations need to be hardcoded. For example, after predicting a\nconv\nop, the model should output kernel size, stride size, etc; or after predicting an\nFC\nop, we need to see the number of units as the next prediction.\n(Top) A sequential representation of CNN. (Bottom) A sequential representation of the tree structure of a recurrent cell. (Image source:\nZoph & Le 2017\n)\nTo make sure the generated architecture is valid, additional rules might be needed (\nZoph & Le 2017\n):\nIf a layer is not connected to any input layer then it is used as the input layer;\nAt the final layer, take all layer outputs that have not been connected and concatenate them;\nIf one layer has many input layers, then all input layers are concatenated in the depth dimension;\nIf input layers to be concatenated have different sizes, we pad the small layers with zeros so that the concatenated layers have the same sizes.\nThe skip connection can be predicted as well, using an\nattention\n-style mechanism. At layer $i$ , an anchor point is added with $i−1$ content-based sigmoids to indicate which of the previous layers to be connected. Each sigmoid takes as input the hidden states of the current node $h_i$ and $i-1$ previous nodes $h_j, j=1, \\dots, i-1$ .\n$$\nP(\\text{Layer j is an input to layer i}) = \\text{sigmoid}(v^\\top \\tanh(\\mathbf{W}_\\text{prev} h_j + \\mathbf{W}_\\text{curr} h_i))\n$$\nThe sequential search space has a lot of representation power, but it is very large and consumes a ton of computation resources to exhaustively cover the search space. In the experiments by\nZoph & Le 2017\n, they were running 800 GPUs in parallel for 28 days and\nBaker et al. 2017\nrestricted the search space to contain at most 2\nFC\nlayers.\nCell-based Representation\n#\nInspired by the design of using repeated modules in successful vision model architectures (e.g. Inception, ResNet), the\nNASNet search space\n(\nZoph et al. 2018\n) defines the architecture of a conv net as the same cell getting repeated multiple times and each cell contains several operations predicted by the NAS algorithm. A well-designed cell module enables transferability between datasets. It is also easy to scale down or up the model size by adjusting the number of cell repeats.\nPrecisely, the NASNet search space learns two types of cells for network construction:\nNormal Cell\n: The input and output feature maps have the same dimension.\nReduction Cell\n: The output feature map has its width and height reduced by half.\nThe NASNet search space constrains the architecture as a repeated stack of cells. The cell architecture is optimized via NAS algorithms. (Image source:\nZoph et al. 2018\n)\nThe predictions for each cell are grouped into $B$ blocks ($B=5$ in the NASNet paper), where each block has 5 prediction steps made by 5 distinct softmax classifiers corresponding to discrete choices of the elements of a block. Note that the NASNet search space does not have residual connections between cells and the model only learns skip connections on their own within blocks.\n(a) Each cell consists of $B$ blocks and each block is predicted by 5 discrete decisions. (b) An concrete example of what operations can be chosen in each decision step.\nDuring the experiments, they discovered that a modified version of\nDropPath\n, named\nScheduledDropPath\n, significantly improves the final performance of NASNet experiments. DropPath stochastically drops out paths (i.e. edges with operations attached in NASNet) with a fixed probability. ScheduledDropPath is DropPath with a linearly increasing probability of path dropping during training time.\nElsken, et al (2019)\npoint out three major advantages of the NASNet search space:\nThe search space size is reduced drastically;\nThe\nmotif\n-based architecture can be more easily transferred to different datasets.\nIt demonstrates a strong proof of a useful design pattern of repeatedly stacking modules in architecture engineering. For example, we can build strong models by stacking residual blocks in CNN or stacking multi-headed attention blocks in Transformer.\nHierarchical Structure\n#\nTo take advantage of already discovered well-designed network\nmotifs\n, the NAS search space can be constrained as a hierarchical structure, as in\nHierarchical NAS\n(\nHNAS\n; (\nLiu et al 2017\n)). It starts with a small set of primitives, including individual operations like convolution operation, pooling, identity, etc. Then small sub-graphs (or “motifs”) that consist of primitive operations are recursively used to form higher-level computation graphs.\nA computation motif at level $\\ell=1, \\dots, L$ can be represented by $(G^{(\\ell)}, \\mathcal{O}^{(\\ell)})$, where:\n$\\mathcal{O}^{(\\ell)}$ is a set of operations, $\\mathcal{O}^{(\\ell)} = \\{ o^{(\\ell)}_1, o^{(\\ell)}_2, \\dots \\}$\n$G^{(\\ell)}$ is an adjacency matrix, where the entry $G_{ij}=k$ indicates that operation $o^{(\\ell)}_k$ is placed between node $i$ and $j$. The node indices follow\ntopological ordering\nin DAG, where the index $1$ is the source and the maximal index is the sink node.\n(Top) Three level-1 primitive operations are composed into a level-2 motif. (Bottom) Three level-2 motifs are plugged into a base network structure and assembled into a level-3 motif. (Image source:\nLiu et al 2017\n)\nTo build a network according to the hierarchical structure, we start from the lowest level $\\ell=1$ and recursively define the $m$-th motif operation at level $\\ell$ as\n$$\no^{(\\ell)}_m = \\text{assemble}\\Big( G_m^{(\\ell)}, \\mathcal{O}^{(\\ell-1)} \\Big)\n$$\nA hierarchical representation becomes $\\Big( \\big\\{ \\{ G_m^{(\\ell)} \\}_{m=1}^{M_\\ell} \\big\\}_{\\ell=2}^L, \\mathcal{O}^{(1)} \\Big), \\forall \\ell=2, \\dots, L$, where $\\mathcal{O}^{(1)}$ contains a set of primitive operations.\nThe $\\text{assemble}()$ process is equivalent to sequentially compute the feature map of node $i$ by aggregating all the feature maps of its predecessor node $j$ following the topological ordering:\n$$\nx_i = \\text{merge} \\big[ \\{ o^{(\\ell)}_{G^{(\\ell)}_{ij}}(x_j) \\}_{j < i} \\big], i = 2, \\dots, \\vert G^{(\\ell)} \\vert\n$$\nwhere $\\text{merge}[]$ is implemented as depth-wise concatenation in the\npaper\n.\nSame as NASNet, experiments in\nLiu et al (2017)\nfocused on discovering good cell architecture within a predefined “macro” structure with repeated modules. They showed that the power of simple search methods (e.g. random search or evolutionary algorithms) can be substantially enhanced using well-designed search spaces.\nCai et al (2018b)\npropose a tree-structure search space using path-level network transformation. Each node in a tree structure defines an\nallocation\nscheme for splitting inputs for child nodes and a\nmerge\nscheme for combining results from child nodes. The path-level network transformation allows replacing a single layer with a multi-branch motif if its corresponding merge scheme is add or concat.\nAn illustration of transforming a single layer to a tree-structured motif via path-level transformation operations. (Image source:\nCai et al. 2018b\n)\nMemory-bank Representation\n#\nA memory-bank representation of feed-forward networks is proposed by\nBrock et al. (2017)\nin\nSMASH\n. Instead of a graph of operations, they view a neural network as a system with multiple memory blocks which can read and write. Each layer operation is designed to: (1) read from a subset of memory blocks; (2) computes results; finally (3) write the results into another subset of blocks. For example, in a sequential model, a single memory block would get read and overwritten consistently.\nMemory-bank representation of several popular network architecture blocks. (Image source:\nBrock et al. 2017\n)\nSearch Algorithms\n#\nNAS search algorithms sample a population of child networks. It receives the child models’ performance metrics as rewards and learns to generate high-performance architecture candidates. You may a lot in common with the field of hyperparameter search.\nRandom Search\n#\nRandom search is the most naive baseline. It samples a valid architecture candidate from the search space\nat random\nand no learning model is involved. Random search has proved to be quite useful in hyperparameter search (\nBergstra & Bengio 2012\n). With a well-designed search space, random search could be a very challenging baseline to beat.\nReinforcement Learning\n#\nThe initial design of\nNAS\n(\nZoph & Le 2017\n) involves a RL-based controller for proposing child model architectures for evaluation. The controller is implemented as a RNN, outputting a variable-length sequence of tokens used for configuring a network architecture.\nA high level overview of NAS, containing a RNN controller and a pipeline for evaluating child models. (Image source:\nZoph & Le 2017\n)\nThe controller is trained as a\nRL task\nusing\nREINFORCE\n.\nAction space\n: The action space is a list of tokens for defining a child network predicted by the controller (See more in the above\nsection\n). The controller outputs\naction\n, $a_{1:T}$, where $T$ is the total number of tokens.\nReward\n: The accuracy of a child network that can be achieved at convergence is the reward for training the controller, $R$.\nLoss\n: NAS optimizes the controller parameters $\\theta$ with a REINFORCE loss. We want to maximize the expected reward (high accuracy) with the gradient as follows. The nice thing here with policy gradient is that it works even when the reward is non-differentiable.\n$$\n\\nabla_{\\theta} J(\\theta) = \\sum_{t=1}^T \\mathbb{E}[\\nabla_{\\theta} \\log P(a_t \\vert a_{1:(t-1)}; \\theta) R ]\n$$\nMetaQNN\n(\nBaker et al. 2017\n) trains an agent to sequentially choose CNN layers using\nQ-learning\nwith an\n$\\epsilon$-greedy\nexploration strategy and experience replay. The reward is the validation accuracy as well.\n$$\nQ^{(t+1)}(s_t,  a_t) = (1 - \\alpha)Q^{(t)}(s_t, a_t) + \\alpha (R_t + \\gamma \\max_{a \\in \\mathcal{A}} Q^{(t)}(s_{t+1},  a'))\n$$\nwhere a state $s_t$ is a tuple of layer operation and related parameters. An action $a$ determines the connectivity between operations. The Q-value is proportional to how confident we are in two connected operations leading to high accuracy.\nOverview of MetaQNN - designing CNN models with Q-Learning. (Image source:\nBaker et al. 2017\n)\nEvolutionary Algorithms\n#\nNEAT\n(short for\nNeuroEvolution of Augmenting Topologies\n) is an approach for evolving neural network topologies with\ngenetic algorithm (GA)\n, proposed by\nStanley & Miikkulainen\nin 2002. NEAT evolves both connection weights and network topology together. Each gene encodes the full information for configuring a network, including node weights and edges. The population grows by applying mutation of both weights and connections, as well as crossover between two parent genes. For more in neuroevolution, please refer to the in-depth\nsurvey\nby Stanley et al. (2019).\nMutations in the NEAT algorithm. (Image source: Fig 3 & 4 in\nStanley & Miikkulainen, 2002\n)\nReal et al. (2018)\nadopt the evolutionary algorithms (EA) as a way to search for high-performance network architectures, named\nAmoebaNet\n. They apply the\ntournament selection\nmethod, which at each iteration picks a best candidate out of a random set of samples and places its mutated offspring back into the population. When the tournament size is $1$, it is equivalent to random selection.\nAmoebaNet modified the tournament selection to favor\nyounger\ngenotypes and always discard the oldest models within each cycle. Such an approach, named\naging evolution\n, allows AmoebaNet to cover and explore more search space, rather than to narrow down on good performance models too early.\nPrecisely, in every cycle of the tournament selection with aging regularization (See Figure 11):\nSample $S$ models from the population and the one with highest accuracy is chosen as\nparent\n.\nA\nchild\nmodel is produced by mutating\nparent\n.\nThen the child model is trained, evaluated and added back into the population.\nThe oldest model is removed from the population.\nThe algorithm of aging evolution. (Image source:\nReal et al. 2018\n)\nTwo types of mutations are applied:\nHidden state mutation\n: randomly chooses a pairwise combination and rewires a random end such that there is no loop in the graph.\nOperation mutation\n: randomly replaces an existing operation with a random one.\nTwo types of mutations in AmoebaNet. (Image source:\nReal et al. 2018\n)\nIn their experiments, EA and RL work equally well in terms of the final validation accuracy, but EA has better anytime performance and is able to find smaller models. Here using EA in NAS is still expensive in terms of computation, as each experiment took 7 days with 450 GPUs.\nHNAS\n(\nLiu et al 2017\n) also employs the evolutionary algorithms (the original tournament selection) as their search strategy. In the\nhierarchical structure\nsearch space, each edge is an operation. Thus genotype mutation in their experiments is applied by replacing a random edge with a different operation. The replacement set includes an\nnone\nop, so it can alter, remove and add an edge. The initial set of genotypes is created by applying a large number of random mutations on “trivial” motifs (all identity mappings).\nProgressive Decision Process\n#\nConstructing a model architecture is a sequential process. Every additional operator or layer brings extra complexity. If we guide the search model to start the investigation from simple models and gradually evolve to more complex architectures, it is like to introduce\n“curriculum”\ninto the search model’s learning process.\nProgressive NAS\n(\nPNAS\n;\nLiu, et al 2018\n) frames the problem of NAS as a progressive procedure for searching models of increasing complexity. Instead of RL or EA, PNAS adopts a Sequential Model-based Bayesian Optimization (SMBO) as the search strategy. PNAS works similar to A* search, as it searches for models from simple to hard while simultaneously learning a surrogate function to guide the search.\nA* search algorithm\n(“best-first search”) is a popular algorithm for path finding. The problem is framed as finding a path of smallest cost from a specific starting node to a given target node in a weighted graph. At each iteration, A* finds a path to extend by minimizing: $f(n)=g(n)+h(n)$, where $n$ is the next node, $g(n)$ is the cost from start to $n$, and $h(n)$ is the heuristic function that estimates the minimum cost of going from node $n$ to the goal.\nPNAS uses the\nNASNet\nsearch space. Each block is specified as a 5-element tuple and PNAS only considers the element-wise addition as the step 5 combination operator, no concatenation. Differently, instead of setting the number of blocks $B$ at a fixed number, PNAS starts with $B=1$, a model with only one block in a cell, and gradually increases $B$.\nThe performance on a validation set is used as feedback to train a\nsurrogate\nmodel for\npredicting\nthe performance of novel architectures. With this predictor, we can thus decide which models should be prioritized to be evaluated next. Since the performance predictor should be able to handle various-sized inputs, accuracy, and sample-efficient, they ended up using an RNN model.\nThe algorithm of Progressive NAS. (Image source:\nLiu, et al 2018\n)\nGradient descent\n#\nUsing gradient descent to update the architecture search model requires an effort to make the process of choosing discrete operations differentiable. These approaches usually combine the learning of both architecture parameters and network weights together into one model. See more in the\nsection\non the\n“one-shot”\napproach.\nEvaluation Strategy\n#\nWe need to measure, estimate or predict the performance of every child model in order to obtain feedback for optimizing the search algorithm. The process of candidate evaluation could be very expensive and many new evaluation methods have been proposed to save time or computation. When evaluating a child model, we mostly care about its performance measured as accuracy on a validation set. Recent work has started looking into other factors of a model, such as model size and latency, as certain devices may have limitations on memory or demand fast response time.\nTraining from Scratch\n#\nThe most naive approach is to train every child network independently from scratch until\nconvergence\nand then measure its accuracy on a validation set (\nZoph & Le 2017\n). It provides solid performance numbers, but one complete train-converge-evaluate loop only generates a single data sample for training the RL controller (let alone RL is known to be sample-inefficient in general). Thus it is very expensive in terms of computation consumption.\nProxy Task Performance\n#\nThere are several approaches for using a proxy task performance as the performance estimator of a child network, which is generally cheaper and faster to calculate:\nTrain on a smaller dataset.\nTrain for fewer epochs.\nTrain and evaluate a down-scaled model in the search stage. For example, once a cell structure is learned, we can play with the number of cell repeats or scale up the number of filters (\nZoph et al. 2018\n).\nPredict the learning curve.\nBaker et al (2018)\nmodel the prediction of validation accuracies as a time-series regression problem. The features for the regression model ($\\nu$-support vector machine regressions; $\\nu$-SVR) include the early sequences of accuracy per epoch, architecture parameters, and hyperparameters.\nParameter Sharing\n#\nInstead of training every child model independently from scratch. You may ask, ok, what if we fabricate dependency between them and find a way to reuse weights? Some researchers succeeded to make such approaches work.\nInspired by\nNet2net\ntransformation,\nCai et al (2017)\nproposed\nEfficient Architecture Search\n(\nEAS\n). EAS sets up an RL agent, known as a meta-controller, to predict function-preserving network transformation so as to grow the network depth or layer width. Because the network is growing incrementally, the weights of previously validated networks can be\nreused\nfor further exploration. With inherited weights, newly constructed networks only need some light-weighted training.\nA meta-controller learns to generate\nnetwork transformation actions\ngiven the current network architecture, which is specified with a variable-length string. In order to handle architecture configuration of a variable length, the meta-controller is implemented as a bi-directional recurrent network. Multiple actor networks output different transformation decisions:\nNet2WiderNet\noperation allows to replace a layer with a wider layer, meaning more units for fully-connected layers, or more filters for convolutional layers, while preserving the functionality.\nNet2DeeperNet\noperation allows to insert a new layer that is initialized as adding an identity mapping between two layers so as to preserve the functionality.\nOverview of the RL based meta-controller in Efficient Architecture Search (NAS). After encoding the architecture configuration, it outputs net2net transformation actions through two separate actor networks. (Image source:\nCai et al 2017\n)\nWith similar motivation,\nEfficient NAS\n(\nENAS\n;\nPham et al. 2018\n) speeds up NAS (i.e. 1000x less) by aggressively sharing parameters among child models. The core motivation behind ENAS is the observation that all of the sampled architecture graphs can be viewed as\nsub-graphs\nof a larger\nsupergraph\n. All the child networks are sharing weights of this supergraph.\n(Left) The graph represents the entire search space for a 4-node recurrent cell, but only connections in red are active. (Middle) An example of how the left active sub-graph can be translated into a child model architecture. (Right) The network parameters produced by an RNN controller for the architecture in the middle. (Image source:\nPham et al. 2018\n)\nENAS alternates between training the shared model weights $\\omega$ and training the controller $\\theta$:\nThe parameters of the controller LSTM $\\theta$ are trained with\nREINFORCE\n, where the reward $R(\\mathbf{m}, \\omega)$ is computed on the validation set.\nThe shared parameters of the child models $\\omega$ are trained with standard supervised learning loss. Note that different operators associated with the same node in the supergraph would have their own distinct parameters.\nPrediction-Based\n#\nA routine child model evaluation loop is to update model weights via standard gradient descent. SMASH (\nBrock et al. 2017\n) proposes a different and interesting idea:\nCan we predict the model weights directly based on the network architecture parameters?\nThey employ a\nHyperNet\n(\nHa et al 2016\n) to directly generate the weights of a model conditioned on an encoding of its architecture configuration. Then the model with HyperNet-generated weights is validated directly. Note that we don’t need extra training for every child model but we do need to train the HyperNet.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nThe correlation between model performance with SMASH-generated weights and true validation errors suggests that predicted weights can be used for model comparison, to some extent. We do need a HyperNet of large enough capacity, as the correlation would be corrupted if the HyperNet model is too small compared to the child model size.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nSMASH can be viewed as another way to implement the idea of\nparameter sharing\n. One problem of SMASH as pointed out by\nPham et al. (2018)\nis: The usage of HyperNet restricts the weights of SMASH child models to a\nlow-rank space\n, because weights are generated via tensor products. In comparison,\nENAS\nhas no such restrictions.\nOne-Shot Approach: Search + Evaluation\n#\nRunning search & evaluation independently for a large population of child models is expensive. We have seen promising approaches like\nBrock et al. (2017)\nor\nPham et al. (2018)\n, where training a single model is enough for emulating any child model in the search space.\nThe\none-shot\narchitecture search extends the idea of weight sharing and further combines the learning of architecture generation together with weight parameters. The following approaches all treat child architectures as different sub-graphs of a supergraph with shared weights between common edges in the supergraph.\nBender et al (2018)\nconstruct a single large over-parameterized network, known as the\nOne-Shot model\n, such that it contains every possible operation in the search space. With\nScheduledDropPath\n(the dropout rate is increased over time, which is $r^{1/k}$ at the end of training, where $0 < r < 1$ is a hyperparam and $k$ is the number of incoming paths) and some carefully designed tricks (e.g. ghost batch normalization, L2 regularization only on the active architecture), the training of such a giant model can be stabilized enough and used for evaluating any child model sampled from the supergraph.\nThe architecture of the One-Shot model in\nBender et al 2018\n. Each cell has $N$ choice blocks and each choice block can select up to 2 operations. Solid edges are used in every architecture, where dash lines are optional. (Image source:\nBender et al 2018\n)\nOnce the one-shot model is trained, it is used for evaluating the performance of many different architectures sampled at random by zeroing out or removing some operations. This sampling process can be replaced by RL or evolution.\nThey observed that the difference between the accuracy measured with the one-shot model and the accuracy of the same architecture after a small fine-tuning could be very large. Their hypothesis is that the one-shot model automatically learns to focus on the\nmost useful\noperations in the network and comes to\nrely on\nthese operations when they are available. Thus zeroing out useful operations lead to big reduction in model accuracy, while removing less important components only causes a small impact — Therefore, we see a larger variance in scores when using the one-shot model for evaluation.\nA stratified sample of models with different one-shot model accuracy versus their true validation accuracy as stand-alone models. (Image source:\nBender et al 2018\n)\nClearly designing such a search graph is not a trivial task, but it demonstrates a strong potential with the one-shot approach. It works well with only gradient descent and no additional algorithm like RL or EA is a must.\nSome believe that one main cause for inefficiency in NAS is to treat the architecture search as a\nblack-box optimization\nand thus we fall into methods like RL, evolution, SMBO, etc. If we shift to rely on standard gradient descent, we could potentially make the search process more effectively. As a result,\nLiu et al (2019)\npropose\nDifferentiable Architecture Search\n(\nDARTS\n). DARTS introduces a continuous relaxation on each path in the search supergraph, making it possible to jointly train architecture parameters and weights via gradient descent.\nLet’s use the directed acyclic graph (DAG) representation here. A cell is a DAG consisting of a topologically ordered sequence of $N$ nodes. Each node has a latent representation $x_i$ to be learned. Each edge $(i, j)$ is tied to some operation $o^{(i,j)} \\in \\mathcal{O}$ that transforms $x_j$ to compose $x_i$:\n$$\nx_i = \\sum_{j < i} o^{(i,j)}(x_j)\n$$\nTo make the search space continuous, DARTS relaxes the categorical choice of a particular operation as a softmax over all the operations and the task of architecture search is reduced to learn a set of mixing probabilities $\\alpha = \\{ \\alpha^{(i,j)} \\}$.\n$$\n\\bar{o}^{(i,j)}(x) = \\sum_{o\\in\\mathcal{O}} \\frac{\\exp(\\alpha_{ij}^o)}{\\sum_{o'\\in\\mathcal{O}} \\exp(\\alpha^{o'}_{ij})} o(x)\n$$\nwhere $\\alpha_{ij}$ is a vector of dimension $\\vert \\mathcal{O} \\vert$, containing weights between nodes $i$ and $j$ over different operations.\nThe bilevel optimization exists as we want to optimize both the network weights $w$ and the architecture representation $\\alpha$:\n$$\n\\begin{aligned}\n\\min_\\alpha & \\mathcal{L}_\\text{validate} (w^*(\\alpha), \\alpha) \\\\\n\\text{s.t.} & w^*(\\alpha) = \\arg\\min_w \\mathcal{L}_\\text{train} (w, \\alpha)\n\\end{aligned}\n$$\nAt step $k$, given the current architecture parameters $\\alpha_{k−1}$, we first optimize weights $w_k$ by moving $w_{k−1}$ in the direction of minimizing the training loss $\\mathcal{L}_\\text{train}(w_{k−1}, \\alpha_{k−1})$ with a learning rate $\\xi$. Next, while keeping the newly updated weights $w_k$ fixed, we update the mixing probabilities so as to minimize the validation loss\nafter a single step of gradient descent w.r.t. the weights\n:\n$$\nJ_\\alpha = \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1})\n$$\nThe motivation here is that we want to find an architecture with a low validation loss when its weights are optimized by gradient descent and the one-step unrolled weights serve as the\nsurrogate\nfor $w^∗(\\alpha)$.\nSide note: Earlier we have seen similar formulation in\nMAML\nwhere the two-step optimization happens between task losses and the meta-learner update, as well as framing\nDomain Randomization\nas a bilevel optimization for better transfer in the real environment.\nAn illustration of how DARTS applies continuous relaxation on edges in DAG supergraph and identifies the final model. (Image source:\nLiu et al 2019\n)\n$$\n\\begin{aligned}\n\\text{Let }w'_k &= w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}) & \\\\\nJ_\\alpha &= \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1}) = \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) & \\\\\n\\nabla_\\alpha J_\\alpha \n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\nabla_\\alpha \\alpha_{k-1} + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1})\\nabla_\\alpha w'_k & \\\\& \\text{; multivariable chain rule}\\\\\n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\big( - \\xi \\color{red}{\\nabla^2_{\\alpha, w} \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1})} \\big) & \\\\\n&\\approx \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) - \\xi \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\color{red}{\\frac{\\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^+, \\alpha_{k-1}) - \\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^-, \\alpha_{k-1}) }{2\\epsilon}} & \\\\\n& \\text{; apply numerical differentiation approximation}\n\\end{aligned}\n$$\nwhere the red part is using numerical differentiation approximation where $w_k^+ = w_k + \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$ and $w_k^- = w_k - \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$.\nThe algorithm overview of DARTS. (Image source:\nLiu et al 2019\n)\nAs another idea similar to DARTS, Stochastic NAS (\nXie et al., 2019\n) applies a continuous relaxation by employing the concrete distribution (CONCRETE = CONtinuous relaxations of disCRETE random variables;\nMaddison et al 2017\n) and reparametrization tricks. The goal is same as DARTS, to make the discrete distribution differentiable and thus enable optimization by gradient descent.\nDARTS is able to greatly reduce the cost of GPU hours. Their experiments for searching for CNN cells have $N=7$ and only took 1.5 days with a single GPU. However, it suffers from the high GPU memory consumption issue due to its continuous representation of network architecture. In order to fit the model into the memory of a single GPU, they picked a small $N$.\nTo constrain the GPU memory consumption,\nProxylessNAS\n(\nCai et al., 2019\n) views NAS as a path-level pruning process in DAG and binarizes the architecture parameters to force only one path to be active between two nodes at a time. The probabilities for an edge being either masked out or not are then learned by sampling a few binarized architectures and using\nBinaryConnect\n(\nCourbariaux et al., 2015\n) to update the corresponding probabilities. ProxylessNAS demonstrates a strong connection between NAS and model compression. By using path-level compression, it is able to save memory consumption by one order of magnitude.\nLet’s continue with the graph representation. In a DAG adjacency matrix $G$ where $G_{ij}$ represents an edge between node $i$ and $j$ and its value can be chosen from the set of $\\vert \\mathcal{O} \\vert$ candidate primitive operations, $\\mathcal{O} = \\{ o_1, \\dots \\}$. The One-Shot model, DARTS and ProxylessNAS all consider each edge as a mixture of operations, $m_\\mathcal{O}$, but with different tweaks.\nIn One-Shot, $m_\\mathcal{O}(x)$ is the sum of all the operations. In DARTS, it is a weighted sum where weights are softmax over a real-valued architecture weighting vector $\\alpha$ of length $\\vert \\mathcal{O} \\vert$. ProxylessNAS transforms the softmax probabilities of $\\alpha$ into a binary gate and uses the binary gate to keep only one operation active at a time.\n$$\n\\begin{aligned}\nm^\\text{one-shot}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} o_i(x) \\\\\nm^\\text{DARTS}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} p_i o_i(x) = \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\exp(\\alpha_i)}{\\sum_j \\exp(\\alpha_j)} o_i(x) \\\\\nm^\\text{binary}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} g_i o_i(x) = \\begin{cases}\no_1(x) & \\text{with probability }p_1, \\\\\n\\dots &\\\\\no_{\\vert \\mathcal{O} \\vert}(x) & \\text{with probability }p_{\\vert \\mathcal{O} \\vert}\n\\end{cases} \\\\\n\\text{ where } g &= \\text{binarize}(p_1, \\dots, p_N) = \\begin{cases}\n[1, 0, \\dots, 0] & \\text{with probability }p_1, \\\\\n\\dots & \\\\\n[0, 0, \\dots, 1] & \\text{with probability }p_N. \\\\\n\\end{cases}\n\\end{aligned}\n$$\nProxylessNAS has two training steps running alternatively. (Image source:\nCai et al., 2019\n)\nProxylessNAS runs two training steps alternatively:\nWhen training weight parameters $w$, it freezes the architecture parameters $\\alpha$ and stochastically samples binary gates $g$ according to the above $m^\\text{binary}_\\mathcal{O}(x)$. The weight parameters can be updated with standard gradient descent.\nWhen training architecture parameters $\\alpha$, it freezes $w$, resets the binary gates and then updates $\\alpha$ on the validation set. Following the idea of\nBinaryConnect\n,  the gradient w.r.t. architecture parameters can be approximately estimated using $\\partial \\mathcal{L} / \\partial g_i$ in replacement for $\\partial \\mathcal{L} / \\partial p_i$:\n$$\n\\begin{aligned}\n\\frac{\\partial \\mathcal{L}}{\\partial \\alpha_i} \n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial p_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n\\approx \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial \\frac{e^{\\alpha_j}}{\\sum_k e^{\\alpha_k}}}{\\partial \\alpha_i} \\\\\n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\sum_k e^{\\alpha_k} (\\mathbf{1}_{i=j} e^{\\alpha_j}) - e^{\\alpha_j} e^{\\alpha_i} }{(\\sum_k e^{\\alpha_k})^2}\n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} p_j (\\mathbf{1}_{i=j} -p_i)\n\\end{aligned}\n$$\nInstead of BinaryConnect, REINFORCE can also be used for parameter updates with the goal for maximizing the reward, while no RNN meta-controller is involved.\nComputing $\\partial \\mathcal{L} / \\partial g_i$ needs to calculate and store $o_i(x)$, which requires $\\vert \\mathcal{O} \\vert$ times GPU memory. To resolve this issue, they factorize the task of choosing one path out of $N$ into multiple binary selection tasks (Intuition: “if a path is the best choice, it should be better than any other path”). At every update step, only two paths are sampled while others are masked. These two selected paths are updated according to the above equation and then scaled properly so that other path weights are unchanged. After this process, one of the sampled paths is enhanced (path weight increases) and the other is attenuated (path weight decreases), while all other paths stay unaltered.\nBesides accuracy, ProxylessNAS also considers\nlatency\nas an important metric to optimize, as different devices might have very different requirements on inference time latency (e.g. GPU, CPU, mobile). To make latency differentiable, they model latency as a continuous function of the network dimensions. The expected latency of a mixed operation can be written as $\\mathbb{E}[\\text{latency}] = \\sum_j p_j F(o_j)$, where $F(.)$ is a latency prediction model:\nAdd a differentiable latency loss into the training of ProxylessNAS.  (Image source:\nCai et al., 2019\n)\nWhat’s the Future?\n#\nSo far we have seen many interesting new ideas on automating the network architecture engineering through neural architecture search and many have achieved very impressive performance. However, it is a bit hard to do inference on\nwhy\nsome architecture work well and how we can develop modules generalizable across tasks rather than being very dataset-specific.\nAs also noted in\nElsken, et al (2019)\n:\n“…, so far it provides little insights into why specific architectures work well and how similar the architectures derived in independent runs would be. Identifying common motifs, providing an understanding why those motifs are important for high performance, and investigating if these motifs generalize over different problems would be desirable.”\nIn the meantime, purely focusing on improvement over validation accuracy might not be enough (\nCai et al., 2019\n). Devices like mobile phones for daily usage in general have limited memory and computation power. While AI applications are on the way to affect our daily life, it is unavoidable to be more\ndevice-specific\n.\nAnother interesting investigation is to consider\nunlabelled dataset\nand\nself-supervised learning\nfor NAS. The size of labelled dataset is always limited and it is not easy to tell whether such a dataset has biases or big deviation from the real world data distribution.\nLiu et al (2020)\ndelve into the question\n“Can we find high-quality neural architecture without human-annotated labels?”\nand proposed a new setup called\nUnsupervised Neural Architecture Search\n(\nUnNAS\n). The quality of the architecture needs to be estimated in an unsupervised fashion during the search phase. The paper experimented with three unsupervised\npretext tasks\n: image rotation prediction, colorization, and solving the jigsaw puzzle.\nThey observed in a set of UnNAS experiments that:\nHigh rank correlation between supervised accuracy and pretext accuracy\non the same dataset\n. Typically the rank correlation is higher than 0.8, regardless of the dataset, the search space, and the pretext task.\nHigh rank correlation between supervised accuracy and pretext accuracy\nacross datasets\n.\nBetter pretext accuracy translates to better supervised accuracy.\nPerformance of UnNAS architecture is comparable to supervised counterparts, though not better yet.\nOne hypothesis is that the architecture quality is correlated with image statistics. Because CIFAR-10 and ImageNet are all on the natural images, they are comparable and the results are transferable. UnNAS could potentially enable a much larger amount of unlabelled data into the search phase which captures image statistics better.\nHyperparameter search is a long-standing topic in the ML community. And NAS automates architecture engineering. Gradually we are trying to automate processes in ML which usually demand a lot of human efforts. Taking even one more step further, is it possible to automatically discover ML algorithms?\nAutoML-Zero\n(\nReal et al 2020\n) investigates this idea. Using\naging evolutionary algorithms\n, AutoML-Zero automatically searches for whole ML algorithms using little restriction on the form with only simple mathematical operations as building blocks.\nIt learns three component functions. Each function only adopts very basic operations.\nSetup\n: initialize memory variables (weights).\nLearn\n: modify memory variables\nPredict\n: make a prediction from an input $x$.\nAlgorithm evaluation on one task (Image source:\nReal et al 2020\n)\nThree types of operations are considered when mutating a parent genotype:\nInsert a random instruction or remove an instruction at a random location in a component function;\nRandomize all the instructions in a component function;\nModify one of the arguments of an instruction by replacing it with a random choice (e.g. “swap the output address” or “change the value of a constant”)\nAn illustration of evolutionary progress on projected binary CIFAR-10 with example code. (Image source:\nReal et al 2020\n)\nAppendix: Summary of NAS Papers\n#\nModel name\nSearch space\nSearch algorithms\nChild model evaluation\nNEAT (2002)\n-\nEvolution (Genetic algorithm)\n-\nNAS (2017)\nSequential layer-wise ops\nRL (REINFORCE)\nTrain from scratch until convergence\nMetaQNN (2017)\nSequential layer-wise ops\nRL (Q-learning with $\\epsilon$-greedy)\nTrain for 20 epochs\nHNAS (2017)\nHierarchical structure\nEvolution (Tournament selection)\nTrain for a fixed number of iterations\nNASNet (2018)\nCell-based\nRL (PPO)\nTrain for 20 epochs\nAmoebaNet (2018)\nNASNet search space\nEvolution (Tournament selection with aging regularization)\nTrain for 25 epochs\nEAS (2018a)\nNetwork transformation\nRL (REINFORCE)\n2-stage training\nPNAS (2018)\nReduced version of NASNet search space\nSMBO; Progressive search for architectures of increasing complexity\nTrain for 20 epochs\nENAS (2018)\nBoth sequential and cell-based search space\nRL (REINFORCE)\nTrain one model with shared weights\nSMASH (2017)\nMemory-bank representation\nRandom search\nHyperNet predicts weights of evaluated architectures.\nOne-Shot (2018)\nAn over-parameterized one-shot model\nRandom search (zero out some paths at random)\nTrain the one-shot model\nDARTS (2019)\nNASNet search space\nGradient descent (Softmax weights over operations)\nProxylessNAS (2019)\nTree structure architecture\nGradient descent (BinaryConnect) or REINFORCE\nSNAS (2019)\nNASNet search space\nGradient descent (concrete distribution)\nCitation\n#\nCited as:\nWeng, Lilian. (Aug 2020). Neural architecture search. Lil’Log. https://lilianweng.github.io/posts/2020-08-06-nas/.\nOr\n@article{weng2020nas,\n  title   = \"Neural Architecture Search\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Aug\",\n  url     = \"https://lilianweng.github.io/posts/2020-08-06-nas/\"\n}\nReference\n#\n[1] Thomas Elsken, Jan Hendrik Metzen, Frank Hutter.\n“Neural Architecture Search: A Survey”\nJMLR 20 (2019) 1-21.\n[2] Kenneth O. Stanley, et al.\n“Designing neural networks through neuroevolution”\nNature Machine Intelligence volume 1, pages 24–35 (2019).\n[3] Kenneth O. Stanley & Risto Miikkulainen.\n“Evolving Neural Networks through Augmenting Topologies”\nEvolutionary Computation 10(2): 99-127 (2002).\n[4] Barret Zoph, Quoc V. Le.\n“Neural architecture search with reinforcement learning”\nICLR 2017.\n[5] Bowen Baker, et al.\n“Designing Neural Network Architectures using Reinforcement Learning”\nICLR 2017.\n[6] Bowen Baker, et al.\n“Accelerating neural architecture search using performance prediction”\nICLR Workshop 2018.\n[7] Barret Zoph, et al.\n“Learning transferable architectures for scalable image recognition”\nCVPR 2018.\n[8] Hanxiao Liu, et al.\n“Hierarchical representations for efficient architecture search.”\nICLR 2018.\n[9] Esteban Real, et al.\n“Regularized Evolution for Image Classifier Architecture Search”\narXiv:1802.01548 (2018).\n[10] Han Cai, et al. [“Efficient architecture search by network transformation”] AAAI 2018a.\n[11] Han Cai, et al.\n“Path-Level Network Transformation for Efficient Architecture Search”\nICML 2018b.\n[12] Han Cai, Ligeng Zhu & Song Han.\n“ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware”\nICLR 2019.\n[13] Chenxi Liu, et al.\n“Progressive neural architecture search”\nECCV 2018.\n[14] Hieu Pham, et al.\n“Efficient neural architecture search via parameter sharing”\nICML 2018.\n[15] Andrew Brock, et al.\n“SMASH: One-shot model architecture search through hypernetworks.”\nICLR 2018.\n[16] Gabriel Bender, et al.\n“Understanding and simplifying one-shot architecture search.”\nICML 2018.\n[17] Hanxiao Liu, Karen Simonyan, Yiming Yang.\n“DARTS: Differentiable Architecture Search”\nICLR 2019.\n[18] Sirui Xie, Hehui Zheng, Chunxiao Liu, Liang Lin.\n“SNAS: Stochastic Neural Architecture Search”\nICLR 2019.\n[19] Chenxi Liu et al.\n“Are Labels Necessary for Neural Architecture Search?”\nECCV 2020.\n[20] Esteban Real, et al.\n“AutoML-Zero: Evolving Machine Learning Algorithms From Scratch”\nICML 2020.",
            "metadata": {
              "title": "Neural Architecture Search | Lil'Log",
              "description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "keywords": "architecture, reinforcement-learning, evolution, auto-ML",
              "author": "Lilian Weng",
              "og:title": "Neural Architecture Search",
              "og:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
              "twitter:card": "summary",
              "twitter:title": "Neural Architecture Search",
              "twitter:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "article:section": "posts",
              "article:published_time": "2020-08-06T00:00:00+00:00",
              "article:modified_time": "2020-08-06T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/475f6d363978/code/body-000.txt",
                "chars": 234,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "bytes": 176077,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-22a9e6438726d336ffe1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "bytes": 852559,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-a036ff1cba89bd8ca177.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "bytes": 189886,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-18722c930cf5c497d7b4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "bytes": 234856,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-68fbdff3da3a7b692d3a.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "bytes": 405820,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-41e54ee7ec562394ded4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "bytes": 147376,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-d6536618f786cd88a98d.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "bytes": 82152,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-e6b375e7ba5a5bff8ba1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "bytes": 157138,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f21c72c925e425e2c413.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "bytes": 227348,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-20cc8fbcc63711039176.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "bytes": 307054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-844cb0884d62492c8431.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "bytes": 380120,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2beee1783718ce1e1233.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "bytes": 136228,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-841034ba340426dcc42f.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "bytes": 403536,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-608e700d91e7d97d213c.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "bytes": 359761,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-740a0454d4525705f3c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "bytes": 100940,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-c04d9fc97a4006715831.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "bytes": 138999,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ebfcd764d9e484649bd7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "bytes": 266480,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ea47ad327c3e525d7680.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "bytes": 247091,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-4bfe6aecad730ed414c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "bytes": 128766,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-dc1c1909a9278b076020.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "bytes": 352267,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f40298ff01af8fc9e4dc.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "bytes": 127977,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2453003154b5219dd230.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "bytes": 89862,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-94f6d5d4f164d466c4fb.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "bytes": 144054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-827f8fb6a1866bbd0478.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "bytes": 191620,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f86a63f93973014347b7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "bytes": 582897,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-52ae3de20af990c921e3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "label": "Stanley & Miikkulainen, 2002",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.01578",
                "label": "Zoph & Le 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02167",
                "label": "Baker et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.05377",
                "label": "Elsken, et al 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.07012",
                "label": "Zoph et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.07648",
                "label": "DropPath",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Network_motif",
                "label": "motif",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00436",
                "label": "Liu et al 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Topological_sorting",
                "label": "topological ordering",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.02639",
                "label": "Cai et al (2018b)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.05344",
                "label": "Brock et al. (2017)",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "label": "Bergstra & Bengio 2012",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Q-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$\\epsilon$-greedy",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Genetic_algorithm",
                "label": "genetic algorithm (GA)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/s42256-018-0006-z",
                "label": "survey",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01548",
                "label": "Real et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tournament_selection",
                "label": "tournament selection",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
                "label": "“curriculum”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.00559",
                "label": "Liu, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/A*_search_algorithm",
                "label": "A* search algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.10823",
                "label": "Baker et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05641",
                "label": "Net2net",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04873",
                "label": "Cai et al (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03268",
                "label": "Pham et al. 2018",
                "type": "a"
              },
              {
                "href": "https://blog.otoro.net/2016/09/28/hyper-networks/",
                "label": "HyperNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.09106",
                "label": "Ha et al 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "label": "Bender et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09055",
                "label": "Liu et al (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "Domain Randomization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.09926",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.00712",
                "label": "Maddison et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.00332",
                "label": "Cai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.00363",
                "label": "Courbariaux et al., 2015",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.12056",
                "label": "Liu et al (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.03384",
                "label": "Real et al 2020",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a.html",
                "label": "One-Shot (2018)",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:31Z",
            "source_url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "papers": [
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "bytes": 455683,
                "reused": false,
                "local_path": "papers/repair/805499a4b371ca736e62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01578",
                "bytes": 733204,
                "reused": false,
                "local_path": "papers/repair/a111656177a4c8876b48.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02167",
                "bytes": 2766423,
                "reused": false,
                "local_path": "papers/repair/760094c3d304751da217.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.05377",
                "bytes": 513920,
                "reused": false,
                "local_path": "papers/repair/97142d15c75389ec1783.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.07012",
                "bytes": 8223935,
                "reused": false,
                "local_path": "papers/repair/263d4aa0ef18300727e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.07648",
                "bytes": 301203,
                "reused": false,
                "local_path": "papers/repair/3c2d2df24de01e01fbd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00436",
                "bytes": 625718,
                "reused": false,
                "local_path": "papers/repair/eb6cf4cb96b16ab6e4ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.02639",
                "bytes": 4382572,
                "reused": false,
                "local_path": "papers/repair/680796c56d03bb0724c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05344",
                "bytes": 3204919,
                "reused": false,
                "local_path": "papers/repair/e88c3d4c693981e49fce.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "bytes": 728274,
                "reused": false,
                "local_path": "papers/repair/8a459dcd765c190d80b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01548",
                "bytes": 719617,
                "reused": false,
                "local_path": "papers/repair/65805c891aedf369ff37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.00559",
                "bytes": 1201540,
                "reused": false,
                "local_path": "papers/repair/609e6dc18e9ec4f12c8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.10823",
                "bytes": 696064,
                "reused": false,
                "local_path": "papers/repair/0fe98a08286c39292e71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05641",
                "bytes": 514031,
                "reused": false,
                "local_path": "papers/repair/92e6dc487fb58180dcc6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04873",
                "bytes": 1963936,
                "reused": false,
                "local_path": "papers/repair/ed8c0c59198f186976bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03268",
                "bytes": 437408,
                "reused": false,
                "local_path": "papers/repair/385bdb4f3e6008bec0cf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.09106",
                "bytes": 3125291,
                "reused": false,
                "local_path": "papers/repair/9a50e3e16a9ac5be3fd1.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "bytes": 608254,
                "reused": false,
                "local_path": "papers/repair/3a859646e6c029ea003e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09055",
                "bytes": 636787,
                "reused": false,
                "local_path": "papers/repair/40e69415044afc05d599.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.09926",
                "bytes": 711882,
                "reused": false,
                "local_path": "papers/repair/35befec5995034ad4bfd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.00712",
                "bytes": 858710,
                "reused": false,
                "local_path": "papers/repair/27fa0ebf79e9f6aa3132.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.00332",
                "bytes": 2325253,
                "reused": false,
                "local_path": "papers/repair/61f9a157fe986680a3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.00363",
                "bytes": 1297364,
                "reused": false,
                "local_path": "papers/repair/1bc5305341828713b8ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.12056",
                "bytes": 1315976,
                "reused": false,
                "local_path": "papers/repair/05573f22fe71d2abefb7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.03384",
                "bytes": 1781766,
                "reused": false,
                "local_path": "papers/repair/daabc7af10551ec97ee1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 44902,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/475f6d363978/pages/source.html",
            "local_html": "attachments/475f6d363978/pages/article.html",
            "body_base_path": "attachments/475f6d363978/pages/",
            "body_markdown_path": "attachments/475f6d363978/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
          "status": "ok",
          "article_id": "95e296d541c5",
          "local_path": "series-follow/1600/repair/0131ab3df6b3801717f6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
              "bytes": 378234,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/42322906964d7eff1651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
              "bytes": 283407,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f9b6ebe483799e46cae4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
              "bytes": 228747,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/0ea74210b7f6fad038ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
              "bytes": 213880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9dbbde4fd84a2ab2174a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
              "bytes": 499620,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b1980ce4c249a0e87c8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
              "bytes": 104570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a4dc57fb545108aefd87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
              "bytes": 302909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3165312c8d71a60275e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
              "bytes": 317756,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9c33dac85d8f8acfff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
              "bytes": 836105,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/54a750cb98f126791091.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
              "bytes": 457704,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/822dbc554a0a4c217494.png"
            }
          ],
          "article": {
            "id": "95e296d541c5",
            "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "bytes": 378234,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-42322906964d7eff1651.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "bytes": 283407,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-f9b6ebe483799e46cae4.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "bytes": 228747,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-0ea74210b7f6fad038ef.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "bytes": 213880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9dbbde4fd84a2ab2174a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "bytes": 499620,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-b1980ce4c249a0e87c8a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "bytes": 104570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-a4dc57fb545108aefd87.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "bytes": 302909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-3165312c8d71a60275e1.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "bytes": 317756,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9c33dac85d8f8acfff22.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "bytes": 836105,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-54a750cb98f126791091.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "bytes": 457704,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-822dbc554a0a4c217494.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "So far, I’ve written about two types of generative models,\nGAN\nand\nVAE\n. Neither of them explicitly learns the probability density function of real data, $p(\\mathbf{x})$ (where $\\mathbf{x} \\in \\mathcal{D}$) — because it is really hard! Taking the generative model with latent variables as an example, $p(\\mathbf{x}) = \\int p(\\mathbf{x}\\vert\\mathbf{z})p(\\mathbf{z})d\\mathbf{z}$ can hardly be calculated as it is intractable to go through all possible values of the latent code $\\mathbf{z}$.\nFlow-based deep generative models conquer this hard problem with the help of\nnormalizing flows\n, a powerful statistics tool for density estimation. A good estimation of $p(\\mathbf{x})$ makes it possible to efficiently complete many downstream tasks: sample unobserved but realistic new data points (data generation), predict the rareness of future events (density estimation), infer latent variables, fill in incomplete data samples, etc.\nTypes of Generative Models\n#\nHere is a quick summary of the difference between GAN, VAE, and flow-based generative models:\nGenerative adversarial networks: GAN provides a smart solution to model the data generation, an unsupervised learning problem, as a supervised one. The discriminator model learns to distinguish the real data from the fake samples that are produced by the generator model. Two models are trained as they are playing a\nminimax\ngame.\nVariational autoencoders: VAE inexplicitly optimizes the log-likelihood of the data by maximizing the evidence lower bound (ELBO).\nFlow-based generative models: A flow-based generative model is constructed by a sequence of invertible transformations. Unlike other two, the model explicitly learns the data distribution $p(\\mathbf{x})$ and therefore the loss function is simply the negative log-likelihood.\nComparison of three categories of generative models.\nLinear Algebra Basics Recap\n#\nWe should understand two key concepts before getting into the flow-based generative model: the Jacobian determinant and the change of variable rule. Pretty basic, so feel free to skip.\nJacobian Matrix and Determinant\n#\nGiven a function of mapping a $n$-dimensional input vector $\\mathbf{x}$ to a $m$-dimensional output vector, $\\mathbf{f}: \\mathbb{R}^n \\mapsto \\mathbb{R}^m$, the matrix of all first-order partial derivatives of this function is called the\nJacobian matrix\n, $\\mathbf{J}$ where one entry on the i-th row and j-th column is $\\mathbf{J}_{ij} = \\frac{\\partial f_i}{\\partial x_j}$.\n$$\n\\mathbf{J} = \\begin{bmatrix}\n\\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\[6pt]\n\\vdots & \\ddots & \\vdots \\\\[6pt]\n\\frac{\\partial f_m}{\\partial x_1} & \\dots & \\frac{\\partial f_m}{\\partial x_n} \\\\[6pt]\n\\end{bmatrix}\n$$\nThe determinant is one real number computed as a function of all the elements in a squared matrix. Note that the determinant\nonly exists for\nsquare\nmatrices\n. The absolute value of the determinant can be thought of as a measure of\n“how much multiplication by the matrix expands or contracts space”.\nThe determinant of a nxn matrix $M$ is:\n$$\n\\det M = \\det \\begin{bmatrix}\na_{11} & a_{12} & \\dots & a_{1n} \\\\\na_{21} & a_{22} & \\dots & a_{2n} \\\\\n\\vdots & \\vdots & & \\vdots \\\\\na_{n1} & a_{n2} & \\dots & a_{nn} \\\\\n\\end{bmatrix} = \\sum_{j_1 j_2 \\dots j_n} (-1)^{\\tau(j_1 j_2 \\dots j_n)} a_{1j_1} a_{2j_2} \\dots a_{nj_n}\n$$\nwhere the subscript under the summation $j_1 j_2 \\dots j_n$ are all permutations of the set {1, 2, …, n}, so there are $n!$ items in total; $\\tau(.)$ indicates the\nsignature\nof a permutation.\nThe determinant of a square matrix $M$ detects whether it is invertible: If $\\det(M)=0$ then $M$ is not invertible (a\nsingular\nmatrix with linearly dependent rows or columns; or any row or column is all 0); otherwise, if $\\det(M)\\neq 0$, $M$ is invertible.\nThe determinant of the product is equivalent to the product of the determinants: $\\det(AB) = \\det(A)\\det(B)$. (\nproof\n)\nChange of Variable Theorem\n#\nLet’s review the change of variable theorem specifically in the context of probability density estimation, starting with a single variable case.\nGiven a random variable $z$ and its known probability density function $z \\sim \\pi(z)$, we would like to construct a new random variable using a 1-1 mapping function $x = f(z)$. The function $f$ is invertible, so $z=f^{-1}(x)$. Now the question is\nhow to infer the unknown probability density function of the new variable\n, $p(x)$?\n$$\n\\begin{aligned}\n& \\int p(x)dx = \\int \\pi(z)dz = 1 \\scriptstyle{\\text{   ; Definition of probability distribution.}}\\\\\n& p(x) = \\pi(z) \\left\\vert\\frac{dz}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\left\\vert\\frac{d f^{-1}}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\vert (f^{-1})'(x) \\vert\n\\end{aligned}\n$$\nBy definition, the integral $\\int \\pi(z)dz$ is the sum of an infinite number of rectangles of infinitesimal width $\\Delta z$. The height of such a rectangle at position $z$ is the value of the density function $\\pi(z)$. When we substitute the variable, $z = f^{-1}(x)$ yields $\\frac{\\Delta z}{\\Delta x} = (f^{-1}(x))’$ and $\\Delta z =  (f^{-1}(x))’ \\Delta x$. Here $\\vert(f^{-1}(x))’\\vert$ indicates the ratio between the area of rectangles defined in two different coordinate of variables $z$ and $x$ respectively.\nThe multivariable version has a similar format:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim \\pi(\\mathbf{z}), \\mathbf{x} = f(\\mathbf{z}), \\mathbf{z} = f^{-1}(\\mathbf{x}) \\\\\np(\\mathbf{x}) \n&= \\pi(\\mathbf{z}) \\left\\vert \\det \\dfrac{d \\mathbf{z}}{d \\mathbf{x}} \\right\\vert  \n= \\pi(f^{-1}(\\mathbf{x})) \\left\\vert \\det \\dfrac{d f^{-1}}{d \\mathbf{x}} \\right\\vert\n\\end{aligned}\n$$\nwhere $\\det \\frac{\\partial f}{\\partial\\mathbf{z}}$ is the Jacobian determinant of the function $f$. The full proof of the multivariate version is out of the scope of this post; ask Google if interested ;)\nWhat is Normalizing Flows?\n#\nBeing able to do good density estimation has direct applications in many machine learning problems, but it is very hard. For example, since we need to run backward propagation in deep learning models, the embedded probability distribution (i.e. posterior $p(\\mathbf{z}\\vert\\mathbf{x})$) is expected to be simple enough to calculate the derivative easily and efficiently. That is why Gaussian distribution is often used in latent variable generative models, even though most of real world distributions are much more complicated than Gaussian.\nHere comes a\nNormalizing Flow\n(NF) model for better and more powerful distribution approximation. A normalizing flow transforms a simple distribution into a complex one by applying a sequence of invertible transformation functions. Flowing through a chain of transformations, we repeatedly substitute the variable for the new one according to the change of variables theorem and eventually obtain a probability distribution of the final target variable.\nIllustration of a normalizing flow model, transforming a simple distribution $p\\_0(\\mathbf{z}\\_0)$ to a complex one $p\\_K(\\mathbf{z}\\_K)$ step by step.\nAs defined in Fig. 2,\n$$\n\\begin{aligned}\n\\mathbf{z}_{i-1} &\\sim p_{i-1}(\\mathbf{z}_{i-1}) \\\\\n\\mathbf{z}_i &= f_i(\\mathbf{z}_{i-1})\\text{, thus }\\mathbf{z}_{i-1} = f_i^{-1}(\\mathbf{z}_i) \\\\\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert\n\\end{aligned}\n$$\nThen let’s convert the equation to be a function of $\\mathbf{z}_i$ so that we can do inference with the base distribution.\n$$\n\\begin{aligned}\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\left\\vert \\det \\color{red}{\\Big(\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\Big)^{-1}} \\right\\vert & \\scriptstyle{\\text{; According to the inverse func theorem.}} \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\color{red}{\\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert^{-1}} & \\scriptstyle{\\text{; According to a property of Jacobians of invertible func.}} \\\\\n\\log p_i(\\mathbf{z}_i) &= \\log p_{i-1}(\\mathbf{z}_{i-1}) - \\log \\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert\n\\end{aligned}\n$$\n(*) A note on the\n“inverse function theorem”\n: If $y=f(x)$ and $x=f^{-1}(y)$, we have:\n$$\n\\dfrac{df^{-1}(y)}{dy} = \\dfrac{dx}{dy} = (\\dfrac{dy}{dx})^{-1} = (\\dfrac{df(x)}{dx})^{-1}\n$$\n(*) A note on\n“Jacobians of invertible function”\n: The determinant of the inverse of an invertible matrix is the inverse of the determinant: $\\det(M^{-1}) = (\\det(M))^{-1}$,\nbecause\n$\\det(M)\\det(M^{-1}) = \\det(M \\cdot M^{-1}) = \\det(I) = 1$.\nGiven such a chain of probability density functions, we know the relationship between each pair of consecutive variables. We can expand the equation of the output $\\mathbf{x}$ step by step until tracing back to the initial distribution $\\mathbf{z}_0$.\n$$\n\\begin{aligned}\n\\mathbf{x} = \\mathbf{z}_K &= f_K \\circ f_{K-1} \\circ \\dots \\circ f_1 (\\mathbf{z}_0) \\\\\n\\log p(\\mathbf{x}) = \\log \\pi_K(\\mathbf{z}_K) \n&= \\log \\pi_{K-1}(\\mathbf{z}_{K-1}) - \\log\\left\\vert\\det\\dfrac{d f_K}{d \\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\log \\pi_{K-2}(\\mathbf{z}_{K-2}) - \\log\\left\\vert\\det\\dfrac{d f_{K-1}}{d\\mathbf{z}_{K-2}}\\right\\vert - \\log\\left\\vert\\det\\dfrac{d f_K}{d\\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\dots \\\\\n&= \\log \\pi_0(\\mathbf{z}_0) - \\sum_{i=1}^K \\log\\left\\vert\\det\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\right\\vert\n\\end{aligned}\n$$\nThe path traversed by the random variables $\\mathbf{z}_i = f_i(\\mathbf{z}_{i-1})$ is the\nflow\nand the full chain formed by the successive distributions $\\pi_i$ is called a\nnormalizing flow\n. Required by the computation in the equation, a transformation function $f_i$ should satisfy two properties:\nIt is easily invertible.\nIts Jacobian determinant is easy to compute.\nModels with Normalizing Flows\n#\nWith normalizing flows in our toolbox, the exact log-likelihood of input data $\\log p(\\mathbf{x})$ becomes tractable. As a result, the training criterion of flow-based generative model is simply the negative log-likelihood (NLL) over the training dataset $\\mathcal{D}$:\n$$\n\\mathcal{L}(\\mathcal{D}) = - \\frac{1}{\\vert\\mathcal{D}\\vert}\\sum_{\\mathbf{x} \\in \\mathcal{D}} \\log p(\\mathbf{x})\n$$\nRealNVP\n#\nThe\nRealNVP\n(Real-valued Non-Volume Preserving;\nDinh et al., 2017\n) model implements a normalizing flow by stacking a sequence of invertible bijective transformation functions. In each bijection $f: \\mathbf{x} \\mapsto \\mathbf{y}$, known as\naffine coupling layer\n,  the input dimensions are split into two parts:\nThe first $d$ dimensions stay same;\nThe second part, $d+1$ to $D$ dimensions, undergo an affine transformation (“scale-and-shift”) and both the scale and shift parameters are functions of the first $d$ dimensions.\n$$\n\\begin{aligned}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{aligned}\n$$\nwhere $s(.)$ and $t(.)$ are\nscale\nand\ntranslation\nfunctions and both map $\\mathbb{R}^d \\mapsto \\mathbb{R}^{D-d}$. The $\\odot$ operation is the element-wise product.\nNow let’s check whether this transformation satisfy two basic properties  for a flow transformation.\nCondition 1\n: “It is easily invertible.”\nYes and it is fairly straightforward.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= (\\mathbf{y}_{d+1:D} - t(\\mathbf{y}_{1:d})) \\odot \\exp(-s(\\mathbf{y}_{1:d}))\n\\end{cases}\n$$\nCondition 2\n: “Its Jacobian determinant is easy to compute.”\nYes. It is not hard to get the Jacobian matrix and determinant of this transformation. The Jacobian is a lower triangular matrix.\n$$\n\\mathbf{J} = \n\\begin{bmatrix}\n  \\mathbb{I}_d & \\mathbf{0}_{d\\times(D-d)} \\\\[5pt]\n  \\frac{\\partial \\mathbf{y}_{d+1:D}}{\\partial \\mathbf{x}_{1:d}} & \\text{diag}(\\exp(s(\\mathbf{x}_{1:d})))\n\\end{bmatrix}\n$$\nHence the determinant is simply the product of terms on the diagonal.\n$$\n\\det(\\mathbf{J}) \n= \\prod_{j=1}^{D-d}\\exp(s(\\mathbf{x}_{1:d}))_j\n= \\exp(\\sum_{j=1}^{D-d} s(\\mathbf{x}_{1:d})_j)\n$$\nSo far, the affine coupling layer looks perfect for constructing a normalizing flow :)\nEven better, since (i) computing $f^-1$ does not require computing the inverse of $s$ or $t$ and (ii) computing the Jacobian determinant does not involve computing the Jacobian of $s$ or $t$, those functions can be\narbitrarily complex\n; i.e. both $s$ and $t$ can be modeled by deep neural networks.\nIn one affine coupling layer, some dimensions (channels) remain unchanged. To make sure all the inputs have a chance to be altered, the model reverses the ordering in each layer so that different components are left unchanged. Following such an alternating pattern, the set of units which remain identical in one transformation layer are always modified in the next. Batch normalization is found to help training models with a very deep stack of coupling layers.\nFurthermore, RealNVP can work in a multi-scale architecture to build a more efficient model for large inputs. The multi-scale architecture applies several “sampling” operations to normal affine layers, including spatial checkerboard pattern masking, squeezing operation, and channel-wise masking. Read the\npaper\nfor more details on the multi-scale architecture.\nNICE\n#\nThe\nNICE\n(Non-linear Independent Component Estimation;\nDinh, et al. 2015\n) model is a predecessor of\nRealNVP\n. The transformation in NICE is the affine coupling layer without the scale term, known as\nadditive coupling layer\n.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} + m(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= \\mathbf{y}_{d+1:D} - m(\\mathbf{y}_{1:d})\n\\end{cases}\n$$\nGlow\n#\nThe\nGlow\n(\nKingma and Dhariwal, 2018\n) model extends the previous reversible generative models, NICE and RealNVP, and simplifies the architecture by replacing the reverse permutation operation on the channel ordering with invertible 1x1 convolutions.\nOne step of flow in the Glow model. (Image source:\nKingma and Dhariwal, 2018\n)\nThere are three substeps in one step of flow in Glow.\nSubstep 1:\nActivation normalization\n(short for “actnorm”)\nIt performs an affine transformation using a scale and bias parameter per channel, similar to batch normalization, but works for mini-batch size 1. The parameters are trainable but initialized so that the first minibatch of data have mean 0 and standard deviation 1 after actnorm.\nSubstep 2:\nInvertible 1x1 conv\nBetween layers of the RealNVP flow, the ordering of channels is reversed so that all the data dimensions have a chance to be altered. A 1×1 convolution with equal number of input and output channels is\na generalization of any permutation\nof the channel ordering.\nSay, we have an invertible 1x1 convolution of an input $h \\times w \\times c$ tensor $\\mathbf{h}$ with a weight matrix $\\mathbf{W}$ of size $c \\times c$. The output is a $h \\times w \\times c$ tensor, labeled as $f = \\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})$. In order to apply the change of variable rule, we need to compute the Jacobian determinant $\\vert \\det\\partial f / \\partial\\mathbf{h}\\vert$.\nBoth the input and output of 1x1 convolution here can be viewed as a matrix of size $h \\times w$. Each entry $\\mathbf{x}_{ij}$ ($i=1,\\dots,h, j=1,\\dots,w$) in $\\mathbf{h}$ is a vector of $c$ channels and each entry is multiplied by the weight matrix $\\mathbf{W}$ to obtain the corresponding entry $\\mathbf{y}_{ij}$ in the output matrix respectively. The derivative of each entry is $\\partial \\mathbf{x}_{ij} \\mathbf{W} / \\partial\\mathbf{x}_{ij} = \\mathbf{W}$ and there are $h \\times w$ such entries in total:\n$$\n\\log \\left\\vert\\det \\frac{\\partial\\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})}{\\partial\\mathbf{h}}\\right\\vert\n= \\log (\\vert\\det\\mathbf{W}\\vert^{h \\cdot w}\\vert) = h \\cdot w \\cdot \\log \\vert\\det\\mathbf{W}\\vert\n$$\nThe inverse 1x1 convolution depends on the inverse matrix $\\mathbf{W}^{-1}$. Since the weight matrix is relatively small, the amount of computation for the matrix determinant (\ntf.linalg.det\n) and inversion (\ntf.linalg.inv\n) is still under control.\nSubstep 3:\nAffine coupling layer\nThe design is same as in RealNVP.\nThree substeps in one step of flow in Glow. (Image source:\nKingma and Dhariwal, 2018\n)\nModels with Autoregressive Flows\n#\nThe\nautoregressive\nconstraint is a way to model sequential data, $\\mathbf{x} = [x_1, \\dots, x_D]$: each output only depends on the data observed in the past, but not on the future ones. In other words, the probability of observing $x_i$ is conditioned on $x_1, \\dots, x_{i-1}$ and the product of these conditional probabilities gives us the probability of observing the full sequence:\n$$\np(\\mathbf{x}) = \\prod_{i=1}^{D} p(x_i\\vert x_1, \\dots, x_{i-1}) = \\prod_{i=1}^{D} p(x_i\\vert x_{1:i-1})\n$$\nHow to model the conditional density is of your choice. It can be a univariate Gaussian with mean and standard deviation computed as a function of $x_{1:i-1}$, or a multilayer neural network with $x_{1:i-1}$ as the input.\nIf a flow transformation in a normalizing flow is framed as an autoregressive model — each dimension in a vector variable is conditioned on the previous dimensions — this is an\nautoregressive flow\n.\nThis section starts with several classic autoregressive models (MADE, PixelRNN, WaveNet) and then we dive into autoregressive flow models (MAF and IAF).\nMADE\n#\nMADE\n(Masked Autoencoder for Distribution Estimation;\nGermain et al., 2015\n) is a specially designed architecture to enforce the autoregressive property in the autoencoder\nefficiently\n. When using an autoencoder to predict the conditional probabilities, rather than feeding the autoencoder with input of different observation windows $D$ times, MADE removes the contribution from certain hidden units by multiplying binary mask matrices so that each input dimension is reconstructed only from previous dimensions in a\ngiven\nordering in a\nsingle pass\n.\nIn a multilayer fully-connected neural network, say, we have $L$ hidden layers with weight matrices $\\mathbf{W}^1, \\dots, \\mathbf{W}^L$ and an output layer with weight matrix $\\mathbf{V}$. The output $\\hat{\\mathbf{x}}$ has each dimension $\\hat{x}_i = p(x_i\\vert x_{1:i-1})$.\nWithout any mask, the computation through layers looks like the following:\n$$\n\\begin{aligned}\n\\mathbf{h}^0 &= \\mathbf{x} \\\\\n\\mathbf{h}^l &= \\text{activation}^l(\\mathbf{W}^l\\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma(\\mathbf{V}\\mathbf{h}^L + \\mathbf{c})\n\\end{aligned}\n$$\nDemonstration of how MADE works in a three-layer feed-forward neural network. (Image source:\nGermain et al., 2015\n)\nTo zero out some connections between layers, we can simply element-wise multiply every weight matrix by a binary mask matrix. Each hidden node is assigned with a random “connectivity integer” between $1$ and $D-1$; the assigned value for the $k$-th unit in the $l$-th layer is denoted by $m^l_k$. The binary mask matrix is determined by element-wise comparing values of two nodes in two layers.\n$$\n\\begin{aligned}\n\\mathbf{h}^l &= \\text{activation}^l((\\mathbf{W}^l \\color{red}{\\odot \\mathbf{M}^{\\mathbf{W}^l}}) \\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma((\\mathbf{V} \\color{red}{\\odot \\mathbf{M}^{\\mathbf{V}}}) \\mathbf{h}^L + \\mathbf{c}) \\\\\nM^{\\mathbf{W}^l}_{k', k} \n&= \\mathbf{1}_{m^l_{k'} \\geq m^{l-1}_k} \n= \\begin{cases}\n    1, & \\text{if } m^l_{k'} \\geq m^{l-1}_k\\\\\n    0, & \\text{otherwise}\n\\end{cases} \\\\\nM^{\\mathbf{V}}_{d, k} \n&= \\mathbf{1}_{d \\geq m^L_k} \n= \\begin{cases}\n    1, & \\text{if } d > m^L_k\\\\\n    0, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nA unit in the current layer can only be connected to other units with equal or smaller numbers in the previous layer and this type of dependency easily propagates through the network up to the output layer. Once the numbers are assigned to all the units and layers, the ordering of input dimensions is fixed and the conditional probability is produced with respect to it.  See a great illustration in To make sure all the hidden units are connected to the input and output layers through some paths, the $m^l_k$ is sampled to be equal or greater than the minimal connectivity integer in the previous layer, $\\min_{k’} m_{k’}^{l-1}$.\nMADE training can be further facilitated by:\nOrder-agnostic training\n: shuffle the input dimensions, so that MADE is able to model any arbitrary ordering; can create an ensemble of autoregressive models at the runtime.\nConnectivity-agnostic training\n: to avoid a model being tied up to a specific connectivity pattern constraints, resample $m^l_k$ for each training minibatch.\nPixelRNN\n#\nPixelRNN (\nOord et al, 2016\n) is a deep generative model for images. The image is generated one pixel at a time and each new pixel is sampled conditional on the pixels that have been seen before.\nLet’s consider an image of size $n \\times n$, $\\mathbf{x} = \\{x_1, \\dots, x_{n^2}\\}$, the model starts generating pixels from the top left corner, from left to right and top to bottom (See Fig. 6).\nThe context for generating one pixel in PixelRNN. (Image source:\nOord et al, 2016\n)\nEvery pixel $x_i$ is sampled from a probability distribution conditional over the the past context: pixels above it or on the left of it when in the same row. The definition of such context looks pretty arbitrary, because how visual\nattention\nis attended to an image is more flexible. Somehow magically a generative model with such a strong assumption works.\nOne implementation that could capture the entire context is the\nDiagonal BiLSTM\n. First, apply the\nskewing\noperation by offsetting each row of the input feature map by one position with respect to the previous row, so that computation for each row can be parallelized. Then the LSTM states are computed with respect to the current pixel and the pixels on the left.\n(a) PixelRNN with diagonal BiLSTM. (b) Skewing operation that offsets each row in the feature map by one with regards to the row above. (Image source:\nOord et al, 2016\n)\n$$\n\\begin{aligned}\n\\lbrack \\mathbf{o}_i, \\mathbf{f}_i, \\mathbf{i}_i, \\mathbf{g}_i \\rbrack &= \\sigma(\\mathbf{K}^{ss} \\circledast \\mathbf{h}_{i-1} + \\mathbf{K}^{is} \\circledast \\mathbf{x}_i) & \\scriptstyle{\\text{; }\\sigma\\scriptstyle{\\text{ is tanh for g, but otherwise sigmoid; }}\\circledast\\scriptstyle{\\text{ is convolution operation.}}} \\\\\n\\mathbf{c}_i &= \\mathbf{f}_i \\odot \\mathbf{c}_{i-1} + \\mathbf{i}_i \\odot \\mathbf{g}_i & \\scriptstyle{\\text{; }}\\odot\\scriptstyle{\\text{ is elementwise product.}}\\\\\n\\mathbf{h}_i &= \\mathbf{o}_i \\odot \\tanh(\\mathbf{c}_i)\n\\end{aligned}\n$$\nwhere $\\circledast$ denotes the convolution operation and $\\odot$ is the element-wise multiplication. The input-to-state component $\\mathbf{K}^{is}$ is a 1x1 convolution, while the state-to-state recurrent component is computed with a column-wise convolution $\\mathbf{K}^{ss}$ with a kernel of size 2x1.\nThe diagonal BiLSTM layers are capable of processing an unbounded context field, but expensive to compute due to the sequential dependency between states. A faster implementation uses multiple convolutional layers without pooling to define a bounded context box. The convolution kernel is masked so that the future context is not seen, similar to\nMADE\n. This convolution version is called\nPixelCNN\n.\nPixelCNN with masked convolution constructed by an elementwise product of a mask tensor and the convolution kernel before applying it. (Image source: http://slazebni.cs.illinois.edu/spring17/lec13_advanced.pdf)\nWaveNet\n#\nWaveNet\n(\nVan Den Oord, et al. 2016\n) is very similar to PixelCNN but applied to 1-D audio signals. WaveNet consists of a stack of\ncausal convolution\nwhich is a convolution operation designed to respect the ordering: the prediction at a certain timestamp can only consume the data observed in the past, no dependency on the future. In PixelCNN, the causal convolution is implemented by masked convolution kernel. The causal convolution in WaveNet is simply to shift the output by a number of timestamps to the future so that the output is aligned with the last input element.\nOne big drawback of convolution layer is a very limited size of receptive field. The output can hardly depend on the input hundreds or thousands of timesteps ago, which can be a crucial requirement for modeling long sequences. WaveNet therefore adopts\ndilated convolution\n(\nanimation\n), where the kernel is applied to an evenly-distributed subset of samples in a much larger receptive field of the input.\nVisualization of WaveNet models with a stack of (top) causal convolution layers and (bottom) dilated convolution layers. (Image source:\nVan Den Oord, et al. 2016\n)\nWaveNet uses the gated activation unit as the non-linear layer, as it is found to work significantly better than ReLU for modeling 1-D audio data. The residual connection is applied after the gated activation.\n$$\n\\mathbf{z} = \\tanh(\\mathbf{W}_{f,k}\\circledast\\mathbf{x})\\odot\\sigma(\\mathbf{W}_{g,k}\\circledast\\mathbf{x})\n$$\nwhere $\\mathbf{W}_{f,k}$ and $\\mathbf{W}_{g,k}$ are convolution filter and gate weight matrix of the $k$-th layer, respectively; both are learnable.\nMasked Autoregressive Flow\n#\nMasked Autoregressive Flow\n(\nMAF\n;\nPapamakarios et al., 2017\n) is a type of normalizing flows, where the transformation layer is built as an autoregressive neural network. MAF is very similar to\nInverse Autoregressive Flow\n(IAF) introduced later. See more discussion on the relationship between MAF and IAF in the next section.\nGiven two random variables, $\\mathbf{z} \\sim \\pi(\\mathbf{z})$ and $\\mathbf{x} \\sim p(\\mathbf{x})$ and the probability density function $\\pi(\\mathbf{z})$ is known, MAF aims to learn $p(\\mathbf{x})$. MAF generates each $x_i$ conditioned on the past dimensions $\\mathbf{x}_{1:i-1}$.\nPrecisely the conditional probability is an affine transformation of $\\mathbf{z}$, where the scale and shift terms are functions of the observed part of $\\mathbf{x}$.\nData generation, producing a new $\\mathbf{x}$:\n$x_i \\sim p(x_i\\vert\\mathbf{x}_{1:i-1}) = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})\\text{, where }\\mathbf{z} \\sim \\pi(\\mathbf{z})$\nDensity estimation, given a known $\\mathbf{x}$:\n$p(\\mathbf{x}) = \\prod_{i=1}^D p(x_i\\vert\\mathbf{x}_{1:i-1})$\nThe generation procedure is sequential, so it is slow by design. While density estimation only needs one pass the network using architecture like\nMADE\n. The transformation function is trivial to inverse and the Jacobian determinant is easy to compute too.\nInverse Autoregressive Flow\n#\nSimilar to MAF,\nInverse autoregressive flow\n(\nIAF\n;\nKingma et al., 2016\n) models the conditional probability of the target variable as an autoregressive model too, but with a reversed flow, thus achieving a much efficient sampling process.\nFirst, let’s reverse the affine transformation in MAF:\n$$\nz_i = \\frac{x_i - \\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} + x_i \\odot \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n$$\nIf let:\n$$\n\\begin{aligned}\n& \\tilde{\\mathbf{x}} = \\mathbf{z}\\text{, }\\tilde{p}(.) = \\pi(.)\\text{, }\\tilde{\\mathbf{x}} \\sim \\tilde{p}(\\tilde{\\mathbf{x}}) \\\\\n& \\tilde{\\mathbf{z}} = \\mathbf{x} \\text{, }\\tilde{\\pi}(.) = p(.)\\text{, }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\\\\\n& \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\mu}_i(\\mathbf{x}_{1:i-1}) = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} \\\\\n& \\tilde{\\sigma}(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\sigma}(\\mathbf{x}_{1:i-1}) = \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n\\end{aligned}\n$$\nThen we would have,\n$$\n\\tilde{x}_i \\sim p(\\tilde{x}_i\\vert\\tilde{\\mathbf{z}}_{1:i}) = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})\n\\text{, where }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\n$$\nIAF intends to estimate the probability density function of $\\tilde{\\mathbf{x}}$ given that $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$ is already known. The inverse flow is an autoregressive affine transformation too, same as in MAF, but the scale and shift terms are autoregressive functions of observed variables from the known distribution $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$. See the comparison between MAF and IAF in\nComparison of MAF and IAF.  The variable with known density is in green while the unknown one is in red.\nComputations of the individual elements $\\tilde{x}_i$ do not depend on each other, so they are easily parallelizable (only one pass using MADE). The density estimation for a known $\\tilde{\\mathbf{x}}$ is not efficient, because we have to recover the value of $\\tilde{z}_i$ in a sequential order, $\\tilde{z}_i = (\\tilde{x}_i - \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})) / \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1})$, thus D times in total.\nBase distribution\nTarget distribution\nModel\nData generation\nDensity estimation\nMAF\n$\\mathbf{z}\\sim\\pi(\\mathbf{z})$\n$\\mathbf{x}\\sim p(\\mathbf{x})$\n$x_i = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})$\nSequential; slow\nOne pass; fast\nIAF\n$\\tilde{\\mathbf{z}}\\sim\\tilde{\\pi}(\\tilde{\\mathbf{z}})$\n$\\tilde{\\mathbf{x}}\\sim\\tilde{p}(\\tilde{\\mathbf{x}})$\n$\\tilde{x}_i  = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})$\nOne pass; fast\nSequential; slow\n———-\n———-\n———-\n———-\n———-\n———-\nVAE + Flows\n#\nIn\nVariational Autoencoder\n, if we want to model the posterior $p(\\mathbf{z}\\vert\\mathbf{x})$ as a more complicated distribution rather than simple Gaussian. Intuitively we can use normalizing flow to transform the base Gaussian for better density approximation. The encoder then would predict a set of scale and shift terms $(\\mu_i, \\sigma_i)$ which are all functions of input $\\mathbf{x}$. Read the\npaper\nfor more details if interested.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be very happy to correct them right away!\nSee you in the next post :D\nCited as:\n@article{weng2018flow,\n  title   = \"Flow-based Deep Generative Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-10-13-flow-models/\"\n}\nReference\n#\n[1] Danilo Jimenez Rezende, and Shakir Mohamed.\n“Variational inference with normalizing flows.”\nICML 2015.\n[2]\nNormalizing Flows Tutorial, Part 1: Distributions and Determinants\nby Eric Jang.\n[3]\nNormalizing Flows Tutorial, Part 2: Modern Normalizing Flows\nby Eric Jang.\n[4]\nNormalizing Flows\nby Adam Kosiorek.\n[5] Laurent Dinh, Jascha Sohl-Dickstein, and Samy Bengio.\n“Density estimation using Real NVP.”\nICLR 2017.\n[6] Laurent Dinh, David Krueger, and Yoshua Bengio.\n“NICE: Non-linear independent components estimation.”\nICLR 2015 Workshop track.\n[7] Diederik P. Kingma, and Prafulla Dhariwal.\n“Glow: Generative flow with invertible 1x1 convolutions.”\narXiv:1807.03039 (2018).\n[8] Germain, Mathieu, Karol Gregor, Iain Murray, and Hugo Larochelle.\n“Made: Masked autoencoder for distribution estimation.”\nICML 2015.\n[9] Aaron van den Oord, Nal Kalchbrenner, and Koray Kavukcuoglu.\n“Pixel recurrent neural networks.”\nICML 2016.\n[10] Diederik P. Kingma, et al.\n“Improved variational inference with inverse autoregressive flow.”\nNIPS. 2016.\n[11] George Papamakarios, Iain Murray, and Theo Pavlakou.\n“Masked autoregressive flow for density estimation.”\nNIPS 2017.\n[12] Jianlin Su, and Guang Wu.\n“f-VAEs: Improve VAEs with Conditional Flows.”\narXiv:1809.05861 (2018).\n[13] Van Den Oord, Aaron, et al.\n“WaveNet: A generative model for raw audio.”\nSSW. 2016.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:34Z",
            "title": "Flow-based Deep Generative Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/95e296d541c5/code/body-000.txt",
                "chars": 231,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05770",
                "bytes": 2901553,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c19a421df88d3d936d27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.08803",
                "bytes": 6681321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d6519de2f9580e55b379.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.8516",
                "bytes": 1717618,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d7013f82bf2a7683aad3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03039",
                "bytes": 13250301,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/60e8d214f8d5c367d55c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03509",
                "bytes": 489445,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5ef7ea5346faa12be094.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06759",
                "bytes": 3015028,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1d8f65c736afa61a5395.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.03499",
                "bytes": 2853802,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/12ed4e68449a6f887358.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.07057",
                "bytes": 1200941,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/298c9ccb8266e330a2f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04934",
                "bytes": 1454651,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7688fe8fd3ce3cbcf849.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.05861",
                "bytes": 9321181,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/8971f265a9c20bb39bab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31712,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/95e296d541c5/pages/source.html",
            "local_html": "attachments/95e296d541c5/pages/article.html",
            "body_base_path": "attachments/95e296d541c5/pages/",
            "body_markdown_path": "attachments/95e296d541c5/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05770",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimax",
                "label": "minimax",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parity_of_a_permutation",
                "label": "signature",
                "type": "a"
              },
              {
                "href": "https://proofwiki.org/wiki/Determinant_of_Matrix_Product",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.08803",
                "label": "Dinh et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.8516",
                "label": "Dinh, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03039",
                "label": "Kingma and Dhariwal, 2018",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/det",
                "label": "tf.linalg.det",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/inv",
                "label": "tf.linalg.inv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03509",
                "label": "Germain et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1601.06759",
                "label": "Oord et al, 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.03499",
                "label": "Van Den Oord, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://github.com/vdumoulin/conv_arithmetic",
                "label": "animation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.07057",
                "label": "Papamakarios et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04934",
                "label": "Kingma et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.05861",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf1.html",
                "label": "Normalizing Flows Tutorial, Part 1: Distributions and Determinants",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf2.html",
                "label": "Normalizing Flows Tutorial, Part 2: Modern Normalizing Flows",
                "type": "a"
              },
              {
                "href": "http://akosiorek.github.io/ml/2018/04/03/norm_flows.html",
                "label": "Normalizing Flows",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
          "status": "partial",
          "article_id": "bd2a1c61491f",
          "local_path": "series-follow/1600/repair/99f4c939175460a007b6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/cfd86d1d041d4e587dd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/57e8505d379090b6a5c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/eb72333120a9bf61db22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
              "bytes": 517373,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/94806f3485ee4c7d4137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
              "bytes": 420355,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/10c3f7a4432b939f41e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
              "bytes": 110695,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9af813630ff27b91e9f8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
              "bytes": 104844,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/2d52fb35835b8ffb9f5c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
              "bytes": 441748,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b512db56c30433d4c252.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
              "bytes": 81702,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/701853184c4d260333df.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
              "bytes": 75150,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/440b77c01199a8fa47a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
              "bytes": 308982,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/321a0b363e9a6d1aa98b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/65f1b4ee283f16066c80.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
              "bytes": 118602,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f6d1acbfbe9a2ebc5720.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
              "bytes": 128314,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/6801941ec960782dbcdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
              "bytes": 49638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/aa7a4901bbb57ffba3a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
              "bytes": 144593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/61300c84161edec245ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
              "bytes": 92635,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e33cbf677e130ee48f58.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
              "bytes": 244624,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f5d3b8b9ebc8beb78c77.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
              "bytes": 135708,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/30a7b1c7f2d502623782.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/528e7d446bed9aeb5917.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
              "bytes": 306995,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/08fa8454100a632db05c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
              "bytes": 296726,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5fade868b98da3fc740e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
              "bytes": 150541,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/1864a0421abec41db939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
              "bytes": 300912,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9bbffc5733b6530c7240.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/8ed5854240a34aa93f46.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family Version 2.0",
            "keywords": "Transformer,注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "publish_date": "2023-01",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer架构家族全景综述（2.0版）",
            "id": "bd2a1c61491f",
            "collected_at": "2026-10-02T14:12:43",
            "title": "The Transformer Family Version 2.0 | Lil'Log",
            "body_markdown": "Many new Transformer architecture improvements have been proposed since my last post on\n“The Transformer Family”\nabout three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$N$\nThe total number of attention layers in the model; not considering MoE.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\nRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nTransformer Basics\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})}{ \\sum_{r \\in \\mathcal{S}_i} \\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_r}^\\top}{\\sqrt{d_k}}) }\n$$\nwhere $\\mathcal{S}_i$ is a collection of key positions for the $i$-th query to attend to.\nSee my old\npost for other types of attention\nif interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttn}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nEncoder-Decoder Architecture\n#\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\n#\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\nSinusoidal Positional Encoding\n#\nSinusoidal positional encoding is defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\nLearned Positional Encoding\n#\nLearned positional encoding assigns each element with a\nlearned\ncolumn vector which encodes its absolute position (\nGehring, et al. 2017\n) and furthermroe this encoding can be learned differently per layer (\nAl-Rfou et al. 2018\n).\nRelative Position Encoding\n#\nShaw et al. (2018)\n) incorporated relative positional information into $\\mathbf{W}^k$ and $\\mathbf{W}^v$. Maximum relative position is clipped to a maximum absolute value of $k$ and this clipping operation enables the model to generalize to unseen sequence lengths. Therefore, $2k + 1$ unique edge labels are considered and let us denote $\\mathbf{P}^k, \\mathbf{P}^v \\in \\mathbb{R}^{2k+1}$ as learnable relative position representations.\n$$\nA_{ij}^k = P^k_{\\text{clip}(j - i, k)} \\quad\nA_{ij}^v = P^v_{\\text{clip}(j - i, k)} \\quad\n\\text{where }\\text{clip}(x, k) = \\text{clip}(x, -k, k)\n$$\nTransformer-XL\n(\nDai et al., 2019\n) proposed a type of relative positional encoding based on reparametrization of dot-product of keys and queries. To keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nRotary Position Embedding\n#\nRotary position embedding (\nRoPE\n;\nSu et al. 2021\n) encodes the absolution position with a\nrotation matrix\nand multiplies key and value matrices of every attention layer with it to inject relative positional information at every layer.\nWhen encoding relative positional information into the inner product of the $i$-th key and the $j$-th query, we would like to formulate the function in a way that the inner product is only about the relative position $i-j$. Rotary Position Embedding (RoPE) makes use of the rotation operation in Euclidean space and frames the relative position embedding as simply rotating feature matrix by an angle proportional to its position index.\nGiven a vector $\\mathbf{z}$, if we want to rotate it counterclockwise by $\\theta$, we can multiply it by a rotation matrix to get $R\\mathbf{z}$ where the rotation matrix $R$ is defined as:\n$$\nR = \\begin{bmatrix}\n\\cos\\theta & -\\sin\\theta \\\\\n\\sin\\theta & \\cos\\theta\n\\end{bmatrix}\n$$\nWhen generalizing to higher dimensional space, RoPE divide the $d$-dimensional space into $d/2$ subspaces and constructs a rotation matrix $R$ of size $d \\times d$ for token at position $i$:\n$$\nR^d_{\\Theta, i} = \\begin{bmatrix}\n\\cos i\\theta_1 & -\\sin i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n\\sin i\\theta_1 & \\cos i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n0 & 0 & \\cos i\\theta_2 & -\\sin i\\theta_2 & \\dots & 0 & 0 \\\\\n0 & 0 & \\sin i\\theta_2 & \\cos i\\theta_2 & \\dots & 0 & 0 \\\\\n\\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n0 & 0 & 0 & 0 & \\dots & \\cos i\\theta_{d/2} & -\\sin i\\theta_{d/2} \\\\\n0 & 0 & 0 & 0 & \\dots & \\sin i\\theta_{d/2} & \\cos i\\theta_{d/2} \\\\\n\\end{bmatrix}\n$$\nwhere in the paper we have $\\Theta = {\\theta_i = 10000^{-2(i−1)/d}, i \\in [1, 2, …, d/2]}$. Note that this is essentially equivalent to sinusoidal positional encoding but formulated as a rotation matrix.\nThen both key and query matrices incorporates the positional information by multiplying with this rotation matrix:\n$$\n\\begin{aligned}\n& \\mathbf{q}_i^\\top \\mathbf{k}_j = (R^d_{\\Theta, i} \\mathbf{W}^q\\mathbf{x}_i)^\\top (R^d_{\\Theta, j} \\mathbf{W}^k\\mathbf{x}_j) = \\mathbf{x}_i^\\top\\mathbf{W}^q R^d_{\\Theta, j-i}\\mathbf{W}^k\\mathbf{x}_j \\\\\n& \\text{ where } R^d_{\\Theta, j-i} = (R^d_{\\Theta, i})^\\top R^d_{\\Theta, j}\n\\end{aligned}\n$$\nVisual illustration of how rotary position embedding is implemented.(Image source:\nSu et al., 2021\n) Note: I used $i$ instead of $m$ to represent the position index compared to the original figure in the paper.\nLonger Context\n#\nThe length of an input sequence for transformer models at inference time is upper-bounded by the context length used for training. Naively increasing context length leads to high consumption in both time ($\\mathcal{O}(L^2d)$) and memory ($\\mathcal{O}(L^2)$) and may not be supported due to hardware constraints.\nThis section introduces several improvements in transformer architecture to better support long context at inference; E.g. using additional memory, design for better context extrapolation, or recurrency mechanism.\nContext Memory\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments. This\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) modifies the architecture to reuse hidden states between segments with an additional memory. The recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both keys and values rely on extended hidden states, while queries only consume hidden states at the current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension. And Transformer-XL needs to use\nrelative positional encoding\nbecause previous and current segments would be assigned with the same encoding if we encode absolute positions, which is undesired.\nCompressive Transformer\n(\nRae et al. 2019\n) extends Transformer-XL by compressing past memories to support longer sequences. It explicitly adds\nmemory\nslots of size $m_m$ per layer for storing past activations of this layer to preserve long context. When some past activations become old enough, they are compressed and saved in an additional\ncompressed memory\nof size $m_{cm}$ per layer.\nCompressive transformer maintains two types of memory slots, memory and compressed memory, to support long context. (Image source:\nRae et al. 2019\n).\nBoth memory and compressed memory are FIFO queues. Given the model context length $L$, the compression function of compression rate $c$ is defined as $f_c: \\mathbb{R}^{L \\times d} \\to \\mathbb{R}^{[\\frac{L}{c}] \\times d}$, mapping $L$ oldest activations to $[\\frac{L}{c}]$ compressed memory elements. There are several choices of compression functions:\nMax/mean pooling of kernel and stride size $c$;\n1D convolution with kernel and stride size $c$ (need to learn additional parameters);\nDilated convolution (need to learn additional parameters). In their experiments, convolution compression works out the best on\nEnWik8\ndataset;\nMost used memories.\nCompressive transformer has two additional training losses:\nAuto-encoding loss\n(lossless compression objective) measures how well we can reconstruct the original memories from compressed memories\n$$\n \\mathcal{L}_{ac} = \\| \\textbf{old_mem}^{(i)} - g(\\textbf{new_cm}^{(i)}) \\|_2\n $$\nwhere $g: \\mathbb{R}^{[\\frac{L}{c}] \\times d} \\to \\mathbb{R}^{L \\times d}$ reverses the compression function $f$.\nAttention-reconstruction loss\n(lossy objective) reconstructs content-based attention over memory vs compressed memory and minimize the difference:\n$$\n \\mathcal{L}_{ar} = \\|\\text{attn}(\\mathbf{h}^{(i)}, \\textbf{old_mem}^{(i)}) − \\text{attn}(\\mathbf{h}^{(i)}, \\textbf{new_cm}^{(i)})\\|_2\n $$\nTransformer-XL with a memory of size $m$ has a maximum temporal range of $m \\times N$, where $N$ is the number of layers in the model, and attention cost $\\mathcal{O}(L^2 + Lm)$. In comparison, compressed transformer has a temporal range of $(m_m + c \\cdot m_{cm}) \\times N$ and attention cost $\\mathcal{O}(L^2 + L(m_m + m_{cm}))$. A larger compression rate $c$ gives better tradeoff between temporal range length and attention cost.\nAttention weights, from oldest to newest, are stored in three locations: compressed memory → memory → causally masked sequence. In the experiments, they observed an increase in attention weights from oldest activations stored in the regular memory, to activations stored in the compressed memory, implying that the network is learning to preserve salient information.\nAttention weights with one standard deviation as error bars versus memory positions, from oldest (left) to newest (right). (Image source:\nRae et al. 2019\n).\nNon-Differentiable External Memory\n#\n$k$NN-LM\n(\nKhandelwal et al. 2020\n) enhances a pretrained LM with a separate $k$NN model by linearly interpolating the next token probabilities predicted by both models. The $k$NN model is built upon an external key-value store  which can store any large pre-training dataset or OOD new dataset. This datastore is preprocessed to save a\nlarge\nnumber of pairs, (LM embedding representation of context, next token) and the nearest neighbor retrieval happens in the LM embedding space. Because the datastore can be gigantic, we need to rely on libraries for fast dense vector search such as\nFAISS\nor\nScaNN\n. The indexing process only happens once and parallelism is easy to implement at inference time.\nAt inference time, the next token probability is a weighted sum of two predictions:\n$$\n\\begin{aligned}\np(y \\vert \\mathbf{x}) &= \\lambda \\; p_\\text{kNN}(y \\vert \\mathbf{x}) + (1- \\lambda) \\; p_\\text{LM}(y \\vert \\mathbf{x}) \\\\\np_\\text{kNN}(y \\vert \\mathbf{x}) &\\propto \\sum_{(k_i, w_i) \\in \\mathcal{N}} \\mathbb{1}[y = w_i] \\exp(-d(k_i, f(\\mathbf{x})))\n\\end{aligned}\n$$\nwhere $\\mathcal{N}$ contains a set of nearest neighbor data points retrieved by $k$NN; $d(., .)$ is a distance function such as L2 distance.\nAccording to the experiments, larger datastore size or larger $k$ is correlated with better perplexity. The weighting scalar $\\lambda$ should be tuned, but in general it is expected to be larger for out-of-domain data compared to in-domain data and larger datastore can afford a larger $\\lambda$.\nSPALM\n(\nAdaptive semiparametric language models\n;\nYogatama et al. 2021\n) incorporates both (1) Transformer-XL style memory for hidden states from external context as short-term memory and (2) $k$NN-LM style key-value store as long memory.\nIllustration of how SPALM combines context memory of past hidden states (short term memory) with an external key-value datastore (long term memory) to support longer context. (Image source:\nYogatama et al. 2021\n).\nSPALM runs $k$NN search to fetch $k$ tokens with most relevant context. For each token we can get the same embedding representation provided by a pretrained LM, denoted as $\\{\\mathbf{y}_i\\}_{i=1}^k$. The gating mechanism first aggregates the retrieved token embeddings with a simple attention layer using $\\mathbf{h}^R_t$ (the hidden state for token $x_t$ at layer $R$) as a query and then learns a gating parameter $\\mathbf{g}_t$ to balance between local information $\\mathbf{h}^R_t$ and long-term information $\\mathbf{m}_t$.\n$$\n\\begin{aligned}\n\\mathbf{m}_t &= \\sum_{i=1}^k \\frac{\\exp(\\mathbf{y}_i^\\top \\mathbf{h}^R_t)}{\\sum_{j=1}^k \\exp(\\mathbf{y}_j^\\top \\mathbf{h}^R_t)} \\cdot \\mathbf{y}_i \\\\\n\\mathbf{g}_t &= \\sigma(\\mathbf{w}_g^\\top \\mathbf{h}_t^R) \\\\\n\\mathbf{z}_t &= (1 - \\mathbf{g}_t) \\odot \\mathbf{m}_t + \\mathbf{g}_t \\odot \\mathbf{h}^R_t \\\\\np(x_{t+1}\\mid \\mathbf{x}_{\\leq t}) &= \\text{softmax}(\\mathbf{z}_t; \\mathbf{W})\n\\end{aligned}\n$$\nwhere $\\mathbf{w}_g$ is a parameter vector to learn; $\\sigma(.)$ is sigmoid; $\\mathbf{W}$ is the word embedding matrix shared between both input and output tokens. Different from $k$NN-LM, they didn’t find the nearest neighbor distance to be helpful in the aggregation of retrieved tokens.\nDuring training, the key representations in the long-term memory stay constant, produced by a pretrained LM, but the value encoder, aka the word embedding matrix, gets updated.\nMemorizing Transformer\n(\nWu et al. 2022\n) adds a $k$NN-augmented attention layer near the top stack of a decoder-only Transformer. This special layer maintains a Transformer-XL style FIFO cache of past key-value pairs.\nThe same QKV values are used for both local attention and $k$NN mechanisms. The $k$NN lookup returns top-$k$ (key, value) pairs for each query in the input sequence and then they are processed through the self-attention stack to compute a weighted average of retrieved values. Two types of attention are combined with a learnable per-head gating parameter. To prevent large distributional shifts in value magnitude, both keys and values in the cache are normalized.\nWhat they found during experiments with Memorizing Transformer:\nIt is observed in some experiments that training models with a small memory and then finetuned with a larger memory works better than training with a large memory from scratch.\nThe smaller Memorizing Transformer with just 8k tokens in memory can match the perplexity of a larger vanilla Transformer with 5X more trainable parameters.\nIncreasing the size of external memory provided consistent gains up to a size of 262K.\nA  non-memory transformer can be finetuned to use memory.\nFine-tuning a vanilla Transformer with a key-value memory can achieve similar performance as training a memorizing transformer from scratch. (Image source:\nWu et al. 2022\n).\nDistance-Enhanced Attention Scores\n#\nDistance Aware Transformer\n(\nDA-Transformer\n;\nWu, et al. 2021\n) and\nAttention with Linear Biases\n(\nALiBi\n;\nPress et al. 2022\n) are motivated by similar ideas — in order to encourage the model to extrapolate over longer context than what the model is trained on, we can explicitly attach the positional information to every pair of attention score based on the distance between key and query tokens.\nNote that the default positional encoding in vanilla Transformer only adds positional information to the input sequence, while later improved encoding mechanisms alter attention scores of every layer, such as\nrotary position embedding\n, and they take on form very similar to distance enhanced attention scores.\nDA-Transformer\n(\nWu, et al. 2021\n) multiplies attention scores at each layer by a learnable bias that is formulated as a function of the distance between key and query. Different attention heads use different parameters to distinguish diverse preferences to short-term vs long-term context. Given two positions, $i, j$, DA-Transformer uses the following weighting function to alter the self-attention score:\n$$\n\\begin{aligned}\n\\mathbf{R}^{(i)} &= \\alpha_i \\mathbf{R} \\quad \\text{where }R_{ij} = \\vert i-j \\vert\\\\\nf(\\mathbf{R}^{(i)}; \\beta_i) &= \\frac{1 + \\exp(\\beta_i)}{1 + \\exp(\\beta_i - \\mathbf{R}^{(i)})} \\\\\n\\text{attn}(\\mathbf{Q}^{(i)}, \\mathbf{K}^{(i)}, \\mathbf{V}^{(i)}) &= \\text{row-softmax}\\Big(\\frac{\\text{ReLU}(\\mathbf{Q}^{(i)}\\mathbf{K}^{(i)\\top})f(\\mathbf{R}^{(i)})}{\\sqrt{d}}\\Big) \\mathbf{V}^{(i)}\n\\end{aligned}\n$$\nwhere $\\alpha_i$ is a learnable parameters to weight relative distance differently per head where the head is indexed by superscript $^{(i)}$; $\\beta_i$ is a learnable parameter to control the upper bound and ascending slope wrt the distance for the $i$-th attention head. The weighting function $f(.)$ is designed in a way that: (1) $f(0)=1$; (2) $f(\\mathbf{R}^{(i)}) = 0$ when $\\mathbf{R}^{(i)} \\to -\\infty$; (3) $f(\\mathbf{R}^{(i)})$ is bounded when $\\mathbf{R}^{(i)} \\to +\\infty$; (4) the scale is tunable; (5) and the function is monotonic. The extra time complexity brought by $f(\\mathbf{R}^{(i)})$ is $\\mathcal{O}(L^2)$ and it is small relative to the self attention time complexity $\\mathcal{O}(L^2 d)$. The extra memory consumption is minimal, ~$\\mathcal{O}(2h)$.\nInstead of multipliers,\nALiBi\n(\nPress et al. 2022\n) adds a constant bias term on query-key attention scores, proportional to pairwise distances. The bias introduces a strong recency preference and penalizes keys that are too far away. The penalties are increased at different rates within different heads.\n$$\n\\text{softmax}(\\mathbf{q}_i \\mathbf{K}^\\top + \\alpha_i \\cdot [0, -1, -2, \\dots, -(i-1)])\n$$\nwhere $\\alpha_i$ is a head-specific weighting scalar. Different from DA-transformer, $\\alpha_i$ is not learned but fixed as a geometric sequence; for example, for 8 heads, ${\\alpha_i} = {\\frac{1}{2}, \\frac{1}{2^2}, \\dots, \\frac{1}{2^8}}$. The overall idea is very much similar to what relative positional encoding aims to solve.\nIllustration of how ALiBi enhances attention scores with a positional bias term. (Image source:\nPress et al. 2021\n).\nWith ALiBi,\nPress et al. (2022)\ntrained a 1.3B model on context length 1024 during training and extrapolated to 2046 at inference time.\nExtrapolation experiments for running inference with Transformers of different configs, including sinusoidal positional encoding, rotary positional encoding, simplified relative positional encoding in T5 and ALiBi. All models were trained with small context length but inference ran for much longer context. (Image source:\nPress et al. 2021\n).\nMake it Recurrent\n#\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN. Rather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{h}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{h}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{h}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{h}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{h}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses\nsinusoidal position signal\nbut with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{h}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nAdaptive Modeling\n#\nAdaptive modeling refers to a mechanism that can adjust the amount of computation according to different inputs. For example, some tokens may only need local information and thus demand a shorter attention span; Or some tokens are relatively easier to predict and do not need to be processed through the entire attention stack.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar et al (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 14) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys within its attention span of size $s$:\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clip}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nDepth-Adaptive Transformer\n#\nAt inference time, it is natural to assume that some tokens are easier to predict and thus do not require as much computation as others. Therefore we may only process its prediction through a limited number of layers to achieve a good balance between speed and performance.\nBoth\nDepth-Adaptive Transformer\n(\nElabyad et al. 2020\n) and\nConfident Adaptive Language Model\n(\nCALM\n;\nSchuster et al. 2022\n) are motivated by this idea and learn to predict optimal numbers of layers needed for different input tokens.\nDepth-adaptive transformer\n(\nElabyad et al. 2020\n) attaches an output classifier to every layer to produce exit predictions based on activations of that layer. The classifier weight matrices can be different per layer or shared across layers. During training, the model sample different sequences of exits such that the model is optimized with hidden states of different layers. The learning objective incorporates likelihood probabilities predicted at different layers, $n=1, \\dots, N$:\n$$\n\\text{LL}^n_t = \\log p(y_t \\vert \\mathbf{h}^n_{t-1}) \\quad\n\\text{LL}^n = \\sum_{t=1}^{\\vert\\mathbf{y}\\vert} LL^n_t\n$$\nAdaptive depth classifiers outputs a parametric distribution $q_t$. It is trained with cross entropy loss against an oracle distribution $q^*_t$. The paper explored three confiurations for how to learn such a classifier $q_t$.\nIllustration of three types of adaptive depth classifiers.\n(Image source:\nElabyad et al. 2020\n).\nSequence-specific depth classifier\n: All tokens of the same sequence share the same exit block. It depends on the average of the encoder representation of the sequence. Given an input sequence $\\mathbf{x}$ of length $L$, the classifier takes $\\bar{\\mathbf{x}} = \\frac{1}{L} \\sum_{t=1}^L \\mathbf{x}_t$ as input and outputs a multinomial distribution of $N$ dimensions, corresponding to $N$ layers.\n$$\n \\begin{aligned}\n q(n \\vert \\mathbf{x}) &=\\text{softmax}(\\mathbf{W}_n \\bar{\\mathbf{x}} + b_n) \\in \\mathbb{R}^N \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\text{LL}^n - \\lambda n) \\\\\n \\text{or }q_\\text{corr}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n C^n - \\lambda n) \\text{ where }C^n = \\vert\\{t \\vert y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})\\}\\vert \\\\\n \\end{aligned}\n $$\nwhere $\\delta$ is\ndirac delta\n(unit impulse) function and $-\\lambda n$ is a regularization term to encourage lower layer exits. The ground truth $q^*$ can be prepared in two way, based on maximum likelihood $q_\\text{lik}^*$ or correctness $q_\\text{corr}^*$.\nToken-specific depth classifier (multinomial)\n: Each token is decoded with different exit block, predicted conditioned on the first decoder hidden state $\\mathbf{h}^1_t$:\n$$\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) = \\text{softmax}(\\mathbf{W}_n \\mathbf{h}^1_t + b_n)\n $$\nToken-specific depth classifier (geometric-like)\n:  A binary exit prediction distribution is made per layer per token, $\\mathcal{X}^n_t$. The RBF kernel $\\kappa(t, t’) = \\exp(\\frac{\\vert t - t’ \\vert^2}{\\sigma})$ is used to smooth the predictions to incorporate the impact of current decision on future time steps.\n$$\n \\begin{aligned}\n \\mathcal{X}^n_t &= \\text{sigmoid}(\\mathbf{w}_n^\\top \\mathbf{h}^n_t + b_n)\\quad \\forall n \\in [1, \\dots, N-1] \\\\\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) &= \\begin{cases}\n \\mathcal{X}^n_t \\prod_{n' < n} (1 - \\mathcal{X}^{n'}_t) & \\text{if } n < N\\\\\n \\prod_{n' < N} (1 - \\mathcal{X}^{n'}_t) & \\text{otherwise}\n \\end{cases} \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\widetilde{\\text{LL}}^n_t - \\lambda n) \\text{ where } \\widetilde{\\text{LL}}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') LL^n_{t'} \\\\\n \\text{or }q_\\text{cor}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\tilde{C}_t^n - \\lambda n) \\text{ where }C_t^n = \\mathbb{1}[y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})],\\; \\tilde{C}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') C^n_{t'} \\\\\n \\end{aligned}\n $$\nAt inference time, the confidence threshold for making an exit decision needs to be calibrated. Depth-adaptive transformer finds such a threshold on a validation set via grid search.\nCALM\n(\nSchuster et al. 2022\n) applied the Learn then Test (LTT) framework (\nAngelopoulos et al. 2021\n) to identify a subset of valid thresholds and chose the minimum value as the threshold for inference. Except for training per-layer exit classifier, CALM also explored other methods for adaptive depth prediction, including the softmax responses (i.e. difference between top two softmax outputs) and hidden state saturation (i.e. $\\cos(\\mathbf{h}^n_t, \\mathbf{h}^{n+1}_t)$) as confidence scores for exit decisions. They found softmax responses result in best inference speedup.\nEfficient Attention\n#\nThe computation and memory cost of the vanilla Transformer grows quadratically with sequence length and hence it is hard to be applied on very long sequences. Many efficiency improvements for Transformer architecture have something to do with the self-attention module - making it cheaper, smaller or faster to run. See the survey paper on\nEfficient Transformers\n(\nTay et al. 2020\n).\nSparse Attention Patterns\n#\nFixed Local Context\n#\nA simple alternation to make self-attention less expensive is to restrict the attention span of each token to\nlocal\ncontext only, so that self-attention grows linearly with the sequence length.\nThe idea was introduced by\nImage Transformer\n(\nParmer, et al 2018\n), which formulates image generation as sequence modeling using an encoder-decoder transformer architecture:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThen the decoder autoregressively generates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nStrided Context\n#\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn auto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\n A_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n \\end{aligned}\n $$\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\n A_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n \\end{aligned}\n $$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. $\\rightarrow$ This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details or my previous post on\ntechniques for scaling up model training\n.\nBlockwise Attention\n(\nQiu et al. 2019\n) introduces a\nsparse block matrix\nto only allow each token to attend to a small set of other tokens. Each attention matrix of size $L \\times L$ is partitioned into $n \\times n$ smaller blocks of size $\\frac{L}{n}\\times\\frac{L}{n}$ and a sparse block matrix $\\mathbf{M} \\in \\{0, 1\\}^{L \\times L}$ is defined by a permutation $\\pi$ of ${1, \\dots, n}$, which records the column index per row in the block matrix.\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) &= \\text{softmax}\\Big(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{d}} \\odot \\mathbf{M}\\Big)\\mathbf{V} \\\\\n(\\mathbf{A} \\odot \\mathbf{M})_{ij} &= \\begin{cases}\nA_{ij} & \\text{if }M_{ij} = 1 \\\\\n-\\infty & \\text{if }M_{ij} = 0 \\\\\n\\end{cases} \\\\\n\\text{where } M_{ij} &= \\begin{cases}\n1 & \\text{if }\\pi\\big(\\lfloor\\frac{(i-1)n}{L} + 1\\rfloor\\big) = \\lfloor\\frac{(j-1)n}{L} + 1\\rfloor \\\\\n0 & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nThe actual implementation of Blockwise Attention only stores QKV as block matrices, each of size $n\\times n$:\n$$\n\\text{Blockwise-attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) = \\begin{bmatrix}\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_1\\hat{\\mathbf{k}}_{\\pi(1)}^\\top}{\\sqrt{d}} \\Big)\\hat{\\mathbf{v}}_{\\pi(1)} \\\\\n\\vdots \\\\\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_n\\hat{\\mathbf{k}}_{\\pi(n)}^\\top}{\\sqrt{d}} \\odot \\Big)\\hat{\\mathbf{v}}_{\\pi(n)} \\\\\n\\end{bmatrix}\n$$\nwhere $\\hat{\\mathbf{q}}_i$, $\\hat{\\mathbf{k}}_i$ and $\\hat{\\mathbf{v}}_i$ are the $i$-the row in the QKV block matrix respectively. Each $\\mathbf{q}_i\\mathbf{k}_{\\pi(i)}^\\top, \\forall i = 1, \\dots, n$ is of size $\\frac{N}{n}\\times\\frac{N}{n}$ and therefore Blockwise Attention is able to reduce the memory complexity of attention matrix from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(\\frac{L}{n}\\times\\frac{L}{n} \\times n) = \\mathcal{O}(L^2/n)$.\nCombination of Local and Global Context\n#\nETC\n(\nExtended Transformer Construction\n;\nAinslie et al. 2019\n),\nLongformer\n(\nBeltagy et al. 2020\n) and\nBig Bird\n(\nZaheer et al. 2020\n) models combine both local and global context when building an attention matrix. All these models can be initialized from existing pretrained models.\nGlobal-Local Attention\nof\nETC\n(\nAinslie et al. 2019\n) takes two inputs, (1) the long input $\\mathbf{x}^l$ of size $n_l$ which is the regular input sequence and (2) the global input $\\mathbf{x}^g$ of size $n_g$ which contains a smaller number of auxiliary tokens, $n_g \\ll n_l$. Attention is thus split into four components based on directional attention across these two inputs: g2g, g2l, l2g and l2l. Because the l2l attention piece can be very large, it is restricted to a fixed size attention span of radius $w$ (i.e. local attention span) and the l2l matrix can be reshaped to $n_l \\times (2w+1)$.\nETC utilizes four binary matrices to handle structured inputs, $\\mathbf{M}^{g2g}$, $\\mathbf{M}^{g2l}$, $\\mathbf{M}^{l2g}$ and $\\mathbf{M}^{l2l}$. For example, each element $z^g_i \\in \\mathbb{R}^d$ in the attention output $z^g = (z^g_1, \\dots, z^g_{n_g})$ for g2g attention piece is formatted as:\n$$\n\\begin{aligned}\na^{g2g}_{ij} = \\frac{1}{\\sqrt{d}} x^g_i \\mathbf{W}^Q (x^g_j \\mathbf{W}^K + P^K_{ij})^\\top - (1- M^{g2g}_{ij})C \\\\\nA^{g2g}_{ij} = \\frac{\\exp(a^{g2g}_{ij})}{\\sum_{k=1}^{n_g} \\exp(a^{g2g}_{ik})} \\quad\nz^g_i = \\sum^{n_g}_{j=1} A^{g2g}_{ij} x^g_j \\mathbf{W}^V\n\\end{aligned}\n$$\nwhere $P^K_{ij}$ is a learnable vector for relative position encoding and $C$ is a very large constant ($C=10000$ in the paper) to offset any attention weights when mask is off.\nAttention patterns of ETC, Longformer and Big Bird.\nOne more update in ETC is to incorporate a CPC (contrastive predictive coding) task using\nNCE loss\ninto the pretraining stage, besides the\nMLM\ntask: The representation of one sentence should be similar to the representation of context around it when this sentence is masked.\nThe global input $\\mathbf{x}^g$ for ETC is constructed as follows: Assuming there are some segments within the long inputs (e.g. by sentence), each segment is attached with one auxiliary token to learn global inputs.\nRelative position encoding\nis used to mark the global segment tokens with the token position. Hard masking in one direction (i.e., tokens before vs after are labeled differently) is found to bring performance gains in some datasets.\nAttention pattern in Longformer contains three components:\nLocal attention\n: Similar to ETC, local attention is controlled by a sliding window of fixed size $w$;\nGlobal attention of preselected tokens\n: Longformer has a few pre-selected tokens (e.g.\n[CLS]\ntoken) assigned with global attention span, that is, attending to all other tokens in the input sequence.\nDilated attention\n: Dilated sliding window of fixed size $r$ and gaps of dilation size $d$, similar to Sparse Transformer;\nBig Bird\nis quite similar to Longformer, equipped with both local attention and a few preselected tokens with global attention span, but Big Bird replaces dilated attention with a new mechanism where all tokens attend to a set of random tokens. The design is motivated by the fact that attention pattern can be viewed as a\ndirected graph\nand a\nrandom graph\nhas the property that information is able to rapidly flow between any pair of nodes.\nLongformer\nuses smaller window size at lower layers and larger window sizes at higher layers. Ablation studies showed that this setup works better than reversed or fixed size config. Lower layers do not have dilated sliding windows to better learn to use immediate local context. Longformer also has a staged training procedure where initially the model is trained with small window size to learn from local context and then subsequent stages of training have window sizes increased and learning rate decreased.\nContent-based Attention\n#\nThe improvements proposed by\nReformer\n(\nKitaev, et al. 2020\n) aim to solve the following pain points in vanilla Transformer:\nQuadratic time and memory complexity within self-attention module.\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 20:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nRouting Transformer\n(\nRoy et al. 2021\n) is also built on content-based clustering of keys and queries. Instead of using a static hashing function like LSH, it utilizes online $k$-means clustering and combines it with local, temporal sparse attention to reduce the attention complexity from $O(L^2)$ to $O(L^{1.5})$.\nWithin routing attention, both keys and queries are clustered with $k$-means clustering method and the same set of centroids $\\boldsymbol{\\mu} = (\\mu_1, \\dots, \\mu_k) \\in \\mathbb{R}^{k \\times d}$. Queries are routed to keys that get assigned to the same centroid. The total complexity is $O(Lkd + L^2d/k)$, where $O(Lkd)$ is for running clustering assignments and $O(L^2d/k)$ is for attention computation. The cluster centroids are updated by EMA (exponential moving average) using all associated keys and queries.\nIn the experiments for Routing Transformer, some best config only has routing attention enabled in the last two layers of the model and half of the attention heads, while the other half utilizing local attention. They also observed that local attention is a pretty strong baseline and larger attention window always leads to better results.\nLow-Rank Attention\n#\nLinformer\n(\nWang et al. 2020\n) approximates the full attention matrix with a\nlow rank\nmatrix, reducing the time & space complexity to be\nlinear\n. Instead of using expensive SVD to identify low rank decomposition, Linformer adds two linear projections $\\mathbf{E}_i, \\mathbf{F}_i \\in \\mathbb{R}^{L \\times k}$ for key and value matrices, respectively, reducing their dimensions from $L \\times d$ to $k \\times d$. As long as $k \\ll L$, the attention memory can be greatly reduced.\n$$\n\\begin{aligned}\n\\overline{\\text{head}}_i \n&= \\text{attn}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{E}_i\\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{F}_i\\mathbf{X}_v\\mathbf{W}^v_i) \\\\\n&= \\underbrace{\\text{softmax}\\Big( \\frac{\\mathbf{X}_q\\mathbf{W}^q_i (\\mathbf{E}_i \\mathbf{X}_k\\mathbf{W}^k_i)^\\top}{\\sqrt{d}} \\Big)}_{\\text{low rank attention matrix }\\bar{A} \\in \\mathbb{R}^{k \\times d}} \\mathbf{F}_i \\mathbf{X}_v\\mathbf{W}^v_i\n\\end{aligned}\n$$\nAdditional techniques can be applied to further improve efficiency of Linformer:\nParameter sharing between projection layers, such as head-wise, key-value  and layer-wise (across all layers) sharing.\nUse different $k$ at different layers, as heads in higher layers tend to have a more skewed distribution (lower rank) and thus we can use smaller $k$ at higher layers.\nUse different types of projections; e.g. mean/max pooling, convolution layer with kernel and stride $L/k$.\n(Left) Informer has two projection layers added for keys and values. (Right) Plot of inference time as a function of sequence length. (Image source:\nWang et al. 2020\n).\nRandom Feature Attention\n(\nRFA\n;\nPeng et al. 2021\n) relies on\nrandom feature methods\n(\nRahimi & Recht, 2007\n) to approximate softmax operation in self-attention with low rank feature maps in order to achieve linear time and space complexity.\nPerformers\n(\nChoromanski et al. 2021\n) also adopts random feature attention with improvements on the kernel construction to further reduce the kernel approximation error.\nThe main theorem behind RFA is from\nRahimi & Recht, 2007\n:\nLet $\\phi: \\mathbb{R}^d \\to \\mathbb{R}^{2D}$ be a nonlinear transformation:\n$$\n\\phi(\\mathbf{x}) = \\frac{1}{\\sqrt{D}}[\\sin(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\sin(\\mathbf{w}_D^\\top \\mathbf{x}), \\cos(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\cos(\\mathbf{w}_D^\\top \\mathbf{x})]^\\top\n$$\nWhen $d$-dimensional random vectors $\\mathbf{w}_i$ are i.i.d. from $\\mathcal{N}(\\mathbf{0}, \\sigma^2\\mathbf{I}_d)$,\n$$\n\\mathbb{E}_{\\mathbf{w}_i} [\\phi(\\mathbf{x}) \\cdot \\phi(\\mathbf{y})] = \\exp(-\\frac{\\| \\mathbf{x} - \\mathbf{y} \\|^2}{2\\sigma^2})\n$$\nAn unbiased estimation of $\\exp(\\mathbf{x} \\cdot \\mathbf{y})$ is:\n$$\n\\begin{aligned}\n\\exp(\\mathbf{x} \\cdot \\mathbf{y} / \\sigma^2) \n&= \\exp(\\frac{1}{2\\sigma^2}(\\|\\mathbf{x}\\|^2 + \\|\\mathbf{y}\\|^2 - \\|\\mathbf{x} - \\mathbf{y}\\|^2) \\\\\n&= \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2}) ( - \\frac{\\|\\mathbf{x} - \\mathbf{y}\\|^2}{2\\sigma^2}) \\\\\n&\\approx \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) \\\\\n&= \\exp(\\frac{1}{\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) & \\text{; unit vectors}\n\\end{aligned}\n$$\nThen we can write the attention function as follows, where $\\otimes$ is outer product operation and $\\sigma^2$ is the temperature:\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\}) \n&= \\sum_i \\frac{\\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_i/\\sigma^2)}{\\sum_j \\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_j/\\sigma^2)}\\mathbf{v}_i^\\top\n\\approx \\sum_i \\frac{\\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_i)\\mathbf{v}_i^\\top}{\\sum_j \\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_j)} \\\\\n&= \\color{green}{\\frac{\\phi(\\mathbf{q}_t)^\\top \\sum_i \\phi(\\mathbf{k}_i)\\otimes\\mathbf{v}_i}{\\phi(\\mathbf{q}_t)^\\top \\sum_j \\phi(\\mathbf{k}_j)}\n= \\text{RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\})}\n\\end{aligned}\n$$\n(Left) The order of computation for default softmax operation. (Right) The order of computation when using random feature attention, a lot cheaper than default softmax. (Image source:\nPeng et al. 2021\n).\nCausal Attention RFA\nhas token at time step $t$ only attend to earlier keys and values $\\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}$. Let us use a tuple of variables, $(\\mathbf{S}_t \\in \\mathbb{R}^{2D \\times d}, \\mathbf{z} \\in \\mathbb{R}^{2D})$, to track the hidden state history at time step $t$, similar to RNNs:\n$$\n\\begin{aligned}\n&\\text{causal-RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}) = \\frac{\\phi(\\mathbf{q}_t)^\\top \\mathbf{S}_t}{\\phi(\\mathbf{q}_t) \\cdot \\mathbf{z}_t} \\\\\n&\\text{where } \n\\mathbf{S}_t = \\mathbf{S}_{t-1} + \\phi(\\mathbf{k}_t)\\otimes\\mathbf{v}_t,\n\\quad \n\\mathbf{z}_t = \\mathbf{z}_{t-1} + \\phi(\\mathbf{k}_t)\n\\end{aligned}\n$$\nwhere $2D$ is the size of $\\phi(.)$ and $D$ should be no less than the model size $d$ for reasonable approximation.\nRFA leads to significant speedup in autoregressive decoding and the memory complexity mainly depends on the choice of $D$ when constructing the kernel $\\phi(.)$.\nPerformer modifies the random feature attention with positive random feature maps to reduce the estimation error. It also keeps the randomly sampled $\\mathbf{w}_1, \\dots, \\mathbf{w}_D$ to be orthogonal to further reduce the variance of the estimator.\nComparison of approximation error when using (Left) i.i.d vs orthogonal features and (Right) sin/cos vs positive random features. (Image source:\nChoromanski et al. 2021\n).\nTransformers for Reinforcement Learning\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nDecision Transformer\n(\nDT\n;\nChen et al 2021\n) formulates Reinforcement Learning problems as a process of\nconditional sequence modeling\n, outputting the optimal actions conditioned on the desired return, past states and actions. It therefore becomes straightforward to use Transformer architecture. Decision Transformer is for\noff-policy RL\n, where the model only has access to a fixed collection of trajectories collected by other policies.\nTo encourage the model to learn how to act in order to achieve a desired return, it feeds the model with desired future return $\\hat{R} = \\sum_{t’=t}^T r_{t’}$ instead of the current reward. The trajectory consists of a list of triplets, (return-to-go $\\hat{R}_t, state $s_t$, action $a_t$), and it is used as an input sequence for Transformer:\n$$\n\\tau = (\\hat{R}_1, s_1, a_1, \\hat{R}_2, s_2, a_2, \\dots, \\hat{R}_T, s_T, a_T)\n$$\nThree linear layers are added and trained for return-to-go, state and action respectively to extract token embeddings. The prediction head learns to predict $a_t$ corresponding to the input token $s_t$. The training uses cross-entropy loss for discrete actions or MSE for continuous actions. Predicting the states or return-to-go was not found to help improve the performance in their experiments.\nThe experiments compared DT with several model-free RL algorithm baselines and showed that:\nDT is more efficient than behavior cloning in low data regime;\nDT can model the distribution of returns very well;\nHaving a long context is crucial for obtaining good results;\nDT can work with sparse rewards.\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2023). The transformer family version 2.0. Lil’Log. https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/.\nOr\n@article{weng2023transformer,\n  title   = \"The Transformer Family Version 2.0\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2023\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/\"\n}\nReferences\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).\n[13] Rae et al.\n“Compressive Transformers for Long-Range Sequence Modelling.”\n2019.\n[14] Press et al.\n“Train Short, Test Long: Attention With Linear Biases Enables Input Length Extrapolation.”\nICLR 2022.\n[15] Wu, et al.\n“DA-Transformer: Distance Aware Transformer”\n2021.\n[16] Elabyad et al.\n“Depth-Adaptive Transformer.”\nICLR 2020.\n[17] Schuster et al.\n“Confident Adaptive Language Modeling”\n2022.\n[18] Qiu et al.\n“Blockwise self-attention for long document understanding”\n2019\n[19] Roy et al.\n“Efficient Content-Based Sparse Attention with Routing Transformers.”\n2021.\n[20] Ainslie et al.\n“ETC: Encoding Long and Structured Inputs in Transformers.”\nEMNLP 2019.\n[21] Beltagy et al.\n“Longformer: The long-document transformer.”\n2020.\n[22] Zaheer et al.\n“Big Bird: Transformers for Longer Sequences.”\n2020.\n[23] Wang et al.\n“Linformer: Self-Attention with Linear Complexity.”\narXiv preprint arXiv:2006.04768 (2020).\n[24] Tay et al. 2020\n“Sparse Sinkhorn Attention.”\nICML 2020.\n[25] Peng et al.\n“Random Feature Attention.”\nICLR 2021.\n[26] Choromanski et al.\n“Rethinking Attention with Performers.”\nICLR 2021.\n[27] Khandelwal et al.\n“Generalization through memorization: Nearest neighbor language models.”\nICLR 2020.\n[28] Yogatama et al.\n“Adaptive semiparametric language models.”\nACL 2021.\n[29] Wu et al.\n“Memorizing Transformers.”\nICLR 2022.\n[30] Su et al.\n“Roformer: Enhanced transformer with rotary position embedding.”\narXiv preprint arXiv:2104.09864 (2021).\n[31] Shaw et al.\n“Self-attention with relative position representations.”\narXiv preprint arXiv:1803.02155 (2018).\n[32] Tay et al.\n“Efficient Transformers: A Survey.”\nACM Computing Surveys 55.6 (2022): 1-28.\n[33] Chen et al.,\n“Decision Transformer: Reinforcement Learning via Sequence Modeling”\narXiv preprint arXiv:2106.01345 (2021).",
            "metadata": {
              "title": "The Transformer Family Version 2.0 | Lil'Log",
              "description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "keywords": "architecture, attention, transformer, foundation, long-read, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family Version 2.0",
              "og:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family Version 2.0",
              "twitter:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "article:section": "posts",
              "article:published_time": "2023-01-27T00:00:00+00:00",
              "article:modified_time": "2023-01-27T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bd2a1c61491f/code/body-000.txt",
                "chars": 272,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-cfd86d1d041d4e587dd2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-57e8505d379090b6a5c2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-eb72333120a9bf61db22.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "bytes": 517373,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-94806f3485ee4c7d4137.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-10c3f7a4432b939f41e9.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "bytes": 110695,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9af813630ff27b91e9f8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "bytes": 104844,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-2d52fb35835b8ffb9f5c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "bytes": 441748,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-b512db56c30433d4c252.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "bytes": 81702,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-701853184c4d260333df.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "bytes": 75150,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-440b77c01199a8fa47a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "bytes": 308982,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-321a0b363e9a6d1aa98b.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-65f1b4ee283f16066c80.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f6d1acbfbe9a2ebc5720.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-6801941ec960782dbcdd.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-aa7a4901bbb57ffba3a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "bytes": 144593,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-61300c84161edec245ef.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-e33cbf677e130ee48f58.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f5d3b8b9ebc8beb78c77.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "bytes": 135708,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-30a7b1c7f2d502623782.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-528e7d446bed9aeb5917.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-08fa8454100a632db05c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "bytes": 296726,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-5fade868b98da3fc740e.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "bytes": 150541,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-1864a0421abec41db939.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "bytes": 300912,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9bbffc5733b6530c7240.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-8ed5854240a34aa93f46.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "“The Transformer Family”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02155",
                "label": "Shaw et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.09864",
                "label": "Su et al. 2021",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Rotation_matrix",
                "label": "rotation matrix",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05507",
                "label": "Rae et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00172",
                "label": "Khandelwal et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research/google-research/tree/master/scann",
                "label": "ScaNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2102.02557",
                "label": "Yogatama et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2203.08913",
                "label": "Wu et al. 2022",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2021.naacl-main.166",
                "label": "Wu, et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2108.12409",
                "label": "Press et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar et al (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10073",
                "label": "Elabyad et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2207.07061",
                "label": "Schuster et al. 2022",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dirac_delta_function",
                "label": "dirac delta",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2110.01052",
                "label": "Angelopoulos et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.06732",
                "label": "Tay et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
                "label": "techniques for scaling up model training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.02972",
                "label": "Qiu et al. 2019",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2020.emnlp-main.19/",
                "label": "Ainslie et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004/05150",
                "label": "Beltagy et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.14062",
                "label": "Zaheer et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "NCE loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_graph",
                "label": "directed graph",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Random_graph",
                "label": "random graph",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.05997",
                "label": "Roy et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.04768",
                "label": "Wang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.02143",
                "label": "Peng et al. 2021",
                "type": "a"
              },
              {
                "href": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "label": "Rahimi & Recht, 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.14794",
                "label": "Choromanski et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2106.01345",
                "label": "Chen et al 2021",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "off-policy RL",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.11296",
                "label": "“Sparse Sinkhorn Attention.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:12Z",
            "source_url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": false,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": false,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02155",
                "bytes": 235373,
                "reused": false,
                "local_path": "papers/repair/f32df5aeac8714d373be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": false,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.09864",
                "bytes": 599289,
                "reused": true,
                "local_path": "papers/repair/b64aa8c5e278403b64ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05507",
                "bytes": 584093,
                "reused": false,
                "local_path": "papers/repair/244ccad8664efd18e77c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00172",
                "bytes": 451453,
                "reused": false,
                "local_path": "papers/repair/43f160fbf0fa81d77393.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2102.02557",
                "bytes": 1018474,
                "reused": false,
                "local_path": "papers/repair/b5c9e91bd79c1b9ef250.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2203.08913",
                "bytes": 1047591,
                "reused": false,
                "local_path": "papers/repair/691204beb9e3b5b17a09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2108.12409",
                "bytes": 759030,
                "reused": true,
                "local_path": "papers/repair/238b286ab4f338940590.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": false,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": false,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": false,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10073",
                "bytes": 480824,
                "reused": false,
                "local_path": "papers/repair/929832372275e4ca6acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2207.07061",
                "bytes": 3006455,
                "reused": false,
                "local_path": "papers/repair/3e493b8dcc10d3f89436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2110.01052",
                "bytes": 2934353,
                "reused": false,
                "local_path": "papers/repair/f48952de2c7830ad0fc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.06732",
                "bytes": 847824,
                "reused": true,
                "local_path": "papers/repair/5442c18a5d3ec7c8eca5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": false,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": false,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.02972",
                "bytes": 716586,
                "reused": false,
                "local_path": "papers/repair/e8d64283562a841b64f9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/2004/05150",
                "retried_at": "2026-10-20T18:03:23Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.14062",
                "bytes": 1153823,
                "reused": false,
                "local_path": "papers/repair/f56d7d4a1317893ab3ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": false,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": false,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.05997",
                "bytes": 727287,
                "reused": false,
                "local_path": "papers/repair/d2f0607b565e49aa10fe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.04768",
                "bytes": 922879,
                "reused": false,
                "local_path": "papers/repair/f20cd0da3a7534f96d1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.02143",
                "bytes": 1241988,
                "reused": false,
                "local_path": "papers/repair/e438f2e0a286bcd79311.pdf"
              },
              {
                "status": "ok",
                "url": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "bytes": 488453,
                "reused": false,
                "local_path": "papers/repair/38e94b7d3685dc5b22d9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.14794",
                "bytes": 5880177,
                "reused": true,
                "local_path": "papers/repair/26948568ccf004004970.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": false,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": false,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2106.01345",
                "bytes": 704784,
                "reused": false,
                "local_path": "papers/repair/9e056437cb3e5b4f695d.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": false,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.11296",
                "bytes": 450138,
                "reused": true,
                "local_path": "papers/repair/0008d87e3417535c824a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 68430,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/bd2a1c61491f/pages/source.html",
            "local_html": "attachments/bd2a1c61491f/pages/article.html",
            "body_base_path": "attachments/bd2a1c61491f/pages/",
            "body_markdown_path": "attachments/bd2a1c61491f/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
          "status": "partial",
          "article_id": "ebc73787cbe5",
          "local_path": "series-follow/1600/repair/ffba49f79f0eef15a925.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
              "bytes": 259350,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/394ec3f8b6a6ccc3dace.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
              "bytes": 205392,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9c60abbe659d28457d7a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
              "bytes": 275060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a8004105b4a88c05a952.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
              "bytes": 581593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7bc12620d13d41e17f0a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
              "bytes": 215084,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a1617c1aadd4262ae84a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
              "bytes": 181566,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/01ca9a7ea1e7d1cd82a2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
              "bytes": 294810,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a362a645159f0dafa82d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
              "bytes": 860130,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/fafbbe0c69813ea86bf2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
              "bytes": 742699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/d58e26716f1f269dae8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
              "bytes": 300409,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5e0d3d90650b6cca848e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
              "bytes": 497568,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a29af53d479214903180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
              "bytes": 332210,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/0061164751ee7e193a70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
              "bytes": 253972,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/58ac4a854eb578c151aa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
              "bytes": 567524,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/6b398117113938e66d50.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Policy Gradient Algorithms",
            "keywords": "策略梯度,PG,强化学习",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "publish_date": "2018-04",
            "corpus_stage": "强化学习/对齐",
            "notes": "策略梯度算法大全（REINFORCE、PPO等）",
            "id": "ebc73787cbe5",
            "collected_at": "2026-10-02T14:13:21",
            "title": "Policy Gradient Algorithms | Lil'Log",
            "body_markdown": "[Updated on 2018-06-30: add two new policy gradient methods,\nSAC\nand\nD4PG\n.]\n[Updated on 2018-09-30: add a new policy gradient method,\nTD3\n.]\n[Updated on 2019-02-09: add\nSAC with automatically adjusted temperature\n].\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in\nKorean\n].\n[Updated on 2019-09-12: add a new policy gradient method\nSVPG\n.]\n[Updated on 2019-12-22: add a new policy gradient method\nIMPALA\n.]\n[Updated on 2020-10-15: add a new policy gradient method\nPPG\n& some new discussion in\nPPO\n.]\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in\nChinese1\n&\nChinese2\n].\nWhat is Policy Gradient\n#\nPolicy gradient is an approach to solve reinforcement learning problems. If you haven’t looked into the field of reinforcement learning, please first read the section\n“A (Long) Peek into Reinforcement Learning » Key Concepts”\nfor the problem definition and key concepts.\nNotations\n#\nHere is a list of notations to help you read through equations in the post easily.\nSymbol\nMeaning\n$s \\in \\mathcal{S}$\nStates.\n$a \\in \\mathcal{A}$\nActions.\n$r \\in \\mathcal{R}$\nRewards.\n$S_t, A_t, R_t$\nState, action, and reward at time step $t$ of one trajectory. I may occasionally use $s_t, a_t, r_t$ as well.\n$\\gamma$\nDiscount factor; penalty to uncertainty of future rewards; $0<\\gamma \\leq 1$.\n$G_t$\nReturn; or discounted future reward; $G_t = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}$.\n$P(s’, r \\vert s, a)$\nTransition probability of getting to the next state $s’$ from the current state $s$ with action $a$ and reward $r$.\n$\\pi(a \\vert s)$\nStochastic policy (agent behavior strategy); $\\pi_\\theta(.)$ is a policy parameterized by $\\theta$.\n$\\mu(s)$\nDeterministic policy; we can also label this as $\\pi(s)$, but using a different letter gives better distinction so that we can easily tell when the policy is stochastic or deterministic without further explanation. Either $\\pi$ or $\\mu$ is what a reinforcement learning algorithm aims to learn.\n$V(s)$\nState-value function measures the expected return of state $s$; $V_w(.)$ is a value function parameterized by $w$.\n$V^\\pi(s)$\nThe value of state $s$ when we follow a policy $\\pi$; $V^\\pi (s) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s]$.\n$Q(s, a)$\nAction-value function is similar to $V(s)$, but it assesses the expected return of a pair of state and action $(s, a)$; $Q_w(.)$ is a action value function parameterized by $w$.\n$Q^\\pi(s, a)$\nSimilar to $V^\\pi(.)$, the value of (state, action) pair when we follow a policy $\\pi$; $Q^\\pi(s, a) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s, A_t = a]$.\n$A(s, a)$\nAdvantage function, $A(s, a) = Q(s, a) - V(s)$; it can be considered as another version of Q-value with lower variance by taking the state-value off as the baseline.\nPolicy Gradient\n#\nThe goal of reinforcement learning is to find an optimal behavior strategy for the agent to obtain optimal rewards. The\npolicy gradient\nmethods target at modeling and optimizing the policy directly. The policy is usually modeled with a parameterized function respect to $\\theta$, $\\pi_\\theta(a \\vert s)$. The value of the reward (objective) function depends on this policy and then various algorithms can be applied to optimize $\\theta$ for the best reward.\nThe reward function is defined as:\n$$\nJ(\\theta) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) V^\\pi(s) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a)\n$$\nwhere $d^\\pi(s)$ is the stationary distribution of Markov chain for $\\pi_\\theta$ (on-policy state distribution under $\\pi$). For simplicity, the parameter $\\theta$ would be omitted for the policy $\\pi_\\theta$ when the policy is present in the subscript of other functions; for example, $d^{\\pi}$ and $Q^\\pi$ should be $d^{\\pi_\\theta}$ and $Q^{\\pi_\\theta}$ if written in full.\nImagine that you can travel along the Markov chain’s states forever, and eventually, as the time progresses, the probability of you ending up with one state becomes unchanged — this is the stationary probability for $\\pi_\\theta$. $d^\\pi(s) = \\lim_{t \\to \\infty} P(s_t = s \\vert s_0, \\pi_\\theta)$ is the probability that $s_t=s$ when starting from $s_0$ and following policy $\\pi_\\theta$ for t steps. Actually, the existence of the stationary distribution of Markov chain is one main reason for why PageRank algorithm works. If you want to read more, check\nthis\n.\nIt is natural to expect policy-based methods are more useful in the continuous space. Because there is an infinite number of actions and (or) states to estimate the values for and hence value-based approaches are way too expensive computationally in the continuous space. For example, in\ngeneralized policy iteration\n, the policy improvement step $\\arg\\max_{a \\in \\mathcal{A}} Q^\\pi(s, a)$ requires a full scan of the action space, suffering from the\ncurse of dimensionality\n.\nUsing\ngradient ascent\n, we can move $\\theta$ toward the direction suggested by the gradient $\\nabla_\\theta J(\\theta)$ to find the best $\\theta$ for $\\pi_\\theta$ that produces the highest return.\nPolicy Gradient Theorem\n#\nComputing the gradient $\\nabla_\\theta J(\\theta)$ is tricky because it depends on both the action selection (directly determined by $\\pi_\\theta$) and the stationary distribution of states following the target selection behavior (indirectly determined by $\\pi_\\theta$). Given that the environment is generally unknown, it is difficult to estimate the effect on the state distribution by a policy update.\nLuckily, the\npolicy gradient theorem\ncomes to save the world! Woohoo! It provides a nice reformation of the derivative of the objective function to not involve the derivative of the state distribution $d^\\pi(.)$ and simplify the gradient computation $\\nabla_\\theta J(\\theta)$ a lot.\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\nabla_\\theta \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\\\\n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \n\\end{aligned}\n$$\nProof of Policy Gradient Theorem\n#\nThis session is pretty dense, as it is the time for us to go through the proof (\nSutton & Barto, 2017\n; Sec. 13.1) and figure out why the policy gradient theorem is correct.\nWe first start with the derivative of the state value function:\n$$\n\\begin{aligned}\n& \\nabla_\\theta V^\\pi(s) \\\\\n=& \\nabla_\\theta \\Big(\\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s)Q^\\pi(s, a) \\Big) & \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta Q^\\pi(s, a)} \\Big) & \\scriptstyle{\\text{; Derivative product rule.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta \\sum_{s', r} P(s',r \\vert s,a)(r + V^\\pi(s'))} \\Big) & \\scriptstyle{\\text{; Extend } Q^\\pi \\text{ with future state value.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s', r} P(s',r \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{P(s',r \\vert s,a) \\text{ or } r \\text{ is not a func of }\\theta}\\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s'} P(s' \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{\\text{; Because }  P(s' \\vert s, a) = \\sum_r P(s', r \\vert s, a)}\n\\end{aligned}\n$$\nNow we have:\n$$\n\\color{red}{\\nabla_\\theta V^\\pi(s)} \n= \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\Big)\n$$\nThis equation has a nice recursive form (see the red parts!) and the future state value function $V^\\pi(s’)$ can be repeated unrolled by following the same equation.\nLet’s consider the following visitation sequence and label the probability of transitioning from state s to state x with policy $\\pi_\\theta$ after k step as $\\rho^\\pi(s \\to x, k)$.\n$$\ns \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s)} s' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s')} s'' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s'')} \\dots\n$$\nWhen k = 0: $\\rho^\\pi(s \\to s, k=0) = 1$.\nWhen k = 1, we scan through all possible actions and sum up the transition probabilities to the target state: $\\rho^\\pi(s \\to s’, k=1) = \\sum_a \\pi_\\theta(a \\vert s) P(s’ \\vert s, a)$.\nImagine that the goal is to go from state s to x after k+1 steps while following policy $\\pi_\\theta$. We can first travel from s to a middle point s’ (any state can be a middle point, $s’ \\in \\mathcal{S}$) after k steps and then go to the final state x during the last step. In this way, we are able to update the visitation probability recursively: $\\rho^\\pi(s \\to x, k+1) = \\sum_{s’} \\rho^\\pi(s \\to s’, k) \\rho^\\pi(s’ \\to x, 1)$.\nThen we go back to unroll the recursive representation of $\\nabla_\\theta V^\\pi(s)$! Let $\\phi(s) = \\sum_{a \\in \\mathcal{A}} \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a)$ to simplify the maths. If we keep on extending $\\nabla_\\theta V^\\pi(.)$ infinitely, it is easy to find out that we can transition from the starting state s to any state after any number of steps in this unrolling process and by summing up all the visitation probabilities, we get $\\nabla_\\theta V^\\pi(s)$!\n$$\n\\begin{aligned}\n& \\color{red}{\\nabla_\\theta V^\\pi(s)} \\\\\n=& \\phi(s) + \\sum_a \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\sum_a \\pi_\\theta(a \\vert s) P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s')Q^\\pi(s', a) + \\pi_\\theta(a \\vert s') \\sum_{s'} P(s'' \\vert s',a) \\nabla_\\theta V^\\pi(s'') \\Big)} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{[ \\phi(s') + \\sum_{s''} \\rho^\\pi(s' \\to s'', 1) \\nabla_\\theta V^\\pi(s'')]} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\color{red}{\\nabla_\\theta V^\\pi(s'')} \\scriptstyle{\\text{ ; Consider }s'\\text{ as the middle point for }s \\to s''}\\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\phi(s'') + \\sum_{s'''} \\rho^\\pi(s \\to s''', 3)\\color{red}{\\nabla_\\theta V^\\pi(s''')} \\\\\n=& \\dots \\scriptstyle{\\text{; Repeatedly unrolling the part of }\\nabla_\\theta V^\\pi(.)} \\\\\n=& \\sum_{x\\in\\mathcal{S}}\\sum_{k=0}^\\infty \\rho^\\pi(s \\to x, k) \\phi(x)\n\\end{aligned}\n$$\nThe nice rewriting above allows us to exclude the derivative of Q-value function, $\\nabla_\\theta Q^\\pi(s, a)$. By plugging it into the objective function $J(\\theta)$, we are getting the following:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta V^\\pi(s_0) & \\scriptstyle{\\text{; Starting from a random state } s_0} \\\\\n&= \\sum_{s}\\color{blue}{\\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)} \\phi(s) &\\scriptstyle{\\text{; Let }\\color{blue}{\\eta(s) = \\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)}} \\\\\n&= \\sum_{s}\\eta(s) \\phi(s) & \\\\\n&= \\Big( {\\sum_s \\eta(s)} \\Big)\\sum_{s}\\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\text{; Normalize } \\eta(s), s\\in\\mathcal{S} \\text{ to be a probability distribution.}}\\\\\n&\\propto \\sum_s \\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\sum_s \\eta(s)\\text{  is a constant}} \\\\\n&= \\sum_s d^\\pi(s) \\sum_a \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) & \\scriptstyle{d^\\pi(s) = \\frac{\\eta(s)}{\\sum_s \\eta(s)}\\text{ is stationary distribution.}}\n\\end{aligned}\n$$\nIn the episodic case, the constant of proportionality ($\\sum_s \\eta(s)$) is the average length of an episode; in the continuing case, it is 1 (\nSutton & Barto, 2017\n; Sec. 13.2). The gradient can be further written as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s)  &\\\\\n&= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} &\\\\\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\scriptstyle{\\text{; Because } (\\ln x)' = 1/x}\n\\end{aligned}\n$$\nWhere $\\mathbb{E}_\\pi$ refers to $\\mathbb{E}_{s \\sim d_\\pi, a \\sim \\pi_\\theta}$ when both state and action distributions follow the policy $\\pi_\\theta$ (on policy).\nThe policy gradient theorem lays the theoretical foundation for various policy gradient algorithms. This vanilla policy gradient update has no bias but high variance. Many following algorithms were proposed to reduce the variance while keeping the bias unchanged.\n$$\n\\nabla_\\theta J(\\theta)  = \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)]\n$$\nHere is a nice summary of a general form of policy gradient methods borrowed from the\nGAE\n(general advantage estimation) paper (\nSchulman et al., 2016\n) and this\npost\nthoroughly discussed several components in GAE , highly recommended.\nA general form of policy gradient methods. (Image source:\nSchulman et al., 2016\n)\nPolicy Gradient Algorithms\n#\nTons of policy gradient algorithms have been proposed during recent years and there is no way for me to exhaust them. I’m introducing some of them that I happened to know and read about.\nREINFORCE\n#\nREINFORCE\n(Monte-Carlo policy gradient) relies on an estimated return by\nMonte-Carlo\nmethods using episode samples to update the policy parameter $\\theta$. REINFORCE works because the expectation of the sample gradient is equal to the actual gradient:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\\\\n&= \\mathbb{E}_\\pi [G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)] & \\scriptstyle{\\text{; Because } Q^\\pi(S_t, A_t) = \\mathbb{E}_\\pi[G_t \\vert S_t, A_t]}\n\\end{aligned}\n$$\nTherefore we are able to measure $G_t$ from real sample trajectories and use that to update our policy gradient. It relies on a full trajectory and that’s why it is a Monte-Carlo method.\nThe process is pretty straightforward:\nInitialize the policy parameter $\\theta$ at random.\nGenerate one trajectory on policy $\\pi_\\theta$: $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$.\nFor t=1, 2, … , T:\nEstimate the the return $G_t$;\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)$\nA widely used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to\nreduce the variance of gradient estimation while keeping the bias unchanged\n(Remember we always want to do this when possible). For example, a common baseline is to subtract state-value from action-value, and if applied, we would use advantage $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update. This\npost\nnicely explained why a baseline works for reducing the variance, in addition to a set of fundamentals of policy gradient.\nActor-Critic\n#\nTwo main components in policy gradient are the policy model and the value function. It makes a lot of sense to learn the value function in addition to the policy, since knowing the value function can assist the policy update, such as by reducing gradient variance in vanilla policy gradients, and that is exactly what the\nActor-Critic\nmethod does.\nActor-critic methods consist of two models, which may optionally share parameters:\nCritic\nupdates the value function parameters w and depending on the algorithm it could be action-value $Q_w(a \\vert s)$ or state-value $V_w(s)$.\nActor\nupdates the policy parameters $\\theta$ for $\\pi_\\theta(a \\vert s)$, in the direction suggested by the critic.\nLet’s see how it works in a simple action-value actor-critic algorithm.\nInitialize $s, \\theta, w$ at random; sample $a \\sim \\pi_\\theta(a \\vert s)$.\nFor $t = 1 \\dots T$:\nSample reward $r_t \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$;\nThen sample the next action $a’ \\sim \\pi_\\theta(a’ \\vert s’)$;\nUpdate the policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q_w(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)$;\nCompute the correction (TD error) for action-value at time t:\n$\\delta_t = r_t + \\gamma Q_w(s’, a’) - Q_w(s, a)$\nand use it to update the parameters of action-value function:\n$w \\leftarrow w + \\alpha_w \\delta_t \\nabla_w Q_w(s, a)$\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\nTwo learning rates, $\\alpha_\\theta$ and $\\alpha_w$, are predefined for policy and value function parameter updates respectively.\nOff-Policy Policy Gradient\n#\nBoth REINFORCE and the vanilla version of actor-critic method are on-policy: training samples are collected according to the target policy — the very same policy that we try to optimize for. Off policy methods, however, result in several additional advantages:\nThe off-policy approach does not require full trajectories and can reuse any past episodes (\n“experience replay”\n) for much better sample efficiency.\nThe sample collection follows a behavior policy different from the target policy, bringing better\nexploration\n.\nNow let’s see how off-policy policy gradient is computed. The behavior policy for collecting samples is a known policy (predefined just like a hyperparameter), labelled as $\\beta(a \\vert s)$. The objective function sums up the reward over the state distribution defined by this behavior policy:\n$$\nJ(\\theta)\n= \\sum_{s \\in \\mathcal{S}} d^\\beta(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)\n= \\mathbb{E}_{s \\sim d^\\beta} \\big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\big]\n$$\nwhere $d^\\beta(s)$ is the stationary distribution of the behavior policy $\\beta$; recall that $d^\\beta(s) = \\lim_{t \\to \\infty} P(S_t = s \\vert S_0, \\beta)$; and $Q^\\pi$ is the action-value function estimated with regard to the target policy $\\pi$ (not the behavior policy!).\nGiven that the training observations are sampled by $a \\sim \\beta(a \\vert s)$, we can rewrite the gradient as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)  \\Big] & \\\\ \n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\big( Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) + \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)} \\big) \\Big] & \\scriptstyle{\\text{; Derivative product rule.}}\\\\\n&\\stackrel{(i)}{\\approx} \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; Ignore the red part: } \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)}}. \\\\\n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} \\Big] & \\\\\n&= \\mathbb{E}_\\beta \\Big[\\frac{\\color{blue}{\\pi_\\theta(a \\vert s)}}{\\color{blue}{\\beta(a \\vert s)}} Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; The blue part is the importance weight.}}\n\\end{aligned}\n$$\nwhere $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$ is the\nimportance weight\n. Because $Q^\\pi$ is a function of the target policy and thus a function of policy parameter $\\theta$,  we should take the derivative of $\\nabla_\\theta Q^\\pi(s, a)$ as well according to the product rule. However, it is super hard to compute $\\nabla_\\theta Q^\\pi(s, a)$ in reality. Fortunately if we use an approximated gradient with the gradient of Q ignored, we still guarantee the policy improvement and eventually achieve the true local minimum. This is justified in the proof\nhere\n(Degris, White & Sutton, 2012).\nIn summary, when applying policy gradient in the off-policy setting, we can simple adjust it with a weighted sum and the weight is the ratio of the target policy to the behavior policy, $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$.\nA3C\n#\n[\npaper\n|\ncode\n]\nAsynchronous Advantage Actor-Critic\n(\nMnih et al., 2016\n), short for\nA3C\n, is a classic policy gradient method with a special focus on parallel training.\nIn A3C, the critics learn the value function while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is designed to work well for parallel training.\nLet’s use the state-value function as an example. The loss function for state value is to minimize the mean squared error, $J_v(w) = (G_t - V_w(s))^2$ and gradient descent can be applied to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, $\\theta$ and $w$; similar thread-specific parameters, $\\theta’$ and $w’$.\nInitialize the time step $t = 1$\nWhile $T \\leq T_\\text{MAX}$:\nReset gradient: $\\mathrm{d}\\theta = 0$ and $\\mathrm{d}w = 0$.\nSynchronize thread-specific parameters with global ones: $\\theta’ = \\theta$ and $w’ = w$.\n$t_\\text{start}$ = t and sample a starting state $s_t$.\nWhile ($s_t$ != TERMINAL) and $t - t_\\text{start} \\leq t_\\text{max}$:\nPick the action $A_t \\sim \\pi_{\\theta’}(A_t \\vert S_t)$ and receive a new reward $R_t$ and a new state $s_{t+1}$.\nUpdate $t = t + 1$ and $T = T + 1$\nInitialize the variable that holds the return estimation\n$$\n R = \\begin{cases} \n 0 & \\text{if } s_t \\text{ is TERMINAL} \\\\\n V_{w'}(s_t) & \\text{otherwise}\n \\end{cases}\n $$\n6. For $i = t-1, \\dots, t\\_\\text{start}$:\n     1. $R \\leftarrow \\gamma R + R\\_i$; here R is a MC measure of $G\\_i$.\n     2. Accumulate gradients w.r.t. $\\theta'$: $d\\theta \\leftarrow d\\theta + \\nabla\\_{\\theta'} \\log \\pi\\_{\\theta'}(a\\_i \\vert s\\_i)(R - V\\_{w'}(s\\_i))$;\nAccumulate gradients w.r.t. w': $dw \\leftarrow dw + 2 (R - V\\_{w'}(s\\_i)) \\nabla\\_{w'} (R - V\\_{w'}(s\\_i))$.\nUpdate asynchronously $\\theta$ using $\\mathrm{d}\\theta$, and $w$ using $\\mathrm{d}w$.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a parallelized reformation of minibatch-based stochastic gradient update: the values of $w$ or $\\theta$ get corrected by a little bit in the direction of each training thread independently.\nA2C\n#\n[\npaper\n|\ncode\n]\nA2C\nis a synchronous, deterministic version of A3C; that’s why it is named as “A2C” with the first “A” (“asynchronous”) removed. In A3C each agent talks to the global parameters independently, so it is possible sometimes the thread-specific agents would be playing with policies of different versions and therefore the aggregated update would not be optimal. To resolve the inconsistency, a coordinator in A2C waits for all the parallel actors to finish their work before updating the global parameters and then in the next iteration parallel actors starts from the same policy. The synchronized gradient update keeps the training more cohesive and potentially to make convergence faster.\nA2C has been\nshown\nto be able to utilize GPUs more efficiently and work better with large batch sizes while achieving same or better performance than A3C.\nThe architecture of A3C versus A2C.\nDPG\n#\n[\npaper\n|code]\nIn methods described above, the policy function $\\pi(. \\vert s)$ is always modeled as a probability distribution over actions $\\mathcal{A}$ given the current state and thus it is\nstochastic\n.\nDeterministic policy gradient (DPG)\ninstead models the policy as a deterministic decision: $a = \\mu(s)$. It may look bizarre — how can you calculate the gradient of the action probability when it outputs a single action? Let’s look into it step by step.\nRefresh on a few notations to facilitate the discussion:\n$\\rho_0(s)$: The initial distribution over states\n$\\rho^\\mu(s \\to s’, k)$: Starting from state s, the visitation probability density at state s’ after moving k steps by policy $\\mu$.\n$\\rho^\\mu(s’)$: Discounted state distribution, defined as $\\rho^\\mu(s’) = \\int_\\mathcal{S} \\sum_{k=1}^\\infty \\gamma^{k-1} \\rho_0(s) \\rho^\\mu(s \\to s’, k) ds$.\nThe objective function to optimize for is listed as follows:\n$$\nJ(\\theta) = \\int_\\mathcal{S} \\rho^\\mu(s) Q(s, \\mu_\\theta(s)) ds\n$$\nDeterministic policy gradient theorem\n: Now it is the time to compute the gradient! According to the chain rule, we first take the gradient of Q w.r.t. the action a and then take the gradient of the deterministic policy function $\\mu$ w.r.t. $\\theta$:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\int_\\mathcal{S} \\rho^\\mu(s) \\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)} ds \\\\\n&= \\mathbb{E}_{s \\sim \\rho^\\mu} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}]\n\\end{aligned}\n$$\nWe can consider the deterministic policy as a\nspecial case\nof the stochastic one, when the probability distribution contains only one extreme non-zero value over one action. Actually, in the DPG\npaper\n, the authors have shown that if the stochastic policy $\\pi_{\\mu_\\theta, \\sigma}$ is re-parameterized by a deterministic policy $\\mu_\\theta$ and a variation variable $\\sigma$, the stochastic policy is eventually equivalent to the deterministic case when $\\sigma=0$. Compared to the deterministic policy, we expect the stochastic policy to require more samples as it integrates the data over the whole state and action space.\nThe deterministic policy gradient theorem can be plugged into common policy gradient frameworks.\nLet’s consider an example of on-policy actor-critic algorithm to showcase the procedure. In each iteration of on-policy actor-critic, two actions are taken deterministically $a = \\mu_\\theta(s)$ and the\nSARSA\nupdate on policy parameters relies on the new gradient that we just computed above:\n$$\n\\begin{aligned}\n\\delta_t &= R_t + \\gamma Q_w(s_{t+1}, a_{t+1}) - Q_w(s_t, a_t) & \\small{\\text{; TD error in SARSA}}\\\\\nw_{t+1} &= w_t + \\alpha_w \\delta_t \\nabla_w Q_w(s_t, a_t) & \\\\\n\\theta_{t+1} &= \\theta_t + \\alpha_\\theta \\color{red}{\\nabla_a Q_w(s_t, a_t) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}} & \\small{\\text{; Deterministic policy gradient theorem}}\n\\end{aligned}\n$$\nHowever, unless there is sufficient noise in the environment, it is very hard to guarantee enough\nexploration\ndue to the determinacy of the policy. We can either add noise into the policy (ironically this makes it nondeterministic!) or learn it off-policy-ly by following a different stochastic behavior policy to collect samples.\nSay, in the off-policy approach, the training trajectories are generated by a stochastic policy $\\beta(a \\vert s)$ and thus the state distribution follows the corresponding discounted state density $\\rho^\\beta$:\n$$\n\\begin{aligned}\nJ_\\beta(\\theta) &= \\int_\\mathcal{S} \\rho^\\beta Q^\\mu(s, \\mu_\\theta(s)) ds \\\\\n\\nabla_\\theta J_\\beta(\\theta) &= \\mathbb{E}_{s \\sim \\rho^\\beta} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s)  \\rvert_{a=\\mu_\\theta(s)} ]\n\\end{aligned}\n$$\nNote that because the policy is deterministic, we only need $Q^\\mu(s, \\mu_\\theta(s))$ rather than $\\sum_a \\pi(a \\vert s) Q^\\pi(s, a)$ as the estimated reward of a given state s.\nIn the off-policy approach with a stochastic policy, importance sampling is often used to correct the mismatch between behavior and target policies, as what we have described\nabove\n. However, because the deterministic policy gradient removes the integral over actions, we can avoid importance sampling.\nDDPG\n#\n[\npaper\n|\ncode\n]\nDDPG\n(\nLillicrap, et al., 2015\n), short for\nDeep Deterministic Policy Gradient\n, is a model-free off-policy actor-critic algorithm, combining\nDPG\nwith\nDQN\n. Recall that DQN (Deep Q-Network) stabilizes the learning of Q-function by experience replay and the frozen target network. The original DQN works in discrete space, and DDPG extends it to continuous space with the actor-critic framework while learning a deterministic policy.\nIn order to do better exploration, an exploration policy $\\mu’$ is constructed by adding noise $\\mathcal{N}$:\n$$\n\\mu'(s) = \\mu_\\theta(s) + \\mathcal{N}\n$$\nIn addition, DDPG does soft updates (“conservative policy iteration”) on the parameters of both actor and critic, with $\\tau \\ll 1$: $\\theta’ \\leftarrow \\tau \\theta + (1 - \\tau) \\theta’$. In this way, the target network values are constrained to change slowly, different from the design in DQN that the target network stays frozen for some period of time.\nOne detail in the paper that is particularly useful in robotics is on how to normalize the different physical units of low dimensional features. For example, a model is designed to learn a policy with the robot’s positions and velocities as input; these physical statistics are different by nature and even statistics of the same type may vary a lot across multiple robots.\nBatch normalization\nis applied to fix it by normalizing every dimension across samples in one minibatch.\nFig 3. DDPG Algorithm. (Image source:\nLillicrap, et al., 2015\n)\nD4PG\n#\n[\npaper\n|code (Search “github d4pg” and you will see a few.)]\nDistributed Distributional DDPG (D4PG)\napplies a set of improvements on DDPG to make it run in the distributional fashion.\n(1)\nDistributional Critic\n: The critic estimates the expected Q value as a random variable ~ a distribution $Z_w$ parameterized by $w$ and therefore $Q_w(s, a) = \\mathbb{E} Z_w(x, a)$. The loss for learning the distribution parameter is to minimize some measure of the distance between two distributions — distributional TD error: $L(w) = \\mathbb{E}[d(\\mathcal{T}_{\\mu_\\theta}, Z_{w’}(s, a), Z_w(s, a)]$, where $\\mathcal{T}_{\\mu_\\theta}$ is the Bellman operator.\nThe deterministic policy gradient update becomes:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\approx \\mathbb{E}_{\\rho^\\mu} [\\nabla_a Q_w(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; gradient update in DPG}} \\\\\n&= \\mathbb{E}_{\\rho^\\mu} [\\mathbb{E}[\\nabla_a Z_w(s, a)] \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; expectation of the Q-value distribution.}}\n\\end{aligned}\n$$\n(2)\n$N$-step returns\n: When calculating the TD error, D4PG computes $N$-step TD target rather than one-step to incorporate rewards in more future steps. Thus the new TD target is:\n$$\nr(s_0, a_0) + \\mathbb{E}[\\sum_{n=1}^{N-1} r(s_n, a_n) + \\gamma^N Q(s_N, \\mu_\\theta(s_N)) \\vert s_0, a_0 ]\n$$\n(3)\nMultiple Distributed Parallel Actors\n: D4PG utilizes $K$ independent actors, gathering experience in parallel and feeding data into the same replay buffer.\n(4)\nPrioritized Experience Replay (\nPER\n)\n: The last piece of modification is to do sampling from the replay buffer of size $R$ with an non-uniform probability $p_i$. In this way, a sample $i$ has the probability $(Rp_i)^{-1}$ to be selected and thus the importance weight is $(Rp_i)^{-1}$.\nD4PG algorithm (Image source:\nBarth-Maron, et al. 2018\n); Note that in the original paper, the variable letters are chosen slightly differently from what in the post; i.e. I use $\\mu(.)$ for representing a deterministic policy instead of $\\pi(.)$.\nMADDPG\n#\n[\npaper\n|\ncode\n]\nMulti-agent DDPG\n(\nMADDPG\n) (\nLowe et al., 2017\n) extends DDPG to an environment where multiple agents are coordinating to complete tasks with only local information. In the viewpoint of one agent, the environment is non-stationary as policies of other agents are quickly upgraded and remain unknown. MADDPG is an actor-critic model redesigned particularly for handling such a changing environment and interactions between agents.\nThe problem can be formalized in the multi-agent version of MDP, also known as\nMarkov games\n. MADDPG is proposed for partially observable Markov games. Say, there are N agents in total with a set of states $\\mathcal{S}$. Each agent owns a set of possible action, $\\mathcal{A}_1, \\dots, \\mathcal{A}_N$, and a set of observation, $\\mathcal{O}_1, \\dots, \\mathcal{O}_N$. The state transition function involves all states, action and observation spaces  $\\mathcal{T}: \\mathcal{S} \\times \\mathcal{A}_1 \\times \\dots \\mathcal{A}_N \\mapsto \\mathcal{S}$. Each agent’s stochastic policy only involves its own state and action: $\\pi_{\\theta_i}: \\mathcal{O}_i \\times \\mathcal{A}_i \\mapsto [0, 1]$, a probability distribution over actions given its own observation, or a deterministic policy: $\\mu_{\\theta_i}: \\mathcal{O}_i \\mapsto \\mathcal{A}_i$.\nLet $\\vec{o} = {o_1, \\dots, o_N}$, $\\vec{\\mu} = {\\mu_1, \\dots, \\mu_N}$ and the policies are parameterized by $\\vec{\\theta} = {\\theta_1, \\dots, \\theta_N}$.\nThe critic in MADDPG learns a centralized action-value function $Q^\\vec{\\mu}_i(\\vec{o}, a_1, \\dots, a_N)$ for the i-th agent, where $a_1 \\in \\mathcal{A}_1, \\dots, a_N \\in \\mathcal{A}_N$ are actions of all agents. Each $Q^\\vec{\\mu}_i$ is learned separately for $i=1, \\dots, N$ and therefore multiple agents can have arbitrary reward structures, including conflicting rewards in a competitive setting. Meanwhile, multiple actors, one for each agent, are exploring and upgrading the policy parameters $\\theta_i$ on their own.\nActor update\n:\n$$\n\\nabla_{\\theta_i} J(\\theta_i) = \\mathbb{E}_{\\vec{o}, a \\sim \\mathcal{D}} [\\nabla_{a_i} Q^{\\vec{\\mu}}_i (\\vec{o}, a_1, \\dots, a_N) \\nabla_{\\theta_i} \\mu_{\\theta_i}(o_i) \\rvert_{a_i=\\mu_{\\theta_i}(o_i)} ]\n$$\nWhere $\\mathcal{D}$ is the memory buffer for experience replay, containing multiple episode samples $(\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}’)$ — given current observation $\\vec{o}$, agents take action $a_1, \\dots, a_N$ and get rewards $r_1, \\dots, r_N$, leading to the new observation $\\vec{o}’$.\nCritic update\n:\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta_i) &= \\mathbb{E}_{\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}'}[ (Q^{\\vec{\\mu}}_i(\\vec{o}, a_1, \\dots, a_N) - y)^2 ] & \\\\\n\\text{where } y &= r_i + \\gamma Q^{\\vec{\\mu}'}_i (\\vec{o}', a'_1, \\dots, a'_N) \\rvert_{a'_j = \\mu'_{\\theta_j}} & \\scriptstyle{\\text{; TD target!}}\n\\end{aligned}\n$$\nwhere $\\vec{\\mu}’$ are the target policies with delayed softly-updated parameters.\nIf the policies $\\vec{\\mu}$ are unknown during the critic update, we can ask each agent to learn and evolve its own approximation of others’ policies. Using the approximated policies, MADDPG still can learn efficiently although the inferred policies might not be accurate.\nTo mitigate the high variance triggered by the interaction between competing or collaborating agents in the environment, MADDPG proposed one more element -\npolicy ensembles\n:\nTrain K policies for one agent;\nPick a random policy for episode rollouts;\nTake an ensemble of these K policies to do gradient update.\nIn summary, MADDPG added three additional ingredients on top of DDPG to make it adapt to the multi-agent environment:\nCentralized critic + decentralized actors;\nActors are able to use estimated policies of other agents for learning;\nPolicy ensembling is good for reducing variance.\nThe architecture design of MADDPG. (Image source:\nLowe et al., 2017\n)\nTRPO\n#\n[\npaper\n|\ncode\n]\nTo improve training stability, we should avoid parameter updates that change the policy too much at one step.\nTrust region policy optimization (TRPO)\n(\nSchulman, et al., 2015\n) carries out this idea by enforcing a\nKL divergence\nconstraint on the size of policy update at each iteration.\nConsider the case when we are doing off-policy RL, the policy $\\beta$ used for collecting trajectories on rollout workers is different from the policy $\\pi$ to optimize for. The objective function in an off-policy model measures the total advantage over the state visitation distribution and actions, while the mismatch between the training data distribution and the true policy state distribution is compensated by importance sampling estimator:\n$$\n\\begin{aligned}\nJ(\\theta)\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\pi_\\theta(a \\vert s) \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\\\\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\scriptstyle{\\text{; Importance sampling}} \\\\\n&= \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\beta} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big] &\n\\end{aligned}\n$$\nwhere $\\theta_\\text{old}$ is the policy parameters before the update and thus known to us; $\\rho^{\\pi_{\\theta_\\text{old}}}$ is defined in the same way as\nabove\n; $\\beta(a \\vert s)$ is the behavior policy for collecting trajectories. Noted that we use an estimated advantage $\\hat{A}(.)$ rather than the true advantage function $A(.)$ because the true rewards are usually unknown.\nWhen training on policy, theoretically the policy for collecting data is same as the policy that we want to optimize. However, when rollout workers and optimizers are running in parallel asynchronously, the behavior policy can get stale. TRPO considers this subtle difference: It labels the behavior policy as $\\pi_{\\theta_\\text{old}}(a \\vert s)$ and thus the objective function becomes:\n$$\nJ(\\theta) = \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\pi_{\\theta_\\text{old}}} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big]\n$$\nTRPO aims to maximize the objective function $J(\\theta)$ subject to,\ntrust region constraint\nwhich enforces the distance between old and new policies measured by\nKL-divergence\nto be small enough, within a parameter δ:\n$$\n\\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}} [D_\\text{KL}(\\pi_{\\theta_\\text{old}}(.\\vert s) \\| \\pi_\\theta(.\\vert s)] \\leq \\delta\n$$\nIn this way, the old and new policies would not diverge too much when this hard constraint is met. While still, TRPO can guarantee a monotonic improvement over policy iteration (Neat, right?). Please read the proof in the\npaper\nif interested :)\nPPO\n#\n[\npaper\n|\ncode\n]\nGiven that TRPO is relatively complicated and we still want to implement a similar constraint,\nproximal policy optimization (PPO)\nsimplifies it by using a clipped surrogate objective while retaining similar performance.\nFirst, let’s denote the probability ratio between old and new policies as:\n$$\nr(\\theta) = \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)}\n$$\nThen, the objective function of TRPO (on policy) becomes:\n$$\nJ^\\text{TRPO} (\\theta) = \\mathbb{E} [ r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a) ]\n$$\nWithout a limitation on the distance between $\\theta_\\text{old}$ and $\\theta$, to maximize $J^\\text{TRPO} (\\theta)$ would lead to instability with extremely large parameter updates and big policy ratios. PPO imposes the constraint by forcing $r(\\theta)$ to stay within a small interval around 1, precisely $[1-\\epsilon, 1+\\epsilon]$, where $\\epsilon$ is a hyperparameter.\n$$\nJ^\\text{CLIP} (\\theta) = \\mathbb{E} [ \\min( r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a), \\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon) \\hat{A}_{\\theta_\\text{old}}(s, a))]\n$$\nThe function $\\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon)$ clips the ratio to be no more than $1+\\epsilon$ and no less than $1-\\epsilon$. The objective function of PPO takes the minimum one between the original value and the clipped version and therefore we lose the motivation for increasing the policy update to extremes for better rewards.\nWhen applying PPO on the network architecture with shared parameters for both policy (actor) and value (critic) functions, in addition to the clipped reward, the objective function is augmented with an error term on the value estimation (formula in red) and an entropy term (formula in blue) to encourage sufficient exploration.\n$$\nJ^\\text{CLIP'} (\\theta) = \\mathbb{E} [ J^\\text{CLIP} (\\theta) - \\color{red}{c_1 (V_\\theta(s) - V_\\text{target})^2} + \\color{blue}{c_2 H(s, \\pi_\\theta(.))} ]\n$$\nwhere Both $c_1$ and $c_2$ are two hyperparameter constants.\nPPO has been tested on a set of benchmark tasks and proved to produce awesome results with much greater simplicity.\nIn a later paper by\nHsu et al., 2020\n, two common design choices in PPO are revisited, precisely (1) clipped probability ratio for policy regularization and (2) parameterize policy action space by continuous Gaussian or discrete softmax distribution. They first identified three failure modes in PPO and proposed replacements for these two designs.\nThe failure modes are:\nOn continuous action spaces, standard PPO is unstable when rewards vanish outside bounded support.\nOn discrete action spaces with sparse high rewards, standard PPO often gets stuck at suboptimal actions.\nThe policy is sensitive to initialization when there are locally optimal actions close to initialization.\nDiscretizing the action space or use Beta distribution helps avoid failure mode 1&3 associated with Gaussian policy. Using KL regularization (same motivation as in\nTRPO\n) as an alternative surrogate model helps resolve failure mode 1&2.\nPPG\n#\n[\npaper\n|\ncode\n]\nSharing parameters between policy and value networks have pros and cons. It allows policy and value functions to share the learned features with each other, but it may cause conflicts between competing objectives and demands the same data for training two networks at the same time.\nPhasic policy gradient\n(\nPPG\n;\nCobbe, et al 2020\n) modifies the traditional on-policy\nactor-critic\npolicy gradient algorithm. precisely\nPPO\n, to have separate training phases for policy and value functions. In two alternating phases:\nThe\npolicy phase\n: updates the policy network by optimizing the PPO\nobjective\n$L^\\text{CLIP} (\\theta)$;\nThe\nauxiliary phase\n: optimizes an auxiliary objective alongside a behavioral cloning loss. In the paper, value function error is the sole auxiliary objective, but it can be quite general and includes any other additional auxiliary losses.\n$$\n\\begin{aligned}\nL^\\text{joint} &= L^\\text{aux} + \\beta_\\text{clone} \\cdot \\mathbb{E}_t[\\text{KL}[\\pi_{\\theta_\\text{old}}(\\cdot\\mid s_t), \\pi_\\theta(\\cdot\\mid s_t)]] \\\\\nL^\\text{aux} &= L^\\text{value} = \\mathbb{E}_t \\big[\\frac{1}{2}\\big( V_w(s_t) - \\hat{V}_t^\\text{targ} \\big)^2\\big]\n\\end{aligned}\n$$\nwhere $\\beta_\\text{clone}$ is a hyperparameter for controlling how much we would like to keep the policy not diverge too much from its original behavior while optimizing the auxiliary objectives.\nThe algorithm of PPG. (Image source:\nCobbe, et al 2020\n)\nwhere\n$N_\\pi$ is the number of policy update iterations in the policy phase. Note that the policy phase performs multiple iterations of updates per single auxiliary phase.\n$E_\\pi$ and $E_V$ control the sample reuse (i.e. the number of training epochs performed across data in the reply buffer) for the policy and value functions, respectively. Note that this happens within the policy phase and thus $E_V$ affects the learning of true value function not the auxiliary value function.\n$E_\\text{aux}$ defines the sample reuse in the auxiliary phrase. In PPG, value function optimization can tolerate a much higher level sample reuse; for example, in the experiments of the paper, $E_\\text{aux} = 6$ while $E_\\pi = E_V = 1$.\nPPG leads to a significant improvement on sample efficiency compared to PPO.\nThe mean normalized performance of PPG vs PPO on the\nProcgen\nbenchmark. (Image source:\nCobbe, et al 2020\n)\nACER\n#\n[\npaper\n|\ncode\n]\nACER\n, short for\nactor-critic with experience replay\n(\nWang, et al., 2017\n), is an off-policy actor-critic model with experience replay, greatly increasing the sample efficiency and decreasing the data correlation. A3C builds up the foundation for ACER, but it is on policy; ACER is A3C’s off-policy counterpart. The major obstacle to making A3C off policy is how to control the stability of the off-policy estimator. ACER proposes three designs to overcome it:\nUse Retrace Q-value estimation;\nTruncate the importance weights with bias correction;\nApply efficient TRPO.\nRetrace Q-value Estimation\nRetrace\nis an off-policy return-based Q-value estimation algorithm with a nice guarantee for convergence for any target and behavior policy pair $(\\pi, \\beta)$, plus good data efficiency.\nRecall how TD learning works for prediction:\nCompute TD error: $\\delta_t = R_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(S_{t+1}, a) - Q(S_t, A_t)$; the term $r_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(s_{t+1}, a) $ is known as “TD target”. The expectation $\\mathbb{E}_{a \\sim \\pi}$ is used because for the future step the best estimation we can make is what the return would be if we follow the current policy $\\pi$.\nUpdate the value by correcting the error to move toward the goal: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha \\delta_t$. In other words, the incremental update on Q is proportional to the TD error: $\\Delta Q(S_t, A_t) = \\alpha \\delta_t$.\nWhen the rollout is off policy, we need to apply importance sampling on the Q update:\n$$\n\\Delta Q^\\text{imp}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)} \\delta_t\n$$\nThe product of importance weights looks pretty scary when we start imagining how it can cause super high variance and even explode. Retrace Q-value estimation method modifies $\\Delta Q$ to have importance weights truncated by no more than a constant $c$:\n$$\n\\Delta Q^\\text{ret}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\min(c, \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)})  \\delta_t\n$$\nACER uses $Q^\\text{ret}$ as the target to train the critic by minimizing the L2 error term: $(Q^\\text{ret}(s, a) - Q(s, a))^2$.\nImportance weights truncation\nTo reduce the high variance of the policy gradient $\\hat{g}$, ACER truncates the importance weights by a constant c, plus a correction term. The label $\\hat{g}_t^\\text{acer}$ is the ACER policy gradient at time t.\n$$\n\\begin{aligned}\n\\hat{g}_t^\\text{acer}\n= & \\omega_t \\big( Q^\\text{ret}(S_t, A_t) - V_{\\theta_v}(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t) \n  & \\scriptstyle{\\text{; Let }\\omega_t=\\frac{\\pi(A_t \\vert S_t)}{\\beta(A_t \\vert S_t)}} \\\\\n= & \\color{blue}{\\min(c, \\omega_t) \\big( Q^\\text{ret}(S_t, A_t) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)} \\\\\n  & + \\color{red}{\\mathbb{E}_{a \\sim \\pi} \\big[ \\max(0, \\frac{\\omega_t(a) - c}{\\omega_t(a)}) \\big( Q_w(S_t, a) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert S_t) \\big]}\n  & \\scriptstyle{\\text{; Let }\\omega_t (a) =\\frac{\\pi(a \\vert S_t)}{\\beta(a \\vert S_t)}}\n\\end{aligned}\n$$\nwhere $Q_w(.)$ and $V_w(.)$ are value functions predicted by the critic with parameter w. The first term (blue) contains the clipped important weight. The clipping helps reduce the variance, in addition to subtracting state value function $V_w(.)$ as a baseline. The second term (red) makes a correction to achieve unbiased estimation.\nEfficient TRPO\nFurthermore, ACER adopts the idea of TRPO but with a small adjustment to make it more computationally efficient: rather than measuring the KL divergence between policies before and after one update, ACER maintains a running average of past policies and forces the updated policy to not deviate far from this average.\nThe ACER\npaper\nis pretty dense with many equations. Hopefully, with the prior knowledge on TD learning, Q-learning, importance sampling and TRPO, you will find the\npaper\nslightly easier to follow :)\nACTKR\n#\n[\npaper\n|\ncode\n]\nACKTR (actor-critic using Kronecker-factored trust region)\n(\nYuhuai Wu, et al., 2017\n) proposed to use Kronecker-factored approximation curvature (\nK-FAC\n) to do the gradient update for both the critic and actor. K-FAC made an improvement on the computation of\nnatural gradient\n, which is quite different from our\nstandard gradient\n.\nHere\nis a nice, intuitive explanation of natural gradient. One sentence summary is probably:\n“we first consider all combinations of parameters that result in a new network a constant KL divergence away from the old network. This constant value can be viewed as the step size or learning rate. Out of all these possible combinations, we choose the one that minimizes our loss function.”\nI listed ACTKR here mainly for the completeness of this post, but I would not dive into details, as it involves a lot of theoretical knowledge on natural gradient and optimization methods. If interested, check these papers/posts, before reading the ACKTR paper:\nAmari.\nNatural Gradient Works Efficiently in Learning\n. 1998\nKakade.\nA Natural Policy Gradient\n. 2002\nA intuitive explanation of natural gradient descent\nWiki: Kronecker product\nMartens & Grosse.\nOptimizing neural networks with kronecker-factored approximate curvature.\n2015.\nHere is a high level summary from the K-FAC\npaper\n:\n“This approximation is built in two stages. In the first, the rows and columns of the Fisher are divided into groups, each of which corresponds to all the weights in a given layer, and this gives rise to a block-partitioning of the matrix. These blocks are then approximated as Kronecker products between much smaller matrices, which we show is equivalent to making certain approximating assumptions regarding the statistics of the network’s gradients.\nIn the second stage, this matrix is further approximated as having an inverse which is either block-diagonal or block-tridiagonal. We justify this approximation through a careful examination of the relationships between inverse covariances, tree-structured graphical models, and linear regression. Notably, this justification doesn’t apply to the Fisher itself, and our experiments confirm that while the inverse Fisher does indeed possess this structure (approximately), the Fisher itself does not.”\nSAC\n#\n[\npaper\n|\ncode\n]\nSoft Actor-Critic (SAC)\n(\nHaarnoja et al. 2018\n) incorporates the entropy measure of the policy into the reward to encourage exploration: we expect to learn a policy that acts as randomly as possible while it is still able to succeed at the task. It is an off-policy actor-critic model following the maximum entropy reinforcement learning framework. A precedent work is\nSoft Q-learning\n.\nThree key components in SAC:\nAn\nactor-critic\narchitecture with separate policy and value function networks;\nAn\noff-policy\nformulation that enables reuse of previously collected data for efficiency;\nEntropy maximization to enable stability and exploration.\nThe policy is trained with the objective to maximize the expected return and the entropy at the same time:\n$$\nJ(\\theta) = \\sum_{t=1}^T \\mathbb{E}_{(s_t, a_t) \\sim \\rho_{\\pi_\\theta}} [r(s_t, a_t) + \\alpha \\mathcal{H}(\\pi_\\theta(.\\vert s_t))]\n$$\nwhere $\\mathcal{H}(.)$ is the entropy measure and $\\alpha$ controls how important the entropy term is, known as\ntemperature\nparameter. The entropy maximization leads to policies that can (1) explore more and (2) capture multiple modes of near-optimal strategies (i.e., if there exist multiple options that seem to be equally good, the policy should assign each with an equal probability to be chosen).\nPrecisely, SAC aims to learn three functions:\nThe policy with parameter $\\theta$, $\\pi_\\theta$.\nSoft Q-value function parameterized by $w$, $Q_w$.\nSoft state value function parameterized by $\\psi$, $V_\\psi$; theoretically we can infer $V$ by knowing $Q$ and $\\pi$, but in practice, it helps stabilize the training.\nSoft Q-value and soft state value are defined as:\n$$\n\\begin{aligned}\nQ(s_t, a_t) &= r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_{\\pi}(s)} [V(s_{t+1})] & \\text{; according to Bellman equation.}\\\\\n\\text{where }V(s_t) &= \\mathbb{E}_{a_t \\sim \\pi} [Q(s_t, a_t) - \\alpha \\log \\pi(a_t \\vert s_t)] & \\text{; soft state value function.}\n\\end{aligned}\n$$\n$$\n\\text{Thus, } Q(s_t, a_t) = r(s_t, a_t) + \\gamma \\mathbb{E}_{(s_{t+1}, a_{t+1}) \\sim \\rho_{\\pi}} [Q(s_{t+1}, a_{t+1}) - \\alpha \\log \\pi(a_{t+1} \\vert s_{t+1})]\n$$\n$\\rho_\\pi(s)$ and $\\rho_\\pi(s, a)$ denote the state and the state-action marginals of the state distribution induced by the policy $\\pi(a \\vert s)$; see the similar definitions in\nDPG\nsection.\nThe soft state value function is trained to minimize the mean squared error:\n$$\n\\begin{aligned}\nJ_V(\\psi) &= \\mathbb{E}_{s_t \\sim \\mathcal{D}} [\\frac{1}{2} \\big(V_\\psi(s_t) - \\mathbb{E}[Q_w(s_t, a_t) - \\log \\pi_\\theta(a_t \\vert s_t)] \\big)^2] \\\\\n\\text{with gradient: }\\nabla_\\psi J_V(\\psi) &= \\nabla_\\psi V_\\psi(s_t)\\big( V_\\psi(s_t) - Q_w(s_t, a_t) + \\log \\pi_\\theta (a_t \\vert s_t) \\big)\n\\end{aligned}\n$$\nwhere $\\mathcal{D}$ is the replay buffer.\nThe soft Q function is trained to minimize the soft Bellman residual:\n$$\n\\begin{aligned}\nJ_Q(w) &= \\mathbb{E}_{(s_t, a_t) \\sim \\mathcal{D}} [\\frac{1}{2}\\big( Q_w(s_t, a_t) - (r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_\\pi(s)}[V_{\\bar{\\psi}}(s_{t+1})]) \\big)^2] \\\\\n\\text{with gradient: } \\nabla_w J_Q(w) &= \\nabla_w Q_w(s_t, a_t) \\big( Q_w(s_t, a_t) - r(s_t, a_t) - \\gamma V_{\\bar{\\psi}}(s_{t+1})\\big) \n\\end{aligned}\n$$\nwhere $\\bar{\\psi}$ is the target value function which is the exponential moving average (or only gets updated periodically in a “hard” way), just like how the parameter of the target Q network is treated in\nDQN\nto stabilize the training.\nSAC updates the policy to minimize the\nKL-divergence\n:\n$$\n\\begin{aligned}\n\\pi_\\text{new} \n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\Big( \\pi'(.\\vert s_t) \\| \\frac{\\exp(Q^{\\pi_\\text{old}}(s_t, .))}{Z^{\\pi_\\text{old}}(s_t)} \\Big) \\\\[6pt]\n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\big( \\pi'(.\\vert s_t) \\| \\exp(Q^{\\pi_\\text{old}}(s_t, .) - \\log Z^{\\pi_\\text{old}}(s_t)) \\big) \\\\[6pt]\n\\text{objective for update: } J_\\pi(\\theta) &= \\nabla_\\theta D_\\text{KL} \\big( \\pi_\\theta(. \\vert s_t) \\| \\exp(Q_w(s_t, .) - \\log Z_w(s_t)) \\big) \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} \\Big[ - \\log \\big( \\frac{\\exp(Q_w(s_t, a_t) - \\log Z_w(s_t))}{\\pi_\\theta(a_t \\vert s_t)} \\big) \\Big] \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} [ \\log \\pi_\\theta(a_t \\vert s_t) - Q_w(s_t, a_t) + \\log Z_w(s_t) ]\n\\end{aligned}\n$$\nwhere $\\Pi$ is the set of potential policies that we can model our policy as to keep them tractable; for example, $\\Pi$ can be the family of Gaussian mixture distributions, expensive to model but highly expressive and still tractable. $Z^{\\pi_\\text{old}}(s_t)$ is the partition function to normalize the distribution. It is usually intractable but does not contribute to the gradient. How to minimize $J_\\pi(\\theta)$ depends our choice of $\\Pi$.\nThis update guarantees that $Q^{\\pi_\\text{new}}(s_t, a_t) \\geq Q^{\\pi_\\text{old}}(s_t, a_t)$, please check the proof on this lemma in the Appendix B.2 in the original\npaper\n.\nOnce we have defined the objective functions and gradients for soft action-state value, soft state value and the policy network, the soft actor-critic algorithm is straightforward:\nThe soft actor-critic algorithm. (Image source:\noriginal paper\n)\nSAC with Automatically Adjusted Temperature\n#\n[\npaper\n|\ncode\n]\nSAC is brittle with respect to the temperature parameter. Unfortunately it is difficult to adjust temperature, because the entropy can vary unpredictably both across tasks and during training as the policy becomes better. An improvement on SAC formulates a constrained optimization problem: while maximizing the expected return, the policy should satisfy a minimum entropy constraint:\n$$\n\\max_{\\pi_0, \\dots, \\pi_T} \\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big] \\text{s.t. } \\forall t\\text{, } \\mathcal{H}(\\pi_t) \\geq \\mathcal{H}_0\n$$\nwhere $\\mathcal{H}_0$ is a predefined minimum policy entropy threshold.\nThe expected return $\\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big]$ can be decomposed into a sum of rewards at all the time steps. Because the policy $\\pi_t$ at time t has no effect on the policy at the earlier time step, $\\pi_{t-1}$, we can maximize the return at different steps backward in time — this is essentially\nDP\n.\n$$\n\\underbrace{\\max_{\\pi_0} \\Big( \\mathbb{E}[r(s_0, a_0)]+ \\underbrace{\\max_{\\pi_1} \\Big(\\mathbb{E}[...] + \\underbrace{\\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T)]}_\\text{1st maximization} \\Big)}_\\text{second but last maximization} \\Big)}_\\text{last maximization}\n$$\nwhere we consider $\\gamma=1$.\nSo we start the optimization from the last timestep $T$:\n$$\n\\text{maximize } \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] \\text{ s.t. } \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 \\geq 0\n$$\nFirst, let us define the following functions:\n$$\n\\begin{aligned}\nh(\\pi_T) &= \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 = \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0\\\\\nf(\\pi_T) &= \\begin{cases}\n\\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ], & \\text{if }h(\\pi_T) \\geq 0 \\\\\n-\\infty, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nAnd the optimization becomes:\n$$\n\\text{maximize } f(\\pi_T) \\text{ s.t. } h(\\pi_T) \\geq 0\n$$\nTo solve the maximization optimization with inequality constraint, we can construct a\nLagrangian expression\nwith a Lagrange multiplier (also known as “dual variable”), $\\alpha_T$:\n$$\nL(\\pi_T, \\alpha_T) = f(\\pi_T) + \\alpha_T h(\\pi_T)\n$$\nConsidering the case when we try to\nminimize $L(\\pi_T, \\alpha_T)$ with respect to $\\alpha_T$\n- given a particular value $\\pi_T$,\nIf the constraint is satisfied, $h(\\pi_T) \\geq 0$, at best we can set $\\alpha_T=0$ since we have no control over the value of $f(\\pi_T)$. Thus, $L(\\pi_T, 0) = f(\\pi_T)$.\nIf the constraint is invalidated, $h(\\pi_T) < 0$, we can achieve $L(\\pi_T, \\alpha_T) \\to -\\infty$ by taking  $\\alpha_T \\to \\infty$. Thus, $L(\\pi_T, \\infty) = -\\infty = f(\\pi_T)$.\nIn either case, we can recover the following equation,\n$$\nf(\\pi_T) = \\min_{\\alpha_T \\geq 0} L(\\pi_T, \\alpha_T)\n$$\nAt the same time, we want to maximize $f(\\pi_T)$,\n$$\n\\max_{\\pi_T} f(\\pi_T) = \\min_{\\alpha_T \\geq 0} \\max_{\\pi_T} L(\\pi_T, \\alpha_T)\n$$\nTherefore, to maximize $f(\\pi_T)$, the dual problem is listed as below. Note that to make sure $\\max_{\\pi_T} f(\\pi_T)$ is properly maximized and would not become $-\\infty$, the constraint has to be satisfied.\n$$\n\\begin{aligned}\n\\max_{\\pi_T} \\mathbb{E}[ r(s_T, a_T) ]\n&= \\max_{\\pi_T} f(\\pi_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} L(\\pi_T, \\alpha_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} f(\\pi_T) + \\alpha_T h(\\pi_T) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] + \\alpha_T ( \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  - \\alpha_T \\log \\pi_T(a_T\\vert s_T)] - \\alpha_T \\mathcal{H}_0 \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ]\n\\end{aligned}\n$$\nWe could compute the optimal $\\pi_T$ and $\\alpha_T$ iteratively. First given the current $\\alpha_T$, get the best policy $\\pi_T^{*}$ that maximizes $L(\\pi_T^{*}, \\alpha_T)$. Then plug in $\\pi_T^{*}$ and compute $\\alpha_T^{*}$ that minimizes $L(\\pi_T^{*}, \\alpha_T)$. Assuming we have one neural network for policy and one network for temperature parameter, the iterative update process is more aligned with how we update network parameters during training.\n$$\n\\begin{aligned}\n\\pi^{*}_T\n&= \\arg\\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ] \\\\\n\\color{blue}{\\alpha^{*}_T}\n&\\color{blue}{=} \\color{blue}{\\arg\\min_{\\alpha_T \\geq 0} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [\\alpha_T \\mathcal{H}(\\pi^{*}_T) - \\alpha_T \\mathcal{H}_0 ]}\n\\end{aligned}\n$$\n$$\n\\text{Thus, }\\max_{\\pi_T} \\mathbb{E} [ r(s_T, a_T) ] \n= \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [ r(s_T, a_T)  + \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) - \\alpha^{*}_T \\mathcal{H}_0 ]\n$$\nNow let’s go back to the soft Q value function:\n$$\n\\begin{aligned}\nQ_{T-1}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [Q(s_T, a_T) - \\alpha_T \\log \\pi(a_T \\vert s_T)] \\\\\n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [r(s_T, a_T)] + \\alpha_T \\mathcal{H}(\\pi_T) \\\\\nQ_{T-1}^{*}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\max_{\\pi_T} \\mathbb{E} [r(s_T, a_T)] +  \\alpha_T \\mathcal{H}(\\pi^{*}_T) & \\text{; plug in the optimal }\\pi_T^{*}\n\\end{aligned}\n$$\nTherefore the expected return is as follows, when we take one step further back to the time step $T-1$:\n$$\n\\begin{aligned}\n&\\max_{\\pi_{T-1}}\\Big(\\mathbb{E}[r(s_{T-1}, a_{T-1})] + \\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T] \\Big) \\\\\n&= \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) \\Big) & \\text{; should s.t. } \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\geq 0 \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) + \\alpha_{T-1} \\big( \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\big) \\Big) & \\text{; dual problem w/ Lagrangian.} \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 \\Big) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T)\n\\end{aligned}\n$$\nSimilar to the previous step,\n$$\n\\begin{aligned}\n\\pi^{*}_{T-1} &= \\arg\\max_{\\pi_{T-1}} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_\\pi} [Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1} \\mathcal{H}_0 ] \\\\\n\\color{green}{\\alpha^{*}_{T-1}} &\\color{green}{=} \\color{green}{\\arg\\min_{\\alpha_{T-1} \\geq 0} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_{\\pi^{*}}} [ \\alpha_{T-1} \\mathcal{H}(\\pi^{*}_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 ]}\n\\end{aligned}\n$$\nThe equation for updating $\\alpha_{T-1}$ in\ngreen\nhas the same format as the equation for updating $\\alpha_{T-1}$ in\nblue\nabove. By repeating this process, we can learn the optimal temperature parameter in every step by minimizing the same objective function:\n$$\nJ(\\alpha) = \\mathbb{E}_{a_t \\sim \\pi_t} [-\\alpha \\log \\pi_t(a_t \\mid s_t) - \\alpha \\mathcal{H}_0]\n$$\nThe final algorithm is same as SAC except for learning $\\alpha$ explicitly with respect to the objective $J(\\alpha)$ (see Fig. 7):\nThe soft actor-critic algorithm with automatically adjusted temperature. (Image source:\noriginal paper\n)\nTD3\n#\n[\npaper\n|\ncode\n]\nThe Q-learning algorithm is commonly known to suffer from the overestimation of the value function. This overestimation can propagate through the training iterations and negatively affect the policy. This property directly motivated\nDouble Q-learning\nand\nDouble DQN\n: the action selection and Q-value update are decoupled by using two value networks.\nTwin Delayed Deep Deterministic\n(short for\nTD3\n;\nFujimoto et al., 2018\n) applied a couple of tricks on\nDDPG\nto prevent the overestimation of the value function:\n(1)\nClipped Double Q-learning\n: In Double Q-Learning, the action selection and Q-value estimation are made by two networks separately. In the DDPG setting, given two deterministic actors $(\\mu_{\\theta_1}, \\mu_{\\theta_2})$ with two corresponding critics $(Q_{w_1}, Q_{w_2})$, the Double Q-learning Bellman targets look like:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma Q_{w_2}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma Q_{w_1}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\nHowever, due to the slow changing policy, these two networks could be too similar to make independent decisions. The\nClipped Double Q-learning\ninstead uses the minimum estimation among two so as to favor underestimation bias which is hard to propagate through training:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma \\min_{i=1,2}Q_{w_i}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma \\min_{i=1,2} Q_{w_i}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\n(2)\nDelayed update of Target and Policy Networks\n:  In the\nactor-critic\nmodel, policy and value updates are deeply coupled: Value estimates diverge through overestimation when the policy is poor, and the policy will become poor if the value estimate itself is inaccurate.\nTo reduce the variance, TD3 updates the policy at a lower frequency than the Q-function. The policy network stays the same until the value error is small enough after several updates. The idea is similar to how the periodically-updated target network stay as a stable objective in\nDQN\n.\n(3)\nTarget Policy Smoothing\n: Given a concern with deterministic policies that they can overfit to narrow peaks in the value function, TD3 introduced a smoothing regularization strategy on the value function: adding a small amount of clipped random noises to the selected action and averaging over mini-batches.\n$$\n\\begin{aligned}\ny &= r + \\gamma Q_w (s', \\mu_{\\theta}(s') + \\epsilon) & \\\\\n\\epsilon &\\sim \\text{clip}(\\mathcal{N}(0, \\sigma), -c, +c) & \\scriptstyle{\\text{ ; clipped random noises.}}\n\\end{aligned}\n$$\nThis approach mimics the idea of\nSARSA\nupdate and enforces that similar actions should have similar values.\nHere is the final algorithm:\nTD3 Algorithm. (Image source:\nFujimoto et al., 2018\n)\nSVPG\n#\n[\npaper\n|\ncode\nfor SVPG]\nStein Variational Policy Gradient (\nSVPG\n;\nLiu et al, 2017\n) applies the\nStein\nvariational gradient descent (\nSVGD\n;\nLiu and Wang, 2016\n) algorithm to update the policy parameter $\\theta$.\nIn the setup of maximum entropy policy optimization, $\\theta$ is considered as a random variable $\\theta \\sim q(\\theta)$ and the model is expected to learn this distribution $q(\\theta)$. Assuming we know a prior on how $q$ might look like, $q_0$, and we would like to guide the learning process to not make $\\theta$ too far away from $q_0$ by optimizing the following objective function:\n$$\n\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0)\n$$\nwhere $\\mathbb{E}_{\\theta \\sim q} [R(\\theta)]$ is the expected reward when $\\theta \\sim q(\\theta)$ and $D_\\text{KL}$ is the KL divergence.\nIf we don’t have any prior information, we might set $q_0$ as a uniform distribution and set $q_0(\\theta)$ to a constant. Then the above objective function becomes\nSAC\n, where the entropy term encourages exploration:\n$$\n\\begin{aligned}\n\\hat{J}(\\theta) \n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha \\mathbb{E}_{\\theta \\sim q} [\\log q(\\theta) - \\log q_0(\\theta)] \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] + \\alpha H(q(\\theta))\n\\end{aligned}\n$$\nLet’s take the derivative of $\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q|q_0)$ w.r.t. $q$:\n$$\n\\begin{aligned}\n\\nabla_q \\hat{J}(\\theta) \n&= \\nabla_q \\big( \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\big) \\\\\n&= \\nabla_q \\int_\\theta \\big( q(\\theta) J(\\theta) - \\alpha q(\\theta)\\log q(\\theta) + \\alpha q(\\theta) \\log q_0(\\theta) \\big) \\\\\n&= \\int_\\theta \\big( J(\\theta) - \\alpha \\log q(\\theta) -\\alpha + \\alpha \\log q_0(\\theta) \\big) \\\\\n&= 0\n\\end{aligned}\n$$\nThe optimal distribution is:\n$$\n\\log q^{*}(\\theta) = \\frac{1}{\\alpha} J(\\theta) + \\log q_0(\\theta) - 1 \\text{ thus } \\underbrace{ q^{*}(\\theta) }_\\textrm{\"posterior\"} \\propto \\underbrace{\\exp ( J(\\theta) / \\alpha )}_\\textrm{\"likelihood\"} \\underbrace{q_0(\\theta)}_\\textrm{prior}\n$$\nThe temperature $\\alpha$ decides a tradeoff between exploitation and exploration. When $\\alpha \\rightarrow 0$, $\\theta$ is updated only according to the expected return $J(\\theta)$. When $\\alpha \\rightarrow \\infty$, $\\theta$ always follows the prior belief.\nWhen using the SVGD method to estimate the target posterior distribution $q(\\theta)$, it relies on a set of particle $\\{\\theta_i\\}_{i=1}^n$ (independently trained policy agents) and each is updated:\n$$\n\\theta_i \\gets \\theta_i + \\epsilon \\phi^{*}(\\theta_i) \\text{ where } \\phi^{*} = \\max_{\\phi \\in \\mathcal{H}} \\{ - \\nabla_\\epsilon D_\\text{KL} (q'_{[\\theta + \\epsilon \\phi(\\theta)]} \\| q) \\text{ s.t. } \\|\\phi\\|_{\\mathcal{H}} \\leq 1\\} \n$$\nwhere $\\epsilon$ is a learning rate and $\\phi^{*}$ is the unit ball of a\nRKHS\n(reproducing kernel Hilbert space) $\\mathcal{H}$ of $\\theta$-shaped value vectors that maximally decreases the KL divergence between the particles and the target distribution. $q’(.)$ is the distribution of $\\theta + \\epsilon \\phi(\\theta)$.\nComparing different gradient-based update methods:\nMethod\nUpdate space\nPlain gradient\n$\\Delta \\theta$ on the parameter space\nNatural gradient\n$\\Delta \\theta$ on the search distribution space\nSVGD\n$\\Delta \\theta$ on the kernel function space (edited)\nOne\nestimation\nof $\\phi^{*}$ has the following form. A positive definite kernel $k(\\vartheta, \\theta)$, i.e. a Gaussian\nradial basis function\n, measures the similarity between particles.\n$$\n\\begin{aligned}\n\\phi^{*}(\\theta_i) \n&= \\mathbb{E}_{\\vartheta \\sim q'} [\\nabla_\\vartheta \\log q(\\vartheta) k(\\vartheta, \\theta_i) + \\nabla_\\vartheta k(\\vartheta, \\theta_i)]\\\\\n&= \\frac{1}{n} \\sum_{j=1}^n [\\color{red}{\\nabla_{\\theta_j} \\log q(\\theta_j) k(\\theta_j, \\theta_i)} + \\color{green}{\\nabla_{\\theta_j} k(\\theta_j, \\theta_i)}] & \\scriptstyle{\\text{;approximate }q'\\text{ with current particle values}}\n\\end{aligned}\n$$\nThe first term in\nred\nencourages $\\theta_i$ learning towards the high probability regions of $q$ that is shared across similar particles. => to be similar to other particles\nThe second term in\ngreen\npushes particles away from each other and therefore diversifies the policy. => to be dissimilar to other particles\nUsually the temperature $\\alpha$ follows an annealing scheme so that the training process does more exploration at the beginning but more exploitation at a later stage.\nIMPALA\n#\n[\npaper\n|\ncode\n]\nIn order to scale up RL training to achieve a very high throughput,\nIMPALA\n(“Importance Weighted Actor-Learner Architecture”) framework decouples acting from learning on top of basic actor-critic setup and learns from all experience trajectories with\nV-trace\noff-policy correction.\nMultiple actors generate experience in parallel, while the learner optimizes both policy and value function parameters using all the generated experience. Actors update their parameters with the latest policy from the learner periodically. Because acting and learning are decoupled, we can add many more actor machines to generate a lot more trajectories per time unit. As the training policy and the behavior policy are not totally synchronized, there is a\ngap\nbetween them and thus we need off-policy corrections.\nLet the value function $V_\\theta$ parameterized by $\\theta$ and the policy $\\pi_\\phi$ parameterized by $\\phi$. Also we know the trajectories in the replay buffer are collected by a slightly older policy $\\mu$.\nAt the training time $t$, given $(s_t, a_t, s_{t+1}, r_t)$, the value function parameter $\\theta$ is learned through an L2 loss between the current value and a V-trace value target. The $n$-step V-trace target is defined as:\n$$\n\\begin{aligned}\nv_t  &= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\delta_i V} \\\\\n&= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\rho_i (r_i + \\gamma V_\\theta(s_{i+1}) - V_\\theta(s_i))}\n\\end{aligned}\n$$\nwhere the\nred\npart $\\delta_i V$ is a temporal difference for $V$. $\\rho_i = \\min\\big(\\bar{\\rho}, \\frac{\\pi(a_i \\vert s_i)}{\\mu(a_i \\vert s_i)}\\big)$ and $c_j = \\min\\big(\\bar{c}, \\frac{\\pi(a_j \\vert s_j)}{\\mu(a_j \\vert s_j)}\\big)$ are\ntruncated\nimportance sampling (IS)\nweights\n. The product of $c_t, \\dots, c_{i-1}$ measures how much a temporal difference $\\delta_i V$ observed at time $i$ impacts the update of the value function at a previous time $t$. In the on-policy case, we have $\\rho_i=1$ and $c_j=1$ (assuming $\\bar{c} \\geq 1$) and therefore the V-trace target becomes on-policy $n$-step Bellman target.\n$\\bar{\\rho}$ and $\\bar{c}$ are two truncation constants with $\\bar{\\rho} \\geq \\bar{c}$. $\\bar{\\rho}$ impacts the fixed-point of the value function we converge to and $\\bar{c}$ impacts the speed of convergence. When $\\bar{\\rho} =\\infty$ (untruncated), we converge to the value function of the target policy $V^\\pi$; when $\\bar{\\rho}$ is close to 0, we evaluate the value function of the behavior policy $V^\\mu$; when in-between, we evaluate a policy between $\\pi$ and $\\mu$.\nThe value function parameter is therefore updated in the direction of:\n$$\n\\Delta\\theta = (v_t - V_\\theta(s_t))\\nabla_\\theta V_\\theta(s_t)\n$$\nThe policy parameter $\\phi$ is updated through policy gradient,\n$$\n\\begin{aligned}\n\\Delta \\phi \n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) + \\nabla_\\phi H(\\pi_\\phi)\\\\\n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) - \\nabla_\\phi \\sum_a \\pi_\\phi(a\\vert s_t)\\log \\pi_\\phi(a\\vert s_t)\n\\end{aligned}\n$$\nwhere $r_t + \\gamma v_{t+1}$ is the estimated Q value, from which a state-dependent baseline $V_\\theta(s_t)$ is subtracted. $H(\\pi_\\phi)$ is an entropy bonus to encourage exploration.\nIn the experiments, IMPALA is used to train one agent over multiple tasks. Two different model architectures are involved, a shallow model (left) and a deep residual model (right).\nQuick Summary\n#\nAfter reading through all the algorithms above, I list a few building blocks or principles that seem to be common among them:\nTry to reduce the variance and keep the bias unchanged to stabilize learning.\nOff-policy gives us better exploration and helps us use data samples more efficiently.\nExperience replay (training data sampled from a replay memory buffer);\nTarget network that is either frozen periodically or updated slower than the actively learned policy network;\nBatch normalization;\nEntropy-regularized reward;\nThe critic and actor can share lower layer parameters of the network and two output heads for policy and value functions.\nIt is possible to learn with deterministic policy rather than stochastic one.\nPut constraint on the divergence between policy updates.\nNew optimization methods (such as K-FAC).\nEntropy maximization of the policy helps encourage exploration.\nTry not to overestimate the value function.\nThink twice whether the policy and value network should share parameters.\nTBA more.\nCited as:\n@article{weng2018PG,\n  title   = \"Policy Gradient Algorithms\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-04-08-policy-gradient/\"\n}\nReferences\n#\n[1] jeremykun.com\nMarkov Chain Monte Carlo Without all the Bullshit\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] John Schulman, et al.\n“High-dimensional continuous control using generalized advantage estimation.”\nICLR 2016.\n[4] Thomas Degris, Martha White, and Richard S. Sutton.\n“Off-policy actor-critic.”\nICML 2012.\n[5] timvieira.github.io\nImportance sampling\n[6] Mnih, Volodymyr, et al.\n“Asynchronous methods for deep reinforcement learning.”\nICML. 2016.\n[7] David Silver, et al.\n“Deterministic policy gradient algorithms.”\nICML. 2014.\n[8] Timothy P. Lillicrap, et al.\n“Continuous control with deep reinforcement learning.”\narXiv preprint arXiv:1509.02971 (2015).\n[9] Ryan Lowe, et al.\n“Multi-agent actor-critic for mixed cooperative-competitive environments.”\nNIPS. 2017.\n[10] John Schulman, et al.\n“Trust region policy optimization.”\nICML. 2015.\n[11] Ziyu Wang, et al.\n“Sample efficient actor-critic with experience replay.”\nICLR 2017.\n[12] Rémi Munos, Tom Stepleton, Anna Harutyunyan, and Marc Bellemare.\n“Safe and efficient off-policy reinforcement learning”\nNIPS. 2016.\n[13] Yuhuai Wu, et al.\n“Scalable trust-region method for deep reinforcement learning using Kronecker-factored approximation.”\nNIPS. 2017.\n[14] kvfrans.com\nA intuitive explanation of natural gradient descent\n[15] Sham Kakade.\n“A Natural Policy Gradient.”\n. NIPS. 2002.\n[16]\n“Going Deeper Into Reinforcement Learning: Fundamentals of Policy Gradients.”\n- Seita’s Place, Mar 2017.\n[17]\n“Notes on the Generalized Advantage Estimation Paper.”\n- Seita’s Place, Apr, 2017.\n[18] Gabriel Barth-Maron, et al.\n“Distributed Distributional Deterministic Policy Gradients.”\nICLR 2018 poster.\n[19] Tuomas Haarnoja, Aurick Zhou, Pieter Abbeel, and Sergey Levine.\n“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”\narXiv preprint arXiv:1801.01290 (2018).\n[20] Scott Fujimoto, Herke van Hoof, and Dave Meger.\n“Addressing Function Approximation Error in Actor-Critic Methods.”\narXiv preprint arXiv:1802.09477 (2018).\n[21] Tuomas Haarnoja, et al.\n“Soft Actor-Critic Algorithms and Applications.”\narXiv preprint arXiv:1812.05905 (2018).\n[22] David Knowles.\n“Lagrangian Duality for Dummies”\nNov 13, 2010.\n[23] Yang Liu, et al.\n“Stein variational policy gradient.”\narXiv preprint arXiv:1704.02399 (2017).\n[24] Qiang Liu and Dilin Wang.\n“Stein variational gradient descent: A general purpose bayesian inference algorithm.”\nNIPS. 2016.\n[25] Lasse Espeholt, et al.\n“IMPALA: Scalable Distributed Deep-RL with Importance Weighted Actor-Learner Architectures”\narXiv preprint 1802.01561 (2018).\n[26] Karl Cobbe, et al.\n“Phasic Policy Gradient.”\narXiv preprint arXiv:2009.04416 (2020).\n[27] Chloe Ching-Yun Hsu, et al.\n“Revisiting Design Choices in Proximal Policy Optimization.”\narXiv preprint arXiv:2009.10897 (2020).",
            "metadata": {
              "title": "Policy Gradient Algorithms | Lil'Log",
              "description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "Policy Gradient Algorithms",
              "og:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
              "twitter:card": "summary",
              "twitter:title": "Policy Gradient Algorithms",
              "twitter:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "article:section": "posts",
              "article:published_time": "2018-04-08T00:00:00+00:00",
              "article:modified_time": "2018-04-08T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/ebc73787cbe5/code/body-000.txt",
                "chars": 226,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "bytes": 259350,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-394ec3f8b6a6ccc3dace.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "bytes": 205392,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-9c60abbe659d28457d7a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "bytes": 275060,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a8004105b4a88c05a952.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "bytes": 581593,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-7bc12620d13d41e17f0a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "bytes": 215084,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a1617c1aadd4262ae84a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "bytes": 181566,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-01ca9a7ea1e7d1cd82a2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "bytes": 294810,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a362a645159f0dafa82d.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "bytes": 860130,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-fafbbe0c69813ea86bf2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "bytes": 742699,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-d58e26716f1f269dae8a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "bytes": 300409,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-5e0d3d90650b6cca848e.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "bytes": 497568,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a29af53d479214903180.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "bytes": 332210,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-0061164751ee7e193a70.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "bytes": 253972,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-58ac4a854eb578c151aa.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "bytes": 567524,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-6b398117113938e66d50.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://talkingaboutme.tistory.com/entry/RL-Policy-Gradient-Algorithms",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://tomaxent.com/2019/04/14/%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6%E6%96%B9%E6%B3%95/",
                "label": "Chinese1",
                "type": "a"
              },
              {
                "href": "https://paperexplained.cn/articles/article/detail/31/",
                "label": "Chinese2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "“A (Long) Peek into Reinforcement Learning » Key Concepts”",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "this",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Curse_of_dimensionality",
                "label": "curse of dimensionality",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Sutton & Barto, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.02438.pdf",
                "label": "GAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/04/02/notes-on-the-generalized-advantage-estimation-paper/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/03/28/going-deeper-into-reinforcement-learning-fundamentals-of-policy-gradients/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://timvieira.github.io/blog/post/2014/12/21/importance-sampling/",
                "label": "importance weight",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1205.4839.pdf",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.01783",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dennybritz/reinforcement-learning/tree/master/PolicyGradient/a3c",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/blob/master/baselines/a2c/a2c.py",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/baselines-acktr-a2c/",
                "label": "shown",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1509.02971.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "label": "Batch normalization",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=SyZipzbCb",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05952",
                "label": "PER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1706.02275.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/maddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1502.05477.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/trpo_mpi",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "KL divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL-divergence",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.06347.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ppo1",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.10897",
                "label": "Hsu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.04416",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/phasic-policy-gradient",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.01588",
                "label": "Procgen",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.01224.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acer",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "label": "Retrace",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1708.05144.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acktr",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.05671.pdf",
                "label": "K-FAC",
                "type": "a"
              },
              {
                "href": "http://kvfrans.com/a-intuitive-explanation-of-natural-gradient-descent/",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.452.7280&rep=rep1&type=pdf",
                "label": "Natural Gradient Works Efficiently in Learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "label": "A Natural Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kronecker_product",
                "label": "Wiki: Kronecker product",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/martens15.pdf",
                "label": "Optimizing neural networks with kronecker-factored approximate curvature.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.01290",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/haarnoja/sac",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.08165",
                "label": "Soft Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.05905",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rail-berkeley/softlearning",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "label": "Lagrangian expression",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.09477",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sfujim/TD3",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/3964-double-q-learning",
                "label": "Double Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1509.06461",
                "label": "Double DQN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dilinwang820/Stein-Variational-Gradient-Descent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://www.cs.dartmouth.edu/~qliu/stein.html",
                "label": "Stein",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1608.04471",
                "label": "Liu and Wang, 2016",
                "type": "a"
              },
              {
                "href": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "label": "RKHS",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "Natural gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Radial_basis_function",
                "label": "radial basis function",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01561",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/deepmind/scalable_agent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.08617.pdf",
                "label": "“Distributed Distributional Deterministic Policy Gradients.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1801.01290.pdf",
                "label": "“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "label": "“Stein variational gradient descent: A general purpose bayesian inference algorithm.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "papers": [
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": false,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438.pdf",
                "bytes": 1798117,
                "reused": false,
                "local_path": "papers/repair/be9d8b8466e33236e35e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1205.4839.pdf",
                "bytes": 1610077,
                "reused": false,
                "local_path": "papers/repair/5ab0424e24a7205667b6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.01783",
                "bytes": 2302720,
                "reused": true,
                "local_path": "papers/repair/4ebd69e62e1319a151ba.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:39:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.02971.pdf",
                "bytes": 663643,
                "reused": false,
                "local_path": "papers/repair/cdfdf91c078ecbc5323f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "bytes": 318669,
                "reused": false,
                "local_path": "papers/repair/278c974d701b74b5258e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05952",
                "bytes": 1685573,
                "reused": false,
                "local_path": "papers/repair/232c5d788b53c3e83f28.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.02275.pdf",
                "bytes": 1502182,
                "reused": false,
                "local_path": "papers/repair/472ab942fc65a818d588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.05477.pdf",
                "bytes": 1026237,
                "reused": false,
                "local_path": "papers/repair/40909aa64b5fd4aacb8a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.06347.pdf",
                "bytes": 2923532,
                "reused": false,
                "local_path": "papers/repair/9e750b40bed5bcd1df74.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.10897",
                "bytes": 2074951,
                "reused": false,
                "local_path": "papers/repair/cb042047afd4ec37247c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.04416",
                "bytes": 2019980,
                "reused": false,
                "local_path": "papers/repair/e6984c4570bddcc10cbe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.01588",
                "bytes": 5158205,
                "reused": false,
                "local_path": "papers/repair/3231a0847e3982baa0a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01224.pdf",
                "bytes": 1856923,
                "reused": false,
                "local_path": "papers/repair/49a104905756e51b1082.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "bytes": 309421,
                "reused": false,
                "local_path": "papers/repair/a3c6ca6c0f5fa7ac392b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05144.pdf",
                "bytes": 5151566,
                "reused": false,
                "local_path": "papers/repair/17bd1711b6b1c975cd6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.05671.pdf",
                "bytes": 1801721,
                "reused": false,
                "local_path": "papers/repair/8348cabb06fa9a77e970.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "bytes": 1517587,
                "reused": false,
                "local_path": "papers/repair/5e5447a001f6bb409591.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/martens15.pdf",
                "bytes": 866438,
                "reused": false,
                "local_path": "papers/repair/cf98bb852a85a8c5a9be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/27be080213df12bc727f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.08165",
                "bytes": 3634452,
                "reused": false,
                "local_path": "papers/repair/cc481afce087c678bd26.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.05905",
                "bytes": 6750542,
                "reused": false,
                "local_path": "papers/repair/eb681f8429e54c661586.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "bytes": 157901,
                "reused": false,
                "local_path": "papers/repair/6d312b63b4d7133c0639.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.09477",
                "bytes": 2744342,
                "reused": false,
                "local_path": "papers/repair/b1cc41c6920f45d34ed8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.06461",
                "bytes": 789062,
                "reused": false,
                "local_path": "papers/repair/1b6dc947b906b3bd9192.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": false,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1608.04471",
                "bytes": 595069,
                "reused": false,
                "local_path": "papers/repair/55aec624e4d940526da7.pdf"
              },
              {
                "status": "download_error",
                "url": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "reason": "ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))",
                "retried_at": "2026-10-20T22:23:38Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01561",
                "bytes": 5601159,
                "reused": false,
                "local_path": "papers/repair/14d26b190854999d5443.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.08617.pdf",
                "bytes": 7734735,
                "reused": false,
                "local_path": "papers/repair/2db1af3554211ce5fb37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290.pdf",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/b36e949651aa96489b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "bytes": 477157,
                "reused": false,
                "local_path": "papers/repair/bb0557ad03965422dda1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 76635,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/ebc73787cbe5/pages/source.html",
            "local_html": "attachments/ebc73787cbe5/pages/article.html",
            "body_base_path": "attachments/ebc73787cbe5/pages/",
            "body_markdown_path": "attachments/ebc73787cbe5/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
          "status": "ok",
          "article_id": "3cea57e75b80",
          "local_path": "series-follow/1600/repair/af2ac25733510357c46b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
              "bytes": 313515,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/41ecf126bf1745efcc5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
              "bytes": 146194,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3ea228d0e87dde9e7cf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
              "bytes": 354759,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/6bd3a5f62a05f8cd2ac7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
              "bytes": 416371,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b634c681f16b15e45c48.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
              "bytes": 57364,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/db6d0799d37711ac02cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
              "bytes": 599299,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e2359292b85ebbae6075.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
              "bytes": 423806,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a6b205a1fce5f8c10434.png"
            }
          ],
          "article": {
            "id": "3cea57e75b80",
            "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "bytes": 313515,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-41ecf126bf1745efcc5a.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "bytes": 146194,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-3ea228d0e87dde9e7cf1.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "bytes": 354759,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-6bd3a5f62a05f8cd2ac7.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "bytes": 416371,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-b634c681f16b15e45c48.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "bytes": 57364,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-db6d0799d37711ac02cd.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "bytes": 599299,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-e2359292b85ebbae6075.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "bytes": 423806,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-a6b205a1fce5f8c10434.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=bLqJHjXihK8",
                "src": "https://youtu.be/bLqJHjXihK8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-bLqJHjXihK8.mp4",
                "bytes": 393293403,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "3474.261000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=P1A1yNsxMjc",
                "src": "https://youtu.be/P1A1yNsxMjc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-P1A1yNsxMjc.mp4",
                "bytes": 7744527,
                "valid": true,
                "height": 1080,
                "width": 1440,
                "duration": "100.041000",
                "reused": false
              }
            ],
            "body_markdown": "Professor Naftali Tishby passed away in 2021. Hope the post can introduce his cool idea of information bottleneck to more people.\nRecently I watched the talk\n“Information Theory in Deep Learning”\nby Prof Naftali Tishby and found it very interesting. He presented how to apply the information theory to study the growth and transformation of deep neural networks during training. Using the\nInformation Bottleneck (IB)\nmethod, he proposed a new learning bound for deep neural networks (DNN), as the traditional learning theory fails due to the exponentially large number of parameters. Another keen observation is that DNN training involves two distinct phases: First, the network is trained to fully represent the input data and minimize the generalization error; then, it learns to forget the irrelevant details by compressing the representation of the input.\nMost of the materials in this post are from Prof Tishby’s talk and\nrelated papers\n.\nBasic Concepts\n#\nMarkov Chain\nA Markov process is a\n“memoryless”\n(also called “Markov Property”) stochastic process. A Markov chain is a type of Markov process containing multiple discrete states. That is being said, the conditional probability of future states of the process is only determined by the current state and does not depend on the past states.\nKullback–Leibler (KL) Divergence\nKL divergence measures how one probability distribution $p$ diverges from a second expected probability distribution $q$. It is asymmetric.\n$$\n\\begin{aligned}\nD_{KL}(p \\| q) &= \\sum_x p(x) \\log \\frac{p(x)}{q(x)} \\\\\n &= - \\sum_x p(x)\\log q(x) + \\sum_x p(x)\\log p(x) \\\\\n &= H(P, Q) - H(P)\n\\end{aligned}\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nMutual Information\nMutual information measures the mutual dependence between two variables. It quantifies the “amount of information” obtained about one random variable through the other random variable. Mutual information is symmetric.\n$$\n\\begin{aligned}\nI(X;Y) &= D_{KL}[p(x,y) \\| p(x)p(y)] \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x, y)}{p(x)p(y)}) \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x|y)}{p(x)}) \\\\ \n &= H(X) - H(X|Y) \\\\\n\\end{aligned}\n$$\nData Processing Inequality (DPI)\nFor any markov chain: $X \\to Y \\to Z$, we would have $I(X; Y) \\geq I(X; Z)$.\nA deep neural network can be viewed as a Markov chain, and thus when we are moving down the layers of a DNN, the mutual information between the layer and the input can only decrease.\nReparametrization invariance\nFor two invertible functions $\\phi$, $\\psi$, the mutual information still holds: $I(X; Y) = I(\\phi(X); \\psi(Y))$.\nFor example, if we shuffle the weights in one layer of DNN, it would not affect the mutual information between this layer and another.\nDeep Neural Networks as Markov Chains\n#\nThe training data contains sampled observations from the joint distribution of $X$ and $Y$. The input variable $X$ and weights of hidden layers are all high-dimensional random variable. The ground truth target $Y$ and the predicted value $\\hat{Y}$ are random variables of smaller dimensions in the classification settings.\nThe structure of a deep neural network, which consists of the target label $Y$, input layer $X$, hidden layers $h\\_1, \\dots, h\\_m$ and the final prediction $\\hat{Y}$. (Image source:\nTishby and Zaslavsky, 2015\n)\nIf we label the hidden layers of a DNN as $h_1, h_2, \\dots, h_m$ as in Fig. 1, we can view each layer as one state of a Markov Chain: $ h_i \\to h_{i+1}$. According to DPI, we would have:\n$$\n\\begin{aligned}\nH(X) \\geq I(X; h_1) \\geq I(X; h_2) \\geq \\dots \\geq I(X; h_m) \\geq I(X; \\hat{Y}) \\\\\nI(X; Y) \\geq I(h_1; Y) \\geq I(h_2; Y) \\geq \\dots \\geq I(h_m; Y) \\geq I(\\hat{Y}; Y)\n\\end{aligned}\n$$\nA DNN is designed to learn how to describe $X$ to predict $Y$ and eventually, to compress $X$ to only hold the information related to $Y$. Tishby describes this processing as\n“successive refinement of relevant information”\n.\nInformation Plane Theorem\n#\nA DNN has successive internal representations of $X$, a set of hidden layers $\\{T_i\\}$. The\ninformation plane\ntheorem characterizes each layer by its encoder and decoder information. The encoder is a representation of the input data $X$, while the decoder translates the information in the current layer to the target ouput $Y$.\nPrecisely, in an information plane plot:\nX-axis\n: The sample complexity of $T_i$ is determined by the encoder mutual information $I(X; T_i)$. Sample complexity refers to how many samples you need to achieve certain accuracy and generalization.\nY-axis\n: The accuracy (generalization error) is determined by the decoder mutual information $I(T_i; Y)$.\nThe encoder vs decoder mutual information of DNN hidden layers of 50 experiments. Different layers are color-coders, with green being the layer right next to the input and the orange being the furthest. There are three snapshots, at the initial epoch, 400 epochs and 9000 epochs respectively. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nEach dot in marks the encoder/ decoder mutual information of one hidden layer of one network simulation (no regularization is applied; no weights decay, no dropout, etc.). They move up as expected because the knowledge about the true labels is increasing (accuracy increases). At the early stage, the hidden layers learn a lot about the input $X$, but later they start to compress to forget some information about the input. Tishby believes that\n“the most important part of learning is actually forgetting”\n. Check out this\nnice video\nthat demonstrates how the mutual information measures of layers are changing in epoch time.\nHere is an aggregated view of Fig 2. The compression happens after the generalization error becomes very small. (Image source:\nTishby’ talk 15:15\n)\nTwo Optimization Phases\n#\nTracking the normalized mean and standard deviation of each layer’s weights in time also reveals two optimization phases of the training process.\nThe norm of mean and standard deviation of each layer's weight gradients for each layer as a function of training epochs. Different layers are color-coded. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nAmong early epochs, the mean values are three magnitudes larger than the standard deviations. After a sufficient number of epochs, the error saturates and the standard deviations become much noisier afterward. The further a layer is away from the output, the noisier it gets, because the noises can get amplified and accumulated through the back-prop process (not due to the width of the layer).\nLearning Theory\n#\n“Old” Generalization Bounds\n#\nThe generalization bounds defined by the classic learning theory is:\n$$\n\\epsilon^2 < \\frac{\\log|H_\\epsilon| + \\log{1/\\delta}}{2m}\n$$\n$\\epsilon$: The difference between the training error and the generalization error. The generalization error measures how accurate the prediction of an algorithm is for previously unseen data.\n$H_\\epsilon$: $\\epsilon$-cover of the hypothesis class. Typically we assume the size $\\vert H_\\epsilon \\vert \\sim (1/\\epsilon)^d$.\n$\\delta$: Confidence.\n$m$: The number of training samples.\n$d$: The VC dimension of the hypothesis.\nThis definition states that the difference between the training error and the generalization error is bounded by a function of the hypothesis space size and the dataset size. The bigger the hypothesis space gets, the bigger the generalization error becomes. I recommend this tutorial on ML theory,\npart1\nand\npart2\n, if you are interested in reading more on generalization bounds.\nHowever, it does not work for deep learning. The larger a network is, the more parameters it needs to learn. With this generalization bounds, larger networks (larger $d$) would have worse bounds. This is contrary to the intuition that larger networks are able to achieve better performance with higher expressivity.\n“New” Input compression bound\n#\nTo solve this counterintuitive observation, Tishby et al. proposed a new input compression bound for DNN.\nFirst let us have $T_\\epsilon$ as an $\\epsilon$-partition of the input variable $X$. This partition compresses the input with respect to the homogeneity to the labels into small cells. The cells in total can cover the whole input space. If the prediction outputs binary values, we can replace the cardinality of the hypothesis, $\\vert H_\\epsilon \\vert$, with $2^{\\vert T_\\epsilon \\vert}$.\n$$\n|H_\\epsilon| \\sim 2^{|X|} \\to 2^{|T_\\epsilon|}\n$$\nWhen $X$ is large, the size of $X$ is approximately $2^{H(X)}$. Each cell in the $\\epsilon$-partition is of size $2^{H(X \\vert T_\\epsilon)}$. Therefore we have $\\vert T_\\epsilon \\vert \\sim \\frac{2^{H(X)}}{2^{H(X \\vert T_\\epsilon)}} = 2^{I(T_\\epsilon; X)}$. Then the input compression bound becomes:\n$$\n\\epsilon^2 < \\frac{2^{I(T_\\epsilon; X)} + \\log{1/\\delta}}{2m}\n$$\nThe black line is the optimal achievable information bottleneck (IB) limit. The red line corresponds to the upper bound on the out-of-sample IB distortion, when trained on a finite sample set. $\\Delta C$ is the complexity gap and $\\Delta G$ is the generalization gap. (Recreated based on\nTishby’ talk 24:50\n)\nNetwork Size and Training Data Size\n#\nThe Benefit of More Hidden Layers\n#\nHaving more layers give us computational benefits and speed up the training process for good generalization.\nThe optimization time is much shorter (fewer epochs) with more hidden layers. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCompression through stochastic relaxation\n: According to the\ndiffusion equation\n, the relaxation time of layer $k$ is proportional to the exponential of this layer’s compression amount $\\Delta S_k$: $\\Delta t_k \\sim \\exp(\\Delta S_k)$. We can compute the layer compression as $\\Delta S_k = I(X; T_k) - I(X; T_{k-1})$.  Because $\\exp(\\sum_k \\Delta S_k) \\geq \\sum_k \\exp(\\Delta S_k)$, we would expect an exponential decrease in training epochs with more hidden layers (larger $k$).\nThe Benefit of More Training Samples\n#\nFitting more training data requires more information captured by the hidden layers. With increased training data size, the decoder mutual information (recall that this is directly related to the generalization error), $I(T; Y)$, is pushed up and gets closer to the theoretical information bottleneck bound. Tishby emphasized that It is the mutual information, not the layer size or the VC dimension, that determines generalization, different from standard theories.\nThe training data of different sizes is color-coded. The information plane of multiple converged networks are plotted. More training data leads to better generalization. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCited as:\n@article{weng2017infotheory,\n  title   = \"Anatomize Deep Learning with Information Theory\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/\"\n}\nReferences\n#\n[1] Naftali Tishby.\nInformation Theory of Deep Learning\n[2]\nMachine Learning Theory - Part 1: Introduction\n[3]\nMachine Learning Theory - Part 2: Generalization Bounds\n[4]\nNew Theory Cracks Open the Black Box of Deep Learning\nby Quanta Magazine.\n[5] Naftali Tishby and Noga Zaslavsky.\n“Deep learning and the information bottleneck principle.”\nIEEE Information Theory Workshop (ITW), 2015.\n[6] Ravid Shwartz-Ziv and Naftali Tishby.\n“Opening the Black Box of Deep Neural Networks via Information.”\narXiv preprint arXiv:1703.00810, 2017.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:54Z",
            "title": "Anatomize Deep Learning with Information Theory | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/3cea57e75b80/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/physics/0004057.pdf",
                "bytes": 136267,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2bcb5c185f6c851f4943.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.02406.pdf",
                "bytes": 370205,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e3468aeea8ac86e9dd9c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00810.pdf",
                "bytes": 3921623,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d2cb5165e032151c7470.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 11409,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/3cea57e75b80/pages/source.html",
            "local_html": "attachments/3cea57e75b80/pages/article.html",
            "body_base_path": "attachments/3cea57e75b80/pages/",
            "body_markdown_path": "attachments/3cea57e75b80/pages/article.md",
            "links": [
              {
                "href": "https://youtu.be/bLqJHjXihK8",
                "label": "“Information Theory in Deep Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/physics/0004057.pdf",
                "label": "Information Bottleneck (IB)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "related papers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_chain",
                "label": "Markov Chain",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/Memoryless.html",
                "label": "“memoryless”",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback–Leibler (KL) Divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Mutual_information",
                "label": "Mutual Information",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Data_processing_inequality",
                "label": "Data Processing Inequality (DPI)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parametrization",
                "label": "Reparametrization invariance",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.02406.pdf",
                "label": "Tishby and Zaslavsky, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.00810.pdf",
                "label": "Shwartz-Ziv and Tishby, 2017",
                "type": "a"
              },
              {
                "href": "https://youtu.be/P1A1yNsxMjc",
                "label": "nice video",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=15m15s",
                "label": "Tishby’ talk 15:15",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt1/",
                "label": "part1",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt2/",
                "label": "part2",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=24m56s",
                "label": "Tishby’ talk 24:50",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Fokker%E2%80%93Planck_equation",
                "label": "diffusion equation",
                "type": "a"
              },
              {
                "href": "https://www.quantamagazine.org/new-theory-cracks-open-the-black-box-of-deep-learning-20170921/",
                "label": "New Theory Cracks Open the Black Box of Deep Learning",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
          "status": "partial",
          "article_id": "8a21c0acfb00",
          "local_path": "series-follow/1600/repair/d28ee743c76f5eaa3eb7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
              "bytes": 337534,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/4166a5ced4caf6791370.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
              "bytes": 147142,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/d50c93dfe76da4d51e52.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
              "bytes": 94880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c273a3bd2d035c6f2911.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
              "bytes": 121482,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1600/repair/assets/ec939fa4e1c720a45f69.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
              "bytes": 113689,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/63a237a784c9d55c73a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
              "bytes": 65056,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3b94a58b47770eed7ab3.png"
            }
          ],
          "article": {
            "id": "8a21c0acfb00",
            "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "bytes": 337534,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-4166a5ced4caf6791370.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "bytes": 147142,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-d50c93dfe76da4d51e52.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "bytes": 94880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-c273a3bd2d035c6f2911.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "bytes": 121482,
                "reused": false,
                "content_type": "image/jpeg",
                "local_path": "attachments/8a21c0acfb00/images/body-ec939fa4e1c720a45f69.jpg",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "bytes": 113689,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-63a237a784c9d55c73a0.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "bytes": 65056,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-3b94a58b47770eed7ab3.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=sGuiWX07sKw",
                "src": "https://youtu.be/sGuiWX07sKw",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/8a21c0acfb00/videos/repair-sGuiWX07sKw.mp4",
                "bytes": 1536006447,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5957.781000",
                "reused": false
              }
            ],
            "body_markdown": "The algorithms are implemented for Bernoulli bandit in\nlilianweng/multi-armed-bandit\n.\nExploitation vs Exploration\n#\nThe exploration vs exploitation dilemma exists in many aspects of our life. Say, your favorite restaurant is right around the corner. If you go there every day, you would be confident of what you will get, but miss the chances of discovering an even better option. If you try new places all the time, very likely you are gonna have to eat unpleasant food from time to time. Similarly, online advisors try to balance between the known most attractive ads and the new ads that might be even more successful.\nA real-life example of the exploration vs exploitation dilemma: where to eat? (Image source: UC Berkeley AI course\nslide\n,\nlecture 11\n.)\nIf we have learned all the information about the environment, we are able to find the best strategy by even just simulating brute-force, let alone many other smart approaches. The dilemma comes from the\nincomplete\ninformation: we need to gather enough information to make best overall decisions while keeping the risk under control. With exploitation, we take advantage of the best option we know. With exploration, we take some risk to collect information about unknown options. The best long-term strategy may involve short-term sacrifices. For example, one exploration trial could be a total failure, but it warns us of not taking that action too often in the future.\nWhat is Multi-Armed Bandit?\n#\nThe\nmulti-armed bandit\nproblem is a classic problem that well demonstrates the exploration vs exploitation dilemma. Imagine you are in a casino facing multiple slot machines and each is configured with an unknown probability of how likely you can get a reward at one play. The question is:\nWhat is the best strategy to achieve highest long-term rewards?\nIn this post, we will only discuss the setting of having an infinite number of trials. The restriction on a finite number of trials introduces a new type of exploration problem. For instance, if the number of trials is smaller than the number of slot machines, we cannot even try every machine to estimate the reward probability (!) and hence we have to behave smartly w.r.t. a limited set of knowledge and resources (i.e. time).\nAn illustration of how a Bernoulli multi-armed bandit works. The reward probabilities are **unknown** to the player.\nA naive approach can be that you continue to playing with one machine for many many rounds so as to eventually estimate the “true” reward probability according to the\nlaw of large numbers\n. However, this is quite wasteful and surely does not guarantee the best long-term reward.\nDefinition\n#\nNow let’s give it a scientific definition.\nA Bernoulli multi-armed bandit can be described as a tuple of $\\langle \\mathcal{A}, \\mathcal{R} \\rangle$, where:\nWe have $K$ machines with reward probabilities, $\\{ \\theta_1, \\dots, \\theta_K \\}$.\nAt each time step t, we take an action a on one slot machine and receive a reward r.\n$\\mathcal{A}$ is a set of actions, each referring to the interaction with one slot machine. The value of action a is the expected reward, $Q(a) = \\mathbb{E} [r \\vert a] = \\theta$. If action $a_t$ at the time step t is on the i-th machine, then $Q(a_t) = \\theta_i$.\n$\\mathcal{R}$ is a reward function. In the case of Bernoulli bandit, we observe a reward r in a\nstochastic\nfashion. At the time step t, $r_t = \\mathcal{R}(a_t)$ may return reward 1 with a probability $Q(a_t)$ or 0 otherwise.\nIt is a simplified version of\nMarkov decision process\n, as there is no state $\\mathcal{S}$.\nThe goal is to maximize the cumulative reward $\\sum_{t=1}^T r_t$.\nIf we know the optimal action with the best reward, then the goal is same as to minimize the potential\nregret\nor loss by not picking the optimal action.\nThe optimal reward probability $\\theta^{*}$ of the optimal action $a^{*}$ is:\n$$\n\\theta^{*}=Q(a^{*})=\\max_{a \\in \\mathcal{A}} Q(a) = \\max_{1 \\leq i \\leq K} \\theta_i\n$$\nOur loss function is the total regret we might have by not selecting the optimal action up to the time step T:\n$$\n\\mathcal{L}_T = \\mathbb{E} \\Big[ \\sum_{t=1}^T \\big( \\theta^{*} - Q(a_t) \\big) \\Big]\n$$\nBandit Strategies\n#\nBased on how we do exploration, there several ways to solve the multi-armed bandit.\nNo exploration: the most naive approach and a bad one.\nExploration at random\nExploration smartly with preference to uncertainty\nε-Greedy Algorithm\n#\nThe ε-greedy algorithm takes the best action most of the time, but does random exploration occasionally. The action value is estimated according to the past experience by averaging the rewards associated with the target action a that we have observed so far (up to the current time step t):\n$$\n\\hat{Q}_t(a) = \\frac{1}{N_t(a)} \\sum_{\\tau=1}^t r_\\tau \\mathbb{1}[a_\\tau = a]\n$$\nwhere $\\mathbb{1}$ is a binary indicator function and $N_t(a)$ is how many times the action a has been selected so far, $N_t(a) = \\sum_{\\tau=1}^t \\mathbb{1}[a_\\tau = a]$.\nAccording to the ε-greedy algorithm, with a small probability $\\epsilon$ we take a random action, but otherwise (which should be the most of the time, probability 1-$\\epsilon$) we pick the best action that we have learnt so far: $\\hat{a}^{*}_t = \\arg\\max_{a \\in \\mathcal{A}} \\hat{Q}_t(a)$.\nCheck my toy implementation\nhere\n.\nUpper Confidence Bounds\n#\nRandom exploration gives us an opportunity to try out options that we have not known much about. However, due to the randomness, it is possible we end up exploring a bad action which we have confirmed in the past (bad luck!). To avoid such inefficient exploration, one approach is to decrease the parameter ε in time and the other is to be optimistic about options with\nhigh uncertainty\nand thus to prefer actions for which we haven’t had a confident value estimation yet. Or in other words, we favor exploration of actions with a strong potential to have a optimal value.\nThe Upper Confidence Bounds (UCB) algorithm measures this potential by an upper confidence bound of the reward value, $\\hat{U}_t(a)$, so that the true value is below with bound $Q(a) \\leq \\hat{Q}_t(a) + \\hat{U}_t(a)$ with high probability. The upper bound $\\hat{U}_t(a)$ is a function of $N_t(a)$; a larger number of trials $N_t(a)$ should give us a smaller bound $\\hat{U}_t(a)$.\nIn UCB algorithm, we always select the greediest action to maximize the upper confidence bound:\n$$\na^{UCB}_t = argmax_{a \\in \\mathcal{A}} \\hat{Q}_t(a) + \\hat{U}_t(a)\n$$\nNow, the question is\nhow to estimate the upper confidence bound\n.\nHoeffding’s Inequality\n#\nIf we do not want to assign any prior knowledge on how the distribution looks like, we can get help from\n“Hoeffding’s Inequality”\n— a theorem applicable to any bounded distribution.\nLet $X_1, \\dots, X_t$ be i.i.d. (independent and identically distributed) random variables and they are all bounded by the interval [0, 1]. The sample mean is $\\overline{X}_t = \\frac{1}{t}\\sum_{\\tau=1}^t X_\\tau$. Then for $u > 0$, we have:\n$$\n\\mathbb{P} [ \\mathbb{E}[X] > \\overline{X}_t + u] \\leq e^{-2tu^2}\n$$\nGiven one target action $a$, let us consider:\n$r_t(a)$ as the random variables,\n$Q(a)$ as the true mean,\n$\\hat{Q}_t(a)$ as the sample mean,\nAnd $u$ as the upper confidence bound, $u = U_t(a)$\nThen we have,\n$$\n\\mathbb{P} [ Q(a) > \\hat{Q}_t(a) + U_t(a)] \\leq e^{-2t{U_t(a)}^2}\n$$\nWe want to pick a bound so that with high chances the true mean is blow the sample mean + the upper confidence bound. Thus $e^{-2t U_t(a)^2}$ should be a small probability. Let’s say we are ok with a tiny threshold p:\n$$\ne^{-2t U_t(a)^2} = p \\text{  Thus, } U_t(a) = \\sqrt{\\frac{-\\log p}{2 N_t(a)}}\n$$\nUCB1\n#\nOne heuristic is to reduce the threshold p in time, as we want to make more confident bound estimation with more rewards observed. Set $p=t^{-4}$ we get\nUCB1\nalgorithm:\n$$\nU_t(a) = \\sqrt{\\frac{2 \\log t}{N_t(a)}} \\text{  and  }\na^{UCB1}_t = \\arg\\max_{a \\in \\mathcal{A}} Q(a) + \\sqrt{\\frac{2 \\log t}{N_t(a)}}\n$$\nBayesian UCB\n#\nIn UCB or UCB1 algorithm, we do not assume any prior on the reward distribution and therefore we have to rely on the Hoeffding’s Inequality for a very generalize estimation. If we are able to know the distribution upfront, we would be able to make better bound estimation.\nFor example, if we expect the mean reward of every slot machine to be Gaussian as in Fig 2, we can set the upper bound as 95% confidence interval by setting $\\hat{U}_t(a)$ to be twice the standard deviation.\nWhen the expected reward has a Gaussian distribution. $\\sigma(a\\_i)$ is the standard deviation and $c\\sigma(a\\_i)$ is the upper confidence bound. The constant $c$ is a adjustable hyperparameter. (Image source:\nUCL RL course lecture 9's slides\n)\nCheck my toy implementation of\nUCB1\nand\nBayesian UCB\nwith Beta prior on θ.\nThompson Sampling\n#\nThompson sampling has a simple idea but it works great for solving the multi-armed bandit problem.\nOops, I guess not this Thompson? (Credit goes to\nBen Taborsky\n; he has a full theorem of how Thompson invented while pondering over who to pass the ball. Yes I stole his joke.)\nAt each time step, we want to select action a according to the probability that a is\noptimal\n:\n$$\n\\begin{aligned}\n\\pi(a \\; \\vert \\; h_t) \n&= \\mathbb{P} [ Q(a) > Q(a'), \\forall a' \\neq a \\; \\vert \\; h_t] \\\\\n&= \\mathbb{E}_{\\mathcal{R} \\vert h_t} [ \\mathbb{1}(a = \\arg\\max_{a \\in \\mathcal{A}} Q(a)) ]\n\\end{aligned}\n$$\nwhere $\\pi(a ; \\vert ; h_t)$ is the probability of taking action a given the history $h_t$.\nFor the Bernoulli bandit, it is natural to assume that $Q(a)$ follows a\nBeta\ndistribution, as $Q(a)$ is essentially the success probability θ in\nBernoulli\ndistribution.  The value of $\\text{Beta}(\\alpha, \\beta)$ is within the interval [0, 1]; α and β correspond to the counts when we\nsucceeded\nor\nfailed\nto get a reward respectively.\nFirst, let us initialize the Beta parameters α and β based on some prior knowledge or belief for every action. For example,\nα = 1 and β = 1; we expect the reward probability to be 50% but we are not very confident.\nα = 1000 and β = 9000; we strongly believe that the reward probability is 10%.\nAt each time t, we sample an expected reward, $\\tilde{Q}(a)$, from the prior distribution $\\text{Beta}(\\alpha_i, \\beta_i)$ for every action. The best action is selected among samples: $a^{TS}_t = \\arg\\max_{a \\in \\mathcal{A}} \\tilde{Q}(a)$. After the true reward is observed, we can update the Beta distribution accordingly, which is essentially doing Bayesian inference to compute the posterior with the known prior and the likelihood of getting the sampled data.\n$$\n\\begin{aligned}\n\\alpha_i & \\leftarrow \\alpha_i + r_t \\mathbb{1}[a^{TS}_t = a_i] \\\\ \n\\beta_i & \\leftarrow \\beta_i + (1-r_t) \\mathbb{1}[a^{TS}_t = a_i]\n\\end{aligned}\n$$\nThompson sampling implements the idea of\nprobability matching\n. Because its reward estimations $\\tilde{Q}$ are sampled from posterior distributions, each of these probabilities is equivalent to the probability that the corresponding action is optimal, conditioned on observed history.\nHowever, for many practical and complex problems, it can be computationally intractable to estimate the posterior distributions with observed true rewards using Bayesian inference. Thompson sampling still can work out if we are able to approximate the posterior distributions using methods like Gibbs sampling, Laplace approximate, and the bootstraps. This\ntutorial\npresents a comprehensive review; strongly recommend it if you want to learn more about Thompson sampling.\nCase Study\n#\nI implemented the above algorithms in\nlilianweng/multi-armed-bandit\n. A\nBernoulliBandit\nobject can be constructed with a list of random or predefined reward probabilities. The bandit algorithms are implemented as subclasses of\nSolver\n, taking a Bandit object as the target problem. The cumulative regrets are tracked in time.\nThe result of a small experiment on solving a Bernoulli bandit with K = 10 slot machines with reward probabilities, {0.0, 0.1, 0.2, ..., 0.9}. Each solver runs 10000 steps.\n(Left) The plot of time step vs the cumulative regrets. \n(Middle) The plot of true reward probability vs estimated probability. \n(Right) The fraction of each action is picked during the 10000-step run.*\nSummary\n#\nWe need exploration because information is valuable. In terms of the exploration strategies, we can do no exploration at all, focusing on the short-term returns. Or we occasionally explore at random. Or even further, we explore and we are picky about which options to explore — actions with higher uncertainty are favored because they can provide higher information gain.\nCited as:\n@article{weng2018bandit,\n  title   = \"The Multi-Armed Bandit Problem and Its Solutions\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/\"\n}\nReferences\n#\n[1] CS229 Supplemental Lecture notes:\nHoeffding’s inequality\n.\n[2] RL Course by David Silver - Lecture 9:\nExploration and Exploitation\n[3] Olivier Chapelle and Lihong Li.\n“An empirical evaluation of thompson sampling.”\nNIPS. 2011.\n[4] Russo, Daniel, et al.\n“A Tutorial on Thompson Sampling.”\narXiv:1707.02038 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:18Z",
            "title": "The Multi-Armed Bandit Problem and Its Solutions | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/8a21c0acfb00/code/body-000.txt",
                "chars": 255,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "bytes": 87277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7f286fae95f9b1c990be.pdf"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "retried_at": "2026-10-20T17:52:05Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.02038.pdf",
                "bytes": 3259310,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/11b5feb4dc8735d58193.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "bytes": 239361,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6b691aa46c22c662cdf.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 13130,
            "expected_body_images": 6,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/8a21c0acfb00/pages/source.html",
            "local_html": "attachments/8a21c0acfb00/pages/article.html",
            "body_base_path": "attachments/8a21c0acfb00/pages/",
            "body_markdown_path": "attachments/8a21c0acfb00/pages/article.md",
            "links": [
              {
                "href": "http://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/lecture_slides.html",
                "label": "slide",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/slides/Lecture%2011%20--%20Reinforcement%20Learning%20II/SP14%20CS188%20Lecture%2011%20--%20Reinforcement%20Learning%20II.pptx",
                "label": "lecture 11",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Multi-armed_bandit",
                "label": "multi-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "law of large numbers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_decision_process",
                "label": "Markov decision process",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Regret_(decision_theory)",
                "label": "regret",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/solvers.py",
                "label": "here",
                "type": "a"
              },
              {
                "href": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "label": "“Hoeffding’s Inequality”",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "label": "UCL RL course lecture 9's slides",
                "type": "a"
              },
              {
                "href": "https://www.linkedin.com/in/benjamin-taborsky",
                "label": "Ben Taborsky",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beta_distribution",
                "label": "Beta",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bernoulli_distribution",
                "label": "Bernoulli",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_matching",
                "label": "probability matching",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.02038.pdf",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/bandits.py",
                "label": "BernoulliBandit",
                "type": "a"
              },
              {
                "href": "https://youtu.be/sGuiWX07sKw",
                "label": "Exploration and Exploitation",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "label": "“An empirical evaluation of thompson sampling.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
          "status": "partial",
          "article_id": "54a9d3380f68",
          "local_path": "series-follow/1600/repair/fd35ae042f354cb3c47d.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
              "bytes": 21634,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/0af902d15df97a679d1d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
              "bytes": 54826,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1600/repair/assets/b14e80a69c065fcf923f.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
              "bytes": 89960,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1600/repair/assets/2ff11bc219d2fddbb103.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
              "bytes": 1470472,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/299fa3d9ecac66743b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
              "bytes": 497605,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/35effb374a6c3725fe88.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
              "bytes": 788370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c0e1f225ec0f222e8138.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
              "bytes": 645042,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c3675d62fb7c6784228f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
              "bytes": 31968,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/069c442cc0ce9957e75d.png"
            }
          ],
          "article": {
            "id": "54a9d3380f68",
            "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "bytes": 21634,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-0af902d15df97a679d1d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "bytes": 54826,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-b14e80a69c065fcf923f.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "bytes": 89960,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-2ff11bc219d2fddbb103.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "bytes": 1470472,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-299fa3d9ecac66743b06.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "bytes": 497605,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-35effb374a6c3725fe88.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "bytes": 788370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c0e1f225ec0f222e8138.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "bytes": 645042,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c3675d62fb7c6784228f.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "bytes": 31968,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-069c442cc0ce9957e75d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Part 1\nof the “Object Detection for Dummies” series introduced: (1) the concept of image gradient vector and how HOG algorithm summarizes the information across all the gradient vectors in one image; (2) how the image segmentation algorithm works to detect regions that potentially contain objects; (3) how the Selective Search algorithm refines the outcomes of image segmentation for better region proposal.\nIn Part 2, we are about to find out more on the classic convolution neural network architectures for image classification. They lay the\nfoundation\nfor further progress on the deep learning models for object detection. Go check\nPart 3\nif you want to learn more on R-CNN and related models.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nCNN for Image Classification\n#\nCNN, short for “\nConvolutional Neural Network\n”, is the go-to solution for computer vision problems in the deep learning world. It was, to some extent,\ninspired\nby how human visual cortex system works.\nConvolution Operation\n#\nI strongly recommend this\nguide\nto convolution arithmetic, which provides a clean and solid explanation with tons of visualizations and examples. Here let’s focus on two-dimensional convolution as we are working with images in this post.\nIn short, convolution operation slides a predefined\nkernel\n(also called “filter”) on top of the input feature map (matrix of image pixels), multiplying and adding the values of the kernel and partial input features to generate the output. The values form an output matrix, as usually, the kernel is much smaller than the input image.\nAn illustration of applying a kernel on the input feature map to generate the output. (Image source:\nRiver Trail documentation\n)\nFigure 2 showcases two real examples of how to convolve a 3x3 kernel over a 5x5 2D matrix of numeric values to generate a 3x3 matrix. By controlling the padding size and the stride length, we can generate an output matrix of a certain size.\nTwo examples of 2D convolution operation: (top) no padding and 1x1 strides; (bottom) 1x1 border zeros padding and 2x2 strides. (Image source:\ndeeplearning.net\n)\nAlexNet (Krizhevsky et al, 2012)\n#\n5 convolution [+ optional max pooling] layers + 2 MLP layers + 1 LR layer\nUse data augmentation techniques to expand the training dataset, such as image translations, horizontal reflections, and patch extractions.\nThe architecture of AlexNet. (Image source:\nlink\n)\nVGG (Simonyan and Zisserman, 2014)\n#\nThe network is considered as “very deep” at its time; 19 layers\nThe architecture is extremely simplified with only 3x3 convolutional layers and 2x2 pooling layers. The stacking of small filters simulates a larger filter with fewer parameters.\nResNet (He et al., 2015)\n#\nThe network is indeed very deep; 152 layers of simple architecture.\nResidual Block\n: Some input of a certain layer can be passed to the component two layers later. Residual blocks are essential for keeping a deep network trainable and eventually work. Without residual blocks, the training loss of a plain network does not monotonically decrease as the number of layers increases due to\nvanishing and exploding gradients\n.\nAn illustration of the residual block of ResNet. In some way, we can say the design of residual blocks is inspired by V4 getting input directly from V1 in the human visual cortex system. (left image source:\nWang et al., 2017\n)\nEvaluation Metrics: mAP\n#\nA common evaluation metric used in many object recognition and detection tasks is “\nmAP\n”, short for “\nmean average precision\n”. It is a number from 0 to 100; higher value is better.\nCombine all detections from all test images to draw a precision-recall curve (PR curve) for each class; The “average precision” (AP) is the area under the PR curve.\nGiven that target objects are in different classes, we first compute AP separately for each class, and then average over classes.\nA detection is a true positive if it has\n“intersection over union” (IoU)\nwith a ground-truth box greater than some threshold (usually 0.5; if so, the metric is “\nmAP@0.5\n”)\nDeformable Parts Model\n#\nThe Deformable Parts Model (DPM) (\nFelzenszwalb et al., 2010\n) recognizes objects with a mixture graphical model (Markov random fields) of deformable parts. The model consists of three major components:\nA coarse\nroot filter\ndefines a detection window that approximately covers an entire object. A filter specifies weights for a region feature vector.\nMultiple\npart filters\nthat cover smaller parts of the object. Parts filters are learned at twice resolution of the root filter.\nA\nspatial model\nfor scoring the locations of part filters relative to the root.\nThe DPM model contains (a) a root filter, (b) multiple part filters at twice the resolution, and (c) a model for scoring the location and deformation of parts.\nThe quality of detecting an object is measured by the score of filters minus the deformation costs. The matching score $f$, in laymen’s terms, is:\n$$\nf(\\text{model}, x) = f(\\beta_\\text{root}, x) + \\sum_{\\beta_\\text{part} \\in \\text{part filters}} \\max_y [f(\\beta_\\text{part}, y) - \\text{cost}(\\beta_\\text{part}, x, y)]\n$$\nin which,\n$x$ is an image with a specified position and scale;\n$y$ is a sub region of $x$.\n$\\beta_\\text{root}$ is the root filter.\n$\\beta_\\text{part}$ is one part filter.\ncost() measures the penalty of the part deviating from its ideal location relative to the root.\nThe basic score model is the dot product between the filter $\\beta$ and the region feature vector $\\Phi(x)$: $f(\\beta, x) = \\beta \\cdot \\Phi(x)$. The feature set $\\Phi(x)$ can be defined by HOG or other similar algorithms.\nA root location with high score detects a region with high chances to contain an object, while the locations of the parts with high scores confirm a recognized object hypothesis. The paper adopted latent SVM to model the classifier.\nThe matching process by DPM. (Image source:\nFelzenszwalb et al., 2010\n)\nThe author later claimed that DPM and CNN models are not two distinct approaches to object recognition. Instead, a DPM model can be formulated as a CNN by unrolling the DPM inference algorithm and mapping each step to an equivalent CNN layer. (Check the details in\nGirshick et al., 2015\n!)\nOverfeat\n#\nOverfeat [\npaper\n][\ncode\n] is a pioneer model of integrating the object detection, localization and classification tasks all into one convolutional neural network. The main idea is to (i) do image classification at different locations on regions of multiple scales of the image in a sliding window fashion, and (ii) predict the bounding box locations with a regressor trained on top of the same convolution layers.\nThe Overfeat model architecture is very similar to\nAlexNet\n. It is trained as follows:\nThe training stages of the Overfeat model. (Image source:\nlink\n)\nTrain a CNN model (similar to AlexNet) on the image classification task.\nThen, we replace the top classifier layers by a regression network and train it to predict object bounding boxes at each spatial location and scale. The regressor is class-specific, each generated for one image class.\nInput: Images with classification and bounding box.\nOutput: $(x_\\text{left}, x_\\text{right}, y_\\text{top}, y_\\text{bottom})$, 4 values in total, representing the coordinates of the bounding box edges.\nLoss: The regressor is trained to minimize $l2$ norm between generated bounding box and the ground truth for each training example.\nAt the detection time,\nPerform classification at each location using the pretrained CNN model.\nPredict object bounding boxes on all classified regions generated by the classifier.\nMerge bounding boxes with sufficient overlap from localization and sufficient confidence of being the same object from the classifier.\nCited as:\n@article{weng2017detection2,\n  title   = \"Object Detection for Dummies Part 2: CNN, DPM and Overfeat\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/\"\n}\nReference\n#\n[1] Vincent Dumoulin and Francesco Visin.\n“A guide to convolution arithmetic for deep learning.”\narXiv preprint arXiv:1603.07285 (2016).\n[2] Haohan Wang, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800 (2017).\n[3] Pedro F. Felzenszwalb, Ross B. Girshick, David McAllester, and Deva Ramanan.\n“Object detection with discriminatively trained part-based models.”\nIEEE transactions on pattern analysis and machine intelligence 32, no. 9 (2010): 1627-1645.\n[4] Ross B. Girshick, Forrest Iandola, Trevor Darrell, and Jitendra Malik.\n“Deformable part models are convolutional neural networks.”\nIn Proc. IEEE Conf. on Computer Vision and Pattern Recognition (CVPR), pp. 437-446. 2015.\n[5] Sermanet, Pierre, David Eigen, Xiang Zhang, Michaël Mathieu, Rob Fergus, and Yann LeCun.\n“OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks”\narXiv preprint arXiv:1312.6229 (2013).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:42Z",
            "title": "Object Detection for Dummies Part 2: CNN, DPM and Overfeat | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/54a9d3380f68/code/body-000.txt",
                "chars": 276,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.07285.pdf",
                "bytes": 913752,
                "reused": true,
                "local_path": "papers/repair/b61fe9cb2654d748de68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6229.pdf",
                "bytes": 937841,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/540d3c26a6305febc0e1.pdf"
              },
              {
                "status": "http_403",
                "url": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "retried_at": "2026-10-20T17:45:41Z"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "bytes": 832728,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1743cfdd1a25ffae4bbb.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "retried_at": "2026-10-20T17:45:42Z"
              },
              {
                "status": "ok",
                "url": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "bytes": 6298687,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/417cc548662a22985f80.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 8988,
            "expected_body_images": 8,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_403",
            "raw_html": "attachments/54a9d3380f68/pages/source.html",
            "local_html": "attachments/54a9d3380f68/pages/article.html",
            "body_base_path": "attachments/54a9d3380f68/pages/",
            "body_markdown_path": "attachments/54a9d3380f68/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/",
                "label": "inspired",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1603.07285.pdf",
                "label": "guide",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "kernel",
                "type": "a"
              },
              {
                "href": "http://intellabs.github.io/RiverTrail/tutorial/",
                "label": "River Trail documentation",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html",
                "label": "deeplearning.net",
                "type": "a"
              },
              {
                "href": "http://vision03.csail.mit.edu/cnn_art/index.html",
                "label": "link",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2015/10/recurrent-neural-networks-tutorial-part-3-backpropagation-through-time-and-vanishing-gradients/",
                "label": "vanishing and exploding gradients",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1312.6229.pdf",
                "label": "Wang et al., 2017",
                "type": "a"
              },
              {
                "href": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "label": "Felzenszwalb et al., 2010",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "label": "Girshick et al., 2015",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sermanet/OverFeat",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
          "status": "http_404"
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
          "status": "partial",
          "article_id": "18b05e29ab9d",
          "local_path": "series-follow/1600/repair/788a1d1b274cec73d601.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
              "bytes": 252865,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/afdfe639fc8e1e1fffd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
              "bytes": 398921,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/16ceaeb88e6dddc6da50.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
              "bytes": 101901,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e1a448b3ff933291fe36.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
              "bytes": 381220,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/0cbda3f821a3c389eac8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
              "bytes": 346442,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7e88364dbbb1f375b821.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
              "bytes": 228570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/df4787f5cc26e6a6c19f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
              "bytes": 338618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5e41793b605df1e81d30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
              "bytes": 288179,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3f6e0179b739c72f6462.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
              "bytes": 922761,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f1d133cc3f81469a78d0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
              "bytes": 287370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f0267a45ebe0513db62f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
              "bytes": 261905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3bf6bcdbee4e7c90f493.png"
            }
          ],
          "article": {
            "id": "18b05e29ab9d",
            "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "bytes": 252865,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-afdfe639fc8e1e1fffd2.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "bytes": 398921,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-16ceaeb88e6dddc6da50.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "bytes": 101901,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-e1a448b3ff933291fe36.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "bytes": 381220,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-0cbda3f821a3c389eac8.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "bytes": 346442,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-7e88364dbbb1f375b821.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "bytes": 228570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-df4787f5cc26e6a6c19f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "bytes": 338618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-5e41793b605df1e81d30.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "bytes": 288179,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3f6e0179b739c72f6462.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "bytes": 922761,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f1d133cc3f81469a78d0.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "bytes": 287370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f0267a45ebe0513db62f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "bytes": 261905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3bf6bcdbee4e7c90f493.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "[Updated on 2020-02-03: mentioning\nPCG\nin the “Task-Specific Curriculum” section.\n[Updated on 2020-02-04: Add a new\n“curriculum through distillation”\nsection.\nIt sounds like an impossible task if we want to teach integral or derivative to a 3-year-old who does not even know basic arithmetics. That’s why education is important, as it provides a systematic way to break down complex knowledge and a nice curriculum for teaching concepts from simple to hard. A curriculum makes learning difficult things easier and approachable for us humans. But, how about machine learning models? Can we train our models more efficiently with a curriculum? Can we design a curriculum to speed up learning?\nBack in 1993, Jeffrey Elman has proposed the idea of training neural networks with a curriculum. His early work on learning simple language grammar demonstrated the importance of such a strategy: starting with a restricted set of simple data and gradually increasing the complexity of training samples; otherwise the model was not able to learn at all.\nCompared to training without a curriculum, we would expect the adoption of the curriculum to expedite the speed of convergence and may or may not improve the final model performance. To design an efficient and effective curriculum is not easy. Keep in mind that, a bad curriculum may even hamper learning.\nNext, we will look into several categories of curriculum learning, as illustrated in Most cases are applied to Reinforcement Learning, with a few exceptions on Supervised Learning.\nFive types of curriculum for reinforcement learning.\nIn “The importance of starting small” paper (\nElman 1993\n), I especially like the starting sentences and find them both inspiring and affecting:\n“Humans differ from other species along many dimensions, but two are particularly noteworthy. Humans display an exceptional capacity to learn; and humans are remarkable for the unusually long time it takes to reach maturity. The adaptive advantage of learning is clear, and it may be argued that, through culture, learning has created the basis for a non-genetically based transmission of behaviors which may accelerate the evolution of our species.”\nIndeed, learning is probably the best superpower we humans have.\nTask-Specific Curriculum\n#\nBengio, et al. (2009)\nprovided a good overview of curriculum learning in the old days. The paper presented two ideas with toy experiments using a manually designed task-specific curriculum:\nCleaner Examples may yield better generalization faster.\nIntroducing gradually more difficult examples speeds up online training.\nIt is plausible that some curriculum strategies could be useless or even harmful. A good question to answer in the field is:\nWhat could be the general principles that make some curriculum strategies work better than others?\nThe Bengio 2009 paper hypothesized it would be beneficial to make learning focus on “interesting” examples that are neither too hard or too easy.\nIf our naive curriculum is to train the model on samples with a gradually increasing level of complexity, we need a way to quantify the difficulty of a task first. One idea is to use its minimal loss with respect to another model while this model is pretrained on other tasks (\nWeinshall, et al. 2018\n). In this way, the knowledge of the pretrained model can be transferred to the new model by suggesting a rank of training samples. Fig. 2 shows the effectiveness of the\ncurriculum\ngroup (green), compared to\ncontrol\n(random order; yellow) and\nanti\n(reverse the order; red) groups.\nImage classification accuracy on test image set (5 member classes of \"small mammals\" in CIFAR100). There are 4 experimental groups, (a) `curriculum`: sort the labels by the confidence of another trained classifier (e.g. the margin of an SVM); (b) `control-curriculum`: sort the labels randomly; (c) `anti-curriculum`: sort the labels reversely; (d) `None`: no curriculum. (Image source:\nWeinshall, et al. 2018\n)\nZaremba & Sutskever (2014)\ndid an interesting experiment on training LSTM to predict the output of a short Python program for mathematical ops without actually executing the code. They found curriculum is necessary for learning. The program’s complexity is controlled by two parameters,\nlength\n∈ [1, a] and\nnesting\n∈ [1, b]. Three strategies are considered:\nNaive curriculum: increase\nlength\nfirst until reaching\na\n; then increase\nnesting\nand reset\nlength\nto 1; repeat this process until both reach maximum.\nMix curriculum: sample\nlength\n~ [1, a] and\nnesting\n~ [1, b]\nCombined: naive + mix.\nThey noticed that combined strategy always outperformed the naive curriculum and would generally (but not always) outperform the mix strategy — indicating that it is quite important to mix in easy tasks during training to\navoid forgetting\n.\nProcedural content generation (\nPCG\n) is a popular approach for creating video games of various levels of difficulty. PCG involves algorithmic randomness and a heavy dose of human expertise in designing game elements and dependencies among them. Procedurally generated levels have been introduced into several benchmark environments for evaluating whether an RL agent can generalize to a new level that it is not trained on (\nmeta-RL\n!), such as\nGVGAI\n, OpenAI\nCoinRun\nand\nProcgen benchmark\n. Using GVGAI,\nJustesen, et al. (2018)\ndemonstrated that an RL policy can easily overfit to a specific game but training over a simple curriculum that grows the task difficulty together with the model performance helps its generalization to new human-designed levels. Similar results are also found in CoinRun (\nCobbe, et al. 2018\n). POET (\nWang et al, 2019\n) is another example for leveraging evolutionary algorithm and procedural generated game levels to improve RL generalization, which I’ve described in details in my\nmeta-RL post\n.\nTo follow the curriculum learning approaches described above, generally we need to figure out two problems in the training procedure:\nDesign a metric to quantify how hard a task is so that we can sort tasks accordingly.\nProvide a sequence of tasks with an increasing level of difficulty to the model during training.\nHowever, the order of tasks does not have to be sequential. In our Rubik’s cube paper (\nOpenAI et al, 2019\n), we depended on\nAutomatic domain randomization\n(\nADR\n) to generate a curriculum by growing a distribution of environments with increasing complexity. The difficulty of each task (i.e. solving a Rubik’s cube in a set of environments) depends on the randomization ranges of various environmental parameters. Even with a simplified assumption that all the environmental parameters are uncorrelated, we were able to create a decent curriculum for our robot hand to learn the task.\nTeacher-Guided Curriculum\n#\nThe idea of\nAutomatic Curriculum Learning\nwas proposed by\nGraves, et al. 2017\nslightly earlier. It considers a $N$-task curriculum as an\n$N$-armed bandit\nproblem and an adaptive policy which learns to optimize the returns from this bandit.\nTwo categories of learning signals have been considered in the paper:\nLoss-driven progress: the loss function change before and after one gradient update. This type of reward signals tracks the speed of the learning process, because the greatest task loss decrease is equivalent to the fastest learning.\nComplex-driven progress: the KL divergence between posterior and prior distribution over network weights. This type of learning signals are inspired by the\nMDL\nprinciple, “increasing the model complexity by a certain amount is only worthwhile if it compresses the data by a greater amount”. The model complexity is therefore expected to increase most in response to the model nicely generalizing to training examples.\nThis framework of proposing curriculum automatically through another RL agent was formalized as\nTeacher-Student Curriculum Learning\n(\nTSCL\n;\nMatiisen, et al. 2017\n). In TSCL, a\nstudent\nis an RL agent working on actual tasks while a\nteacher\nagent is a policy for selecting tasks. The student aims to master a complex task that might be hard to learn directly. To make this task easier to learn, we set up the teacher agent to guide the student’s training process by picking proper sub-tasks.\nThe setup of teacher-student curriculum learning. (Image source:\nMatiisen, et al. 2017\n+ my annotation in red.)\nIn the process, the student should learn tasks which:\ncan help the student make fastest learning progress, or\nare at risk of being forgotten.\nNote: The setup of framing the teacher model as an RL problem feels quite similar to Neural Architecture Search (NAS), but differently the RL model in TSCL operates on the task space and NAS operates on the main model architecture space.\nTraining the teacher model is to solve a\nPOMDP\nproblem:\nThe unobserved $s_t$ is the full state of the student model.\nThe observed $o = (x_t^{(1)}, \\dots, x_t^{(N)})$ are a list of scores for $N$ tasks.\nThe action $a$ is to pick on subtask.\nThe reward per step is the score delta.$r_t = \\sum_{i=1}^N x_t^{(i)} - x_{t-1}^{(i)}$ (i.e., equivalent to maximizing the score of all tasks at the end of the episode).\nThe method of estimating learning progress from noisy task scores while balancing exploration vs exploitation can be borrowed from the non-stationary multi-armed bandit problem — use\nε-greedy\n, or\nThompson sampling\n.\nThe core idea, in summary, is to use one policy to propose tasks for another policy to learn better. Interestingly, both works above (in the discrete task space) found that uniformly sampling from all tasks is a surprisingly strong benchmark.\nWhat if the task space is continuous?\nPortelas, et al. (2019)\nstudied a continuous teacher-student framework, where the teacher has to sample parameters from continuous task space to generate a learning curriculum. Given a newly sampled parameter $p$, the absolute learning progress (short for ALP) is measured as $\\text{ALP}_p = \\vert r - r_\\text{old} \\vert$, where $r$ is the episodic reward associated with $p$ and $r_\\text{old}$ is the reward associated with $p_\\text{old}$. Here, $p_\\text{old}$ is a previous sampled parameter closest to $p$ in the task space, which can be retrieved by nearest neighbor. Note that how this ALP score is different from learning signals in\nTSCL\nor\nGrave, et al. 2017\nabove: ALP score measures the reward difference between two tasks rather than performance at two time steps of the same task.\nOn top of the task parameter space, a Gaussian mixture model is trained to fit the distribution of $\\text{ALP}_p$ over $p$. ε-greedy is used when sampling the tasks: with some probability, sampling a random task; otherwise sampling proportionally to ALP score from the GMM model.\nThe algorithm of ALP-GMM (absolute learning progress Gaussian mixture model). (Image source:\nPortelas, et al., 2019\n)\nCurriculum through Self-Play\n#\nDifferent from the teacher-student framework, two agents are doing very different things. The teacher learns to pick a task for the student without any knowledge of the actual task content. What if we want to make both train on the main task directly? How about even make them compete with each other?\nSukhbaatar, et al. (2017)\nproposed a framework for automatic curriculum learning through\nasymmetric self-play\n. Two agents, Alice and Bob, play the same task with different goals: Alice challenges Bob to achieve the same state and Bob attempts to complete it as fast as he can.\nIllustration of the self-play setup when training two agents. The example task is\nMazeBase\n: An agent is asked to reach a goal flag in a maze with a light switch, a key and a wall with a door. Toggling the key switch can open or close the door and Turning off the light makes only the glowing light switch available to the agent. (Image source:\nSukhbaatar, et al. 2017\n)\nLet us consider Alice and Bob as two separate copies for one RL agent trained in the same environment but with different brains. Each of them has independent parameters and loss objective. The self-play-driven training consists of two types of episodes:\nIn the\nself-play episode\n, Alice alters the state from $s_0$ to $s_t$ and then Bob is asked to return the environment to its original state $s_0$ to get an internal reward.\nIn the\ntarget task episode\n, Bob receives an external reward if he visits the target flag.\nNote that since B has to repeat the actions between the same pair of $(s_0, s_t)$ of A, this framework only works in reversible or resettable environments.\nAlice should learn to push Bob out of his comfort zone, but not give him impossible tasks. Bob’s reward is set as $R_B = -\\gamma t_B$ and Alice’s reward is $R_A = \\gamma \\max(0, t_B - t_A)$, where $t_B$ is the total time for B to complete the task, $t_A$ is the time until Alice performs the STOP action and $\\gamma$ is a scalar constant to rescale the reward to be comparable with the external task reward. If B fails a task, $t_B = t_\\max - t_A$.\nBoth policies are goal-conditioned. The losses imply:\nB wants to finish a task asap.\nA prefers tasks that take more time of B.\nA does not want to take too many steps when B is failing.\nIn this way, the interaction between Alice and Bob automatically builds a curriculum of increasingly challenging tasks. Meanwhile, as A has done the task herself before proposing the task to B, the task is guaranteed to be solvable.\nThe paradigm of A suggesting tasks and then B solving them does sound similar to the Teacher-Student framework. However, in asymmetric self-play, Alice, who plays a teacher role, also works on the same task to find challenging cases for Bob, rather than optimizes B’s learning process explicitly.\nAutomatic Goal Generation\n#\nOften RL policy needs to be able to perform over a set of tasks. The goal should be carefully chosen so that at every training stage, it would not be too hard or too easy for the current policy. A goal $g \\in \\mathcal{G}$ can be defined as a set of states $S^g$ and a goal is considered as achieved whenever an agent arrives at any of those states.\nThe approach of Generative Goal Learning (\nFlorensa, et al. 2018\n) relies on a\nGoal GAN\nto generate desired goals automatically. In their experiment, the reward is very sparse, just a binary flag for whether a goal is achieved or not and the policy is conditioned on goal,\n$$\n\\begin{aligned}\n\\pi^{*}(a_t\\vert s_t, g) &= \\arg\\max_\\pi \\mathbb{E}_{g\\sim p_g(.)} R^g(\\pi) \\\\\n\\text{where }R^g(\\pi) &= \\mathbb{E}_\\pi(.\\mid s_t, g) \\mathbf{1}[\\exists t \\in [1,\\dots, T]: s_t \\in S^g]\n\\end{aligned}\n$$\nHere $R^g(\\pi)$ is the expected return, also equivalent to the success probability. Given sampled trajectories from the current policy, as long as any state belongs to the goal set, the return will be positive.\nTheir approach iterates through 3 steps until the policy converges:\nLabel a set of goals based on whether they are at the appropriate level of difficulty for the current policy.\nThe set of goals at the appropriate level of difficulty are named\nGOID\n(short for “Goals of Intermediate Difficulty”).\n$\\text{GOID}_i := \\{g : R_\\text{min} \\leq R^g(\\pi_i) \\leq R_\\text{max} \\} \\subseteq G$\nHere $R_\\text{min}$ and $R_\\text{max}$ can be interpreted as a minimum and maximum probability of reaching a goal over T time-steps.\nTrain a Goal GAN model using labelled goals from step 1 to produce new goals\nUse these new goals to train the policy, improving its coverage objective.\nThe Goal GAN generates a curriculum automatically:\nGenerator $G(z)$: produces a new goal. => expected to be a goal uniformly sampled from $GOID$ set.\nDiscriminator $D(g)$: evaluates whether a goal can be achieved. => expected to tell whether a goal is from $GOID$ set.\nThe Goal GAN is constructed similar to LSGAN (Least-Squared GAN;\nMao et al., (2017)\n), which has better stability of learning compared to vanilla GAN. According to LSGAN, we should minimize the following losses for $D$ and $G$ respectively:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{LSGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{LSGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nwhere $a$ is the label for fake data, $b$ for real data, and $c$ is the value that $G$ wants $D$ to believe for fake data. In LSGAN paper’s experiments, they used $a=-1, b=1, c=0$.\nThe Goal GAN introduces an extra binary flag $y_b$ indicating whether a goal $g$ is real ($y_g = 1$) or fake ($y_g = 0$) so that the model can use negative samples for training:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{GoalGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2 + (1-y_g) (D(g) - a)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{GoalGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nThe algorithm of Generative Goal Learning. (Image source: (\nFlorensa, et al. 2018\n)\nFollowing the same idea,\nRacaniere & Lampinen, et al. (2019)\ndesigns a method to make the objectives of goal generator more sophisticated. Their method contains three components, same as generative goal learning above:\nSolver\n/Policy $\\pi$: In each episode, the solver gets a goal $g$ at the beginning and get a single binary reward $R^g$ at the end.\nJudge\n/Discriminator $D(.)$: A classifier to predict the binary reward (whether goal can be achieved or not); precisely it outputs the logit of a probability of achieving the given goal, $\\sigma(D(g)) = p(R^g=1\\vert g)$, where $\\sigma$ is the sigmoid function.\nSetter\n/Generator $G(.)$: The goal setter takes as input a desired feasibility score $f \\in \\text{Unif}(0, 1)$ and generates $g = G(z, f)$, where the latent variable $z$ is sampled by $z \\sim \\mathcal{N}(0, I)$. The goal generator is designed to reversible, so $G^{-1}$ can map backwards from a goal $g$ to a latent $z = G^{-1}(g, f)$\nThe generator is optimized with three objectives:\nGoal\nvalidity\n: The proposed goal should be achievable by an expert policy. The corresponding generative loss is designed to increase the likelihood of generating goals that the solver policy has achieved before (like in\nHER\n).\n$\\mathcal{L}_\\text{val}$ is the negative log-likelihood of generated goals that have been solved by the solver in the past.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{val} = \\mathbb{E}_{\\substack{\n  g \\sim \\text{ achieved by solver}, \\\\\n  \\xi \\in \\text{Uniform}(0, \\delta), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ -\\log p(G^{-1}(g + \\xi, f)) \\big]\n\\end{align*}\n$$\nGoal\nfeasibility\n: The proposed goal should be achievable by the current policy; that is, the level of difficulty should be appropriate.\n$\\mathcal{L}_\\text{feas}$ is the output probability by the judge model $D$ on the generated goal $G(z, f)$ should match the desired $f$.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{feas} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ D(G(z, f)) - \\sigma^{-1}(f)^2 \\big]\n\\end{align*}\n$$\nGoal\ncoverage\n: We should maximize the entropy of generated goals to encourage diverse goal and to improve the coverage over the goal space.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{cov} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ \\log p(G(z, f)) \\big]\n\\end{align*}\n$$\nTheir experiments showed complex environments require all three losses above. When the environment is changing between episodes, both the goal generator and the discriminator need to be conditioned on environmental observation to produce better results. If there is a desired goal distribution, an additional loss can be added to match a desired goal distribution using Wasserstein distance. Using this loss, the generator can push the solver toward mastering the desired tasks more efficiently.\nTraining schematic for the (a) solver/policy, (b) judge/discriminator, and (c) setter/goal generator models. (Image source:\nRacaniere & Lampinen, et al., 2019\n)\nSkill-Based Curriculum\n#\nAnother view is to decompose what an agent is able to complete into a variety of skills and each skill set could be mapped into a task. Let’s imagine when an agent interacts with the environment in an unsupervised manner, is there a way to discover useful skills from such interaction and further build into the solutions for more complicated tasks through a curriculum?\nJabri, et al. (2019)\ndeveloped an automatic curriculum,\nCARML\n(short for “Curricula for Unsupervised Meta-Reinforcement Learning”), by modeling unsupervised trajectories into a latent skill space, with a focus on training\nmeta-RL\npolicies (i.e. can transfer to unseen tasks). The setting of training environments in CARML is similar to\nDIAYN\n. Differently, CARML is trained on pixel-level observations but DIAYN operates on the true state space. An RL algorithm $\\pi_\\theta$, parameterized by $\\theta$, is trained via unsupervised interaction formulated as a CMP combined with a learned reward function $r$. This setting naturally works for the meta-learning purpose, since a customized reward function can be given only at the test time.\nAn illustration of CARML, containing two steps: (1) organizing experiential data into the latent skill space; (2) meta-training the policy with the reward function constructed from the learned skills. (Image source:\nJabri, et al 2019\n)\nCARML is framed as a\nvariational Expectation-Maximization (EM)\n.\n(1)\nE-Step\n: This is the stage for organizing experiential data. Collected trajectories are modeled with a mixture of latent components forming the\nbasis\nof\nskills\n.\nLet $z$ be a latent task variable and $q_\\phi$ be a variational distribution of $z$, which could be a mixture model with discrete $z$ or a VAE with continuous $z$. A variational posterior $q_\\phi(z \\vert s)$ works like a classifier, predicting a skill given a state, and we would like to maximize $q_\\phi(z \\vert s)$ to discriminate between data produced by different skills as much as possible. In E-step, $q_\\phi$ is fitted to a set of trajectories produced by $\\pi_\\theta$.\nPrecisely, given a trajectory $\\tau = (s_1,\\dots,s_T)$, we would like to find $\\phi$ such that\n$$\n\\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\log q_\\phi(\\tau \\vert z) \\big]\n= \\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\sum_{s_i \\in \\tau} \\log q_\\phi(s_i \\vert z) \\big]\n$$\nA simplifying assumption is made here to ignore the order of states in one trajectory.\n(2)\nM-Step\n: This is the stage for doing meta-RL training with $\\pi_\\theta$. The learned skill space is considered as a training task distribution. CARML is agnostic to the type of meta-RL algorithm for policy parameter updates.\nGiven a trajectory $\\tau$, it makes sense for the policy to maximize the mutual information between $\\tau$ and $z$, $I(\\tau;z) = H(\\tau) - H(\\tau \\vert z)$, because:\nmaximizing $H(\\tau)$ => diversity in the policy data space; expected to be large.\nminimizing $H(\\tau \\vert z)$ => given a certain skill, the behavior should be restricted; expected to be small.\nThen we have,\n$$\n\\begin{aligned}\nI(\\tau; z) \n&= \\mathcal{H}(z) - \\mathcal{H}(z \\vert s_1,\\dots, s_T) \\\\\n&\\geq \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(z) - \\mathcal{H}(z\\vert s)] & \\scriptstyle{\\text{; discard the order of states.}} \\\\\n&= \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(s_t) - \\mathcal{H}(s\\vert z)] & \\scriptstyle{\\text{; by definition of MI.}} \\\\\n&= \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\log q_\\phi(s|z) - \\log \\pi_\\theta(s)] \\\\\n&\\approx \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\color{green}{\\log q_\\phi(s|z) - \\log q_\\phi(s)}] & \\scriptstyle{\\text{; assume learned marginal distr. matches policy.}}\n\\end{aligned}\n$$\nWe can set the reward as $\\log q_\\phi(s \\vert z) - \\log q_\\phi(s)$, as shown in the\nred\npart in the equation above. In order to balance between task-specific exploration (as in\nred\nbelow) and latent skill matching (as in\nblue\nbelow) , a parameter $\\lambda \\in [0, 1]$ is added. Each realization of $z \\sim q_\\phi(z)$ induces a reward function $r_z(s)$ (remember that reward + CMP => MDP) as follows:\n$$\n\\begin{aligned}\nr_z(s)\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s) \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log \\frac{q_\\phi(s|z) q_\\phi(z)}{q_\\phi(z|s)} \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s|z) - \\log q_\\phi(z) + \\log q_\\phi(z|s) \\\\\n&= (\\lambda - 1) \\log \\color{red}{q_\\phi(s|z)} + \\color{blue}{\\log q_\\phi(z|s)} + C\n\\end{aligned}\n$$\nThe algorithm of CARML. (Image source:\nJabri, et al 2019\n)\nLearning a latent skill space can be done in different ways, such as in\nHausman, et al. 2018\n. The goal of their approach is to learn a task-conditioned policy, $\\pi(a \\vert s, t^{(i)})$, where $t^{(i)}$ is from a discrete list of $N$ tasks, $\\mathcal{T} = [t^{(1)}, \\dots, t^{(N)}]$. However, rather than learning $N$ separate solutions, one per task, it would be nice to learn a latent skill space so that each task could be represented in a distribution over skills and thus skills are\nreused between tasks\n. The policy is defined as $\\pi_\\theta(a \\vert s,t) = \\int \\pi_\\theta(a \\vert z,s,t) p_\\phi(z \\vert t)\\mathrm{d}z$, where $\\pi_\\theta$ and $p_\\phi$ are policy and embedding networks to learn, respectively. If $z$ is discrete, i.e. drawn from a set of $K$ skills, then the policy becomes a mixture of $K$ sub-policies. The policy training uses\nSAC\nand the dependency on $z$ is introduced in the entropy term.\nCurriculum through Distillation\n#\n[I was thinking of the name of this section for a while, deciding between cloning, inheritance, and distillation. Eventually, I picked distillation because it sounds the coolest B-)]\nThe motivation for the\nprogressive neural network\n(\nRusu et al. 2016\n) architecture is to efficiently transfer learned skills between different tasks and in the meantime avoid catastrophic forgetting. The curriculum is realized through a set of progressively stacked neural network towers (or “columns”, as in the paper).\nA progressive network has the following structure:\nIt starts with a single column containing $L$ layers of neurons, in which the corresponding activation layers are labelled as $h^{(1)}_i, i=1, \\dots, L$. We first train this single-column network for one task to convergence, achieving parameter config $\\theta^{(1)}$.\nOnce switch to the next task, we need to add a new column to adapt to the new context while freezing $\\theta^{(1)}$ to lock down the learned skills from the previous task. The new column has activation layers labelled as $h^{(2)}_i, i=1, \\dots, L$, and parameters $\\theta^{(2)}$.\nStep 2 can be repeated with every new task. The $i$-th layer activation in the $k$-th column depends on the previous activation layers in all the existing columns:\n$$\n h^{(k)}_i = f(W^{(k)}_i h^{(k)}_{i-1} + \\sum_{j < k} U_i^{(k:j)} h^{(j)}_{i-1})\n $$\nwhere $W^{(k)}_i$ is the weight matrix of the layer $i$ in the column $k$; $U_i^{(k:j)}, j < k$ are the weight matrices for projecting the layer $i-1$ of the column $j$ to the layer $i$ of column $k$ ($ j < k $). The above weights matrices should be learned. $f(.)$ is a non-linear activation function by choice.\nThe progressive neural network architecture. (Image source:\nRusu, et al. 2017\n)\nThe paper experimented with Atari games by training a progressive network on multiple games to check whether features learned in one game can transfer to another. That is indeed the case. Though interestingly, learning a high dependency on features in the previous columns does not always indicate good transfer performance on the new task. One hypothesis is that features learned from the old task might introduce biases into the new task, leading to policy getting trapped in a sub-optimal solution. Overall, the progressive network works better than only fine-tuning the top layer and can achieve similar transfer performance as fine-tuning the entire network.\nOne use case for the progressive network is to do sim2real transfer (\nRusu, et al. 2017\n), in which the first column is trained in simulator with a lot of samples and then the additional columns (could be for different real-world tasks) are added and trained with a few real data samples.\nCzarnecki, et al. (2018)\nproposed another RL training framework,\nMix & Match\n(short for\nM&M\n) to provide curriculum through coping knowledge between agents. Given a sequence of agents from simple to complex, $\\pi_1, \\dots, \\pi_K$, each parameterized with some shared weights (e.g. by shared some lower common layers). M&M trains a mixture of agents, but only the final performance of the most complex one $\\pi_K$ matters.\nIn the meantime, M&M learns a categorical distribution $c \\sim \\text{Categorical}(1, \\dots, K \\vert \\alpha)$ with\npmf\n$p(c=i) = \\alpha_i$ probability to pick which policy to use at a given time. The mixed M&M policy is a simple weighted sum: $\\pi_\\text{mm}(a \\vert s) = \\sum_{i=1}^K \\alpha_i \\pi_i(a \\vert s)$. Curriculum learning is realized by dynamically adjusting $\\alpha_i$, from $\\alpha_K=0$ to $\\alpha_K=1$. The tuning of $\\alpha$ can be manual or through\npopulation-based training\n.\nTo encourage cooperation rather than competition among policies, besides the RL loss $\\mathcal{L}_\\text{RL}$, another\ndistillation\n-like loss $\\mathcal{L}_\\text{mm}(\\theta)$ is added. The knowledge transfer loss $\\mathcal{L}_\\text{mm}(\\theta)$ measures the KL divergence between two policies, $\\propto D_\\text{KL}(\\pi_{i}(. \\vert s) | \\pi_j(. \\vert s))$ for $i < j$. It encourages complex agents to match the simpler ones early on. The final loss is $\\mathcal{L} = \\mathcal{L}_\\text{RL}(\\theta \\vert \\pi_\\text{mm}) + \\lambda \\mathcal{L}_\\text{mm}(\\theta)$.\nThe Mix & Match architecture for training a mixture of policies.  (Image source:\nCzarnecki, et al., 2018\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2020). Curriculum for reinforcement learning. Lil’Log. https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/.\nOr\n@article{weng2020curriculum,\n  title   = \"Curriculum for Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/\"\n}\nReferences\n#\n[1] Jeffrey L. Elman.\n“Learning and development in neural networks: The importance of starting small.”\nCognition 48.1 (1993): 71-99.\n[2] Yoshua Bengio, et al.\n“Curriculum learning.”\nICML 2009.\n[3] Daphna Weinshall, Gad Cohen, and Dan Amir.\n“Curriculum learning by transfer learning: Theory and experiments with deep networks.”\nICML 2018.\n[4] Wojciech Zaremba and Ilya Sutskever.\n“Learning to execute.”\narXiv preprint arXiv:1410.4615 (2014).\n[5] Tambet Matiisen, et al.\n“Teacher-student curriculum learning.”\nIEEE Trans. on neural networks and learning systems (2017).\n[6] Alex Graves, et al.\n“Automated curriculum learning for neural networks.”\nICML 2017.\n[7]  Remy Portelas, et al.\nTeacher algorithms for curriculum learning of Deep RL in continuously parameterized environments\n. CoRL 2019.\n[8] Sainbayar Sukhbaatar, et al.\n“Intrinsic Motivation and Automatic Curricula via Asymmetric Self-Play.”\nICLR 2018.\n[9] Carlos Florensa, et al.\n“Automatic Goal Generation for Reinforcement Learning Agents”\nICML 2019.\n[10] Sebastien Racaniere & Andrew K. Lampinen, et al.\n“Automated Curriculum through Setter-Solver Interactions”\nICLR 2020.\n[11] Allan Jabri, et al.\n“Unsupervised Curricula for Visual Meta-Reinforcement Learning”\nNeuriPS 2019.\n[12] Karol Hausman, et al.\n“Learning an Embedding Space for Transferable Robot Skills “\nICLR 2018.\n[13] Josh Merel, et al.\n“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”\narXiv preprint arXiv:1911.06636 (2019).\n[14] OpenAI, et al.\n“Solving Rubik’s Cube with a Robot Hand.”\narXiv preprint arXiv:1910.07113 (2019).\n[15] Niels Justesen, et al.\n“Illuminating Generalization in Deep Reinforcement Learning through Procedural Level Generation”\nNeurIPS 2018 Deep RL Workshop.\n[16] Karl Cobbe, et al.\n“Quantifying Generalization in Reinforcement Learning”\narXiv preprint arXiv:1812.02341 (2018).\n[17] Andrei A. Rusu et al.\n“Progressive Neural Networks”\narXiv preprint arXiv:1606.04671 (2016).\n[18] Andrei A. Rusu et al.\n“Sim-to-Real Robot Learning from Pixels with Progressive Nets.”\nCoRL 2017.\n[19] Wojciech Marian Czarnecki, et al.\n“Mix & Match – Agent Curricula for Reinforcement Learning.”\nICML 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:47Z",
            "title": "Curriculum for Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/18b05e29ab9d/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_403",
                "url": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03796",
                "bytes": 585421,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6faa67cb3f93d77c9d67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.4615",
                "bytes": 559518,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a33b0ab1229e8af644d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.10729",
                "bytes": 999159,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/09fa801246d0c67848b3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.02341",
                "bytes": 7003398,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/9e7f2dbe5f93a5d5e4a2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/1910.07113.",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03003",
                "bytes": 3091441,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b98bef9914392e12f875.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.00183",
                "bytes": 1347985,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/79adfbe28098dc1e1722.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07224",
                "bytes": 2628539,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f72a60e37e01560d1e27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.05407",
                "bytes": 2032765,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f4e7d6c2102fc058dc62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.06366",
                "bytes": 6654321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3bc7353a8badf27f9df4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04076",
                "bytes": 3719760,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7af911a9191b6055b1a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.12892",
                "bytes": 2506625,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a8a071c792508aea939d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.01495",
                "bytes": 2464277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/81859ed20fbb79d50eec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.04226",
                "bytes": 3425807,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b8a67f584549b501f6b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04671",
                "bytes": 4278357,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3304a794e8bdd5c42143.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.04286",
                "bytes": 1087389,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b715f19efae8d26a11d0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.01780",
                "bytes": 4106903,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5c9572e1111a7e6fdcb1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06295",
                "bytes": 727329,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/270be775129eb54c13ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.06636",
                "bytes": 5806364,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e62ae132fefd8cc55d44.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07113",
                "bytes": 5194320,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2ef619bdd5bd429418f2.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 32251,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_403；http_404",
            "raw_html": "attachments/18b05e29ab9d/pages/source.html",
            "local_html": "attachments/18b05e29ab9d/pages/article.html",
            "body_base_path": "attachments/18b05e29ab9d/pages/",
            "body_markdown_path": "attachments/18b05e29ab9d/pages/article.md",
            "links": [
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.128.4487&rep=rep1&type=pdf",
                "label": "Elman 1993",
                "type": "a"
              },
              {
                "href": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "label": "Bengio, et al. (2009)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03796",
                "label": "Weinshall, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.4615",
                "label": "Zaremba & Sutskever (2014)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Procedural_generation",
                "label": "PCG",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "meta-RL",
                "type": "a"
              },
              {
                "href": "http://www.gvgai.net/",
                "label": "GVGAI",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/quantifying-generalization-in-reinforcement-learning/",
                "label": "CoinRun",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/procgen-benchmark/",
                "label": "Procgen benchmark",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.10729",
                "label": "Justesen, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.02341",
                "label": "Cobbe, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113.",
                "label": "OpenAI et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03003",
                "label": "Graves, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$N$-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimum_description_length",
                "label": "MDL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.00183",
                "label": "Matiisen, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Partially_observable_Markov_decision_process",
                "label": "POMDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07224",
                "label": "Portelas, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.05407",
                "label": "Sukhbaatar, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://github.com/facebook/MazeBase",
                "label": "MazeBase",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.06366",
                "label": "Florensa, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04076",
                "label": "Mao et al., (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.12892",
                "label": "Racaniere & Lampinen, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.01495",
                "label": "HER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.04226",
                "label": "Jabri, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://chrischoy.github.io/research/Expectation-Maximization-and-Variational-Inference/",
                "label": "variational Expectation-Maximization (EM)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Basis_(linear_algebra)",
                "label": "basis",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=rk07ZXZRb",
                "label": "Hausman, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://127.0.0.1:4000/lil-log/2018/04/07/policy-gradient-algorithms.html",
                "label": "SAC",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04671",
                "label": "Rusu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.04286",
                "label": "Rusu, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.01780",
                "label": "Czarnecki, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_mass_function",
                "label": "pmf",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "population-based training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06295",
                "label": "distillation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.06636",
                "label": "“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113",
                "label": "“Solving Rubik’s Cube with a Robot Hand.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
          "status": "ok",
          "article_id": "c811c8fa03ef",
          "local_path": "series-follow/1600/repair/30b6e9434771c5fcef0e.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
              "bytes": 439380,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/cd75f36109d9a8976ce6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
              "bytes": 581069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e0cb70b1716fc6541886.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
              "bytes": 124447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/bae92611d020d867c823.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
              "bytes": 234189,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5ede211aaa74090777be.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
              "bytes": 1134478,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/037e75ccc6667d3dd676.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
              "bytes": 169121,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/eb009e9e4995ad677d20.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
              "bytes": 238097,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e98d393b3034f7b93c42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
              "bytes": 3433956,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/931034d1f77fea4a9b89.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
              "bytes": 279963,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/67ca3976dba24dedc5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
              "bytes": 137174,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e95985488d6654cc5673.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
              "bytes": 884311,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/6291c7ba7f2547d16349.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
              "bytes": 472655,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/49d8a2995980c00d678d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
              "bytes": 191203,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/a407ab83faa199042c24.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
              "bytes": 237219,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/54c0cf380132c67d2456.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
              "bytes": 986067,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/595316073143c8f09324.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
              "bytes": 334330,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7f21eb25c4d7577b7655.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
              "bytes": 235579,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9ff79113319b46733509.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Train Really Large Models on Many GPUs?",
            "keywords": "分布式训练,并行,大模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "publish_date": "2021-09",
            "corpus_stage": "预训练/SFT",
            "notes": "多GPU大规模模型训练技术综述",
            "id": "c811c8fa03ef",
            "collected_at": "2026-10-02T14:12:59",
            "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
            "body_markdown": "[Updated on 2022-03-13: add\nexpert choice routing\n.]\n[Updated on 2022-06-10]:\nGreg\nand I wrote a shorted and upgraded version of this post, published on OpenAI Blog:\n“Techniques for Training Large Neural Networks”\nIn recent years, we are seeing better results on many NLP benchmark tasks with larger pre-trained\nlanguage models\n. How to train large and deep neural networks is challenging, as it demands a large amount of GPU memory and a long horizon of training time.\nHowever an individual GPU worker has limited memory and the sizes of many large models have grown beyond a single GPU. There are several parallelism paradigms to enable model training across multiple GPUs, as well as a variety of model architecture and memory saving designs to help make it possible to train\nvery large\nneural networks.\nTraining Parallelism\n#\nThe main bottleneck for training very large neural network models is the intense demand for a large amount of GPU memory, way above what can be hosted on an individual GPU machine. Besides the model weights (e.g. tens of billions of floating point numbers), it is usually even more expensive to store intermediate computation outputs such as gradients and optimizer states (e.g. momentums & variations in Adam). Additionally training a large model often pairs with a large training corpus and thus a single process may just take forever.\nAs a result, parallelism is necessary. Parallelism can happen at different dimensions, including data, model architecture, and tensor operation.\nData Parallelism\n#\nThe most naive way for\nData parallelism (DP)\nis to copy the same model weights into multiple workers and assign a fraction of data to each worker to be processed at the same time.\nNaive DP cannot work well if the model size is larger than a single GPU node’s memory. Methods like\nGeePS\n(\nCui et al. 2016\n) offload temporarily unused parameters back to CPU to work with limited GPU memory when the model is too big to fit into one machine. The data swapping transfer should happen at the backend and not interfere with training computation.\nAt the end of each minibatch, workers need to synchronize gradients or weights to avoid staleness. There are two main synchronization approaches and both have clear pros & cons.\nBulk synchronous parallels (BSP)\n: Workers sync data at the end of every minibatch. It prevents model weights staleness and good learning efficiency but each machine has to halt and wait for others to send gradients.\nAsynchronous  parallel (ASP)\n: Every GPU worker processes the data asynchronously, no waiting or stalling. However, it can easily lead to stale weights being used and thus lower the statistical learning efficiency. Even though it increases the computation time, it may not speed up training time to convergence.\nSomewhere in the middle is to synchronize gradients globally once every $x$ iterations ($x > 1$). This feature is called “gradient accumulation” in Distribution Data Parallel (\nDDP\n) since Pytorch v1.5 (\nLi et al. 2021\n). Bucketing gradients avoid immediate\nAllReduce\noperations but instead buckets multiple gradients into one\nAllReduce\nto improve throughput. Computation and communication scheduling optimization can be made based on the computation graph.\nPseudo code for Pytorch DDP. (Image source:\nLi et al. 2021\n)\nModel Parallelism\n#\nModel parallelism (MP)\naims to solve the case when the model weights cannot fit into a single node. The computation and model parameters are partitioned across multiple machines. Different from data parallelism where each worker hosts a full copy of the entire model, MP only allocates a fraction of model parameters on one worker and thus both the memory usage and the computation are reduced.\nSince deep neural networks usually contain a stack of vertical layers, it feels straightforward to split a large model by layer, where a small consecutive set of layers are grouped into one partition on one worker. However, a naive implementation for running every data batch through multiple such workers with sequential dependency leads to big bubbles of waiting time and severe under-utilization of computation resources.\nA naive model parallelism setup where the model is vertically split into 4 partitions. Data is processed by one worker at a time due to sequential dependency, leading to large “bubbles” of idle time. (Image source:\nHuang et al. 2019\n)\nPipeline Parallelism\n#\nPipeline parallelism (PP)\ncombines model parallelism with data parallelism to reduce inefficient time “bubbles’’. The main idea is to split one minibatch into multiple microbatches and enable each stage worker to process one microbatch simultaneously. Note that every microbatch needs two passes, one forward and one backward. Inter-worker communication only transfers activations (forward) and gradients (backward). How these passes are scheduled and how the gradients are aggregated vary in different approaches. The number of partitions (workers) is also known as\npipeline depth\n.\nIn\nGPipe\n(\nHuang et al. 2019\n) gradients from multiple microbatches are aggregated and applied synchronously at the end. The synchronous gradient descent guarantees learning consistency and efficiency irrespective of the number of workers. As shown in Fig. 3, bubbles still exist but are much smaller than what’s in Given $m$ evenly split microbatches and $d$ partitions, assuming both forward and backward per microbatch take one unit of time, the fraction of bubble is:\n$$\n1 - \\frac{2md}{(2m + 2(d-1))d} = \\frac{d-1}{m+d-1}\n$$\nThe GPipe paper observed that the bubble overhead is almost negligible if the number of microbatches is more than 4x the number of partitions $m > 4d$ (when\nactivation recomputation\nis applied).\nIllustration of pipeline parallelism in GPipe with 4 microbatches and 4 partitions. GPipe aggregates and updates gradients across devices synchronously at the end of every batch. (Image source:\nHuang et al. 2019\n)\nGPipe achieves almost linear speedup in throughput with the number of devices, although it is not always guaranteed if the model parameters are not evenly distributed across workers.\nPipeDream\n(\nNarayanan et al. 2019\n) schedules each worker to alternatively process the forward and backward passes (\n1F1B\n).\nPipeDream names each model partition “stage” and each stage worker can have multiple replicas to run data parallelism. In this process, PipeDream uses a deterministic round-robin load balancing strategy to assign work among multiple replicas of stages to ensure that the forward and backward passes for the same minibatch happen on the same replica.\nIllustration of `1F1B` microbatch scheduling in PipeDream. (Image source:\nHarlap et al. 2018\n)\nSince PipeDream does not have an end-of-batch global gradient sync across all the workers, an native implementation of 1F1B can easily lead to the forward and backward passes of one microbatch using different versions of model weights, thus lowering the learning efficiency. PipeDream proposed a few designs to tackle this issue:\nWeight stashing\n: Each worker keeps track of several model versions and makes sure that the same version of weights are used in the forward and backward passes given one data batch.\nVertical sync\n(Optional): The version of model weights flows between stage workers together with activations and gradients. Then the computation adopts the corresponding stashed version propagated from the previous worker. This process keeps version consistency across workers. Note that it is asynchronous, different from GPipe.\nAt the beginning of a training run, PipeDream first profiles the computation memory cost and time of each layer in the model and then optimizes a solution for partitioning layers into stages, which is a dynamic programming problem.\nResults for VGG16 on ILSVRC12. (Top) Accuracy vs time. The integer marks the number of stage workers. ASP =  Asynchronous  parallel & BSP = Bulk synchronous parallels. (Bottom) Training time speedup for different parallelism configurations. Straight pipeline refers to pipeline parallelism without data parallelism. (Image source:\nHarlap et al. 2018\n)\nTwo variations of PipeDream were later proposed to reduce the memory footprint by stashed model versions (\nNarayanan et al. 2021\n).\nPipeDream-flush\nadds a globally synchronized pipeline flush periodically, just like GPipe. In this way, it greatly reduces the memory footprint (i.e. only maintain a single version of model weights) by sacrificing a little throughput.\nIllustration of pipeline scheduling in PipeDream-flush. (Image source: (\nNarayanan et al. 2021\n)\nPipeDream-2BW\nmaintains only two versions of model weights, where “2BW” is short for “double-buffered weights”. It generates a new model version every $k$ microbatches and $k$ should be larger than the pipeline depth $d$, $k > d$. A newly updated model version cannot fully replace the old version immediately since some leftover backward passes still depend on the old version. In total only two versions need to be saved so the memory cost is much reduced.\nIllustration of pipeline scheduling in PipeDream-2BW. (Image source: (\nNarayanan et al. 2021\n)\nTensor Parallelism\n#\nBoth model and pipeline parallelisms split a model vertically. OTOH we can horizontally partition the computation for one tensor operation across multiple devices, named\nTensor parallelism (TP)\n.\nLet’s take the transformer as an example given its popularity. The transformer model mainly consists of layers of MLP and self-attention blocks.\nMegatron-LM\n(\nShoeybi et al. 2020\n) adopts a simple way to parallelize intra-layer computation for MLP and self-attention.\nA MLP layer in a transformer contains a GEMM (General matrix multiply) followed by an non-linear GeLU transfer. Let’s split weight matrix $A$ by column:\n$$\n\\begin{aligned}\n\\text{Split }A &= [A_1, A_2] \\\\\nY &=\\text{GeLU}(XA) \\\\\n[Y_1, Y_2] &= [\\text{GeLU}(XA_1), \\text{GeLU}(XA_2)]\n\\end{aligned}\n$$\nThe attention block runs GEMM with query ($Q$), key ($K$), and value weights ($V$) according to the above partitioning in parallel and then combines them with another GEMM to produce the attention head results.\n$$\n\\text{Attention}(X, Q, K, V) = \\text{softmax}(\\frac{(XQ) (XK)^\\top}{\\sqrt{d_k}}) XV\n$$\nIllustration of tensor parallelism for key transformer components proposed in Megatron-LM. (Image source:\nShoeybi et al. 2020\n)\nNarayanan et al. (2021)\ncombined pipeline, tensor and data parallelism with a new pipeline scheduling strategy and named their approach\nPTD-P\n. Instead of only positioning a continuous set of layers (“model chunk”) on a device, each worker can be assigned with multiple chunks of smaller continuous subsets of layers (e.g. device 1 has layers 1, 2, 9, 10; device 2 has layers 3, 4, 11, 12; each has two model chunks). The number of microbatches in one batch should be exactly divided by the number of workers ($m % d = 0$). If there are $v$ model chunks per worker, the pipeline bubble time can be reduced by a multiplier of $v$ compared to a GPipe scheduling.\n(Top) Default `1F1B` pipeline schedule as in PipeDream-flush. (Bottom) Interleaved 1F1B pipeline schedule. First model chunks are in dark colors and second chunks are in light colors. (Image source:\nNarayanan et al. 202)\n)\nMixture-of-Experts (MoE)\n#\nThe\nMixture-of-Experts (MoE)\napproach attracts a lot of attention recently as researchers (mainly from Google) try to push the limit of model size. The core of the idea is\nensembling learning\n:\nCombination of multiple weak learners gives you a strong learner!\nWithin one deep neural network, ensembling can be implemented with a gating mechanism connecting multiple experts (\nShazeer et al., 2017\n). The gating mechanism controls which subset of the network (e.g. which experts) should be activated to produce outputs. The paper named it “sparsely gated mixture-of-experts” (MoE) layer.\nPrecisely one MoE layer contains\n$n$ feed-forward networks as experts $\\{E_i\\}^n_{i=1}$\nA trainable gating network $G$ to learn a probability distribution over $n$ experts so as to route the traffic to a few selected experts.\nDepending on the gating outputs, not every expert has to be evaluated. When the number of experts is too large, we can consider using a two-level hierarchical MoE.\nIllustration of a mixture-of-experts (MoE) layer. Only 2 out of $n$ experts are selected and activated by the gating network. (Image source:\nShazeer et al., 2017\n)\nA simple choice of $G$ is to multiply the input with a trainable weight matrix $G_g$ and then do softmax: $G_\\sigma (x) = \\text{softmax}(x W_g)$. However, this produces a dense control vector for gating and does not help save computation resources because we don’t need to evaluate an expert only when $G^{(i)}(x)=0$. Thus the MoE layer only keeps the top $k$ values. It also adds tunable Gaussian noise into $G$ to improve load balancing. This mechanism is called\nnoisy top-k gating\n.\n$$\n\\begin{aligned} \nG(x) &= \\text{softmax}( \\text{topk}(H(x), k)) \\\\\nH^{(i)}(x) &= (xW_g)^{(i)} + \\epsilon \\cdot \\text{softplus}((xW_\\text{noise})^{(i)} ); \\quad \\epsilon \\sim \\mathcal{N}(0, \\mathbf{1}) \\\\\n\\text{topk}^{(i)}(v, k) &= \\begin{cases} v^{(i)} & \\text{if }v^{(i)}\\text{ is in the top }k\\text{ elements of }v \\\\ -\\infty & \\text{otherwise} \n\\end{cases} \n\\end{aligned}\n$$\nwhere the superscript $v^{(i)}$ denotes the i-th dimension of the vector $v$. The function $\\text{topk}(., k)$ selected the top $k$ dimensions with highest values by setting other dimensions to $-\\infty$.\nTo avoid the self-reinforcing effect that the gating network may favor a few strong experts all the time,\nShazeer et al. (2017)\nproposed a soft constraint via an additional importance loss to encourage all the experts to have the same weights. It is equivalent to the square of the\ncoefficient of variation\nof batchwise average value per expert.\n$$\nL_\\text{aux} = w_\\text{aux} \\cdot \\text{CV}(\\sum_{x \\in X} G(x))^2\n$$\nwhere $ \\text{CV}$ is the coefficient of variation and the loss weight $w_\\text{aux}$ is a hyperparameter to tune.\nBecause every expert network only gets a fraction of training samples (“The shrinking batch problem”), we should try to use a batch size as large as possible in MoE. However, it is restricted by GPU memory. Data parallelism and model parallelism can be applied to improve the throughput.\nTest perplexity on 1-Billion-Word language modeling benchmark. (Left) The model capacity increases from left to right, containing 4, 32, 256, 256, 1024 and 4096 experts. (Right) Performance of the 4 billion parameters MoE model, the largest one in the left figure, under different computation budgets. (Image source:\nShazeer et al., 2017\n)\nGShard\n(\nLepikhin et al., 2020\n) scales the MoE transformer model up to 600 billion parameters with sharding. The MoE transformer replaces every other feed forward layer with a MoE layer. The\nsharded MoE transformer\nonly has the MoE layers sharded across multiple machines, while other layers are simply duplicated.\nThere are several improved designs for the gating function $G$ in GShard:\nExpert capacity\n: The amount of tokens going through one expert should not go above a threshold, named “expert capacity”. If a token is routed to experts that have reached their capacity, the token would be marked “overflowed” and the gating output is changed to a zero vector.\nLocal group dispatching\n: Tokens are evenly partitioned into multiple local groups and the expert capacity is enforced on the group level.\nAuxiliary loss\n: The motivation is similar to the original MoE aux loss. They add an auxiliary loss to minimize the mean square of the fraction of data routed to each expert.\nRandom routing\n: The 2nd-best expert is selected with a probability proportional to its weight; otherwise, GShard follows a random routing, so as to add some randomness.\nPseudo code of the group-level top-2 gating mechanism with auxiliary loss in GShard. (Image source:\nLepikhin et al., 2020\n)\nSwitch Transformer\n(\nFedus et al. 2021\n) scales the model size up to trillions of parameters (!!) by replacing the dense feed forward layer with a\nsparse switch FFN layer\nin which each input is only routed to\none\nexpert network. The auxiliary loss for load balancing is $\\text{loss}_\\text{aux} = w_\\text{aux} \\sum_{i=1}^n f_i p_i$ given $n$ experts, where $f_i$ is the fraction of tokens routed to the $i$-th expert and $p_i$ is the routing probability for expert $i$ predicted by the gating network.\nSwitch transformer. The sparse switch FFN layer is in the blue boxes. (Image source:\nFedus et al. 2021\n)\nTo improve training stability, switch transformer incorporates the following designs:\nSelective precision\n. They showed that selectively casting only a local part of the model to FP32 precision improves stability, while avoiding the expensive communication cost of FP32 tensors. The FP32 precision is only used within the body of the router function and the results are recast to FP16.\nSmaller initialization\n. The initialization of weight matrices is sampled from a truncated normal distribution with mean $\\mu=0$ and stdev $\\sigma = \\sqrt{s/n}$. They also recommended reducing the transformer initialization scale parameter $s=1$ to $s=0.1$.\nUse higher expert dropout\n. Fine-tuning often works with a small dataset. To avoid overfitting, the dropout rate within each expert is increased by a significant amount. Interestingly they found that increasing dropout across all layers lead to poor performance. In the paper, they used a dropout rate 0.1 at non-expert layers but 0.4 within expert FF layers.\nThe switch transformer paper summarized different data and model parallelism strategies for training large models with a nice illustration:\nAn illustration of various parallelism strategies on how (Top) model weights and (Bottom) data are split over multiple GPU cores. In the top row, each color denotes a unique weight matrix. In the bottom row, different colors indicate different sets of tokens.  (Image source:\nFedus et al. 2021\n)\nBoth GShard top-2 and Switch Transformer top-1 depend on\ntoken choice\n, where each token picks the best one or two experts to route through. They both adopt an auxiliary loss to encourage more balanced load allocation but it does not guarantee the best performance. Furthermore, the expert capacity limit may lead to wasted tokens as they would be discarded if an expert reaches its capacity limit.\nExport Choice (EC)\n(\nZhou et al. 2022\n) routing instead enables each expert to select the top-$k$ tokens. In this way, each expert naturally guarantees a fixed capacity and each token may be routed to multiple experts. EC can achieve perfect load balancing and is shown to improve training convergence by 2x.\nGiven $e$ experts and an input matrix $X \\in \\mathbb{R}^{n \\times d}$, the token-to-expert affinity scores are computed by:\n$$\nS = \\text{softmax}(X \\cdot W_g), \\text{where } W_g \\in \\mathbb{R}^{d \\times e}, S \\in \\mathbb{R}^{n \\times e}\n$$\nA token-to-expert assignment is represented by three matrices, $I, G \\in \\mathbb{R}^{e\\times k}$ and $P \\in \\mathbb{R}^{e \\times k \\times n}$. $I[i,j]$ annotates which token is the $j$-th selection by the $i$-th expert. The gating matrix $G$ stores the routing weights of selected tokens. $P$ is the one-hot version of $I$, used to produce the input matrix ($P \\cdot X \\in \\mathbb{R}^{e \\times k \\times d}$) for the gated FFN layer.\n$$\nG, I = \\text{top-k}(S^\\top, k)\\quad P = \\text{one-hot}(I)\n$$\nOne regularization that export choice routing explored is to limit the maximum number of experts per token.\n$$\n\\begin{aligned}\n& \\max_A \\langle S^\\top, A\\rangle + \\lambda H(A) \\\\\n\\text{s.t.} & \n\\forall i: \\sum_{j'} A[i, j'] = k,\\quad\n\\forall j: \\sum_{i'} A[i', j] \\leq b,\\quad\n\\forall i,j: 0 \\leq A[i,j] \\leq 1\n\\end{aligned}\n$$\nwhere each entry $A[i,j]$ in $A \\in \\mathbb{R}^{e \\times n}$ marks whether the $i$-the expert selects the $j$-th token. Solving this is non-trivial. The paper used\nDykstra’s algorithm\nthat runs a sequence of multiple iterative computation steps. Capped expert choice results in a slight decrease in the fine-tuning performance in the experiments.\nThe parameter $k$ is determined by $k=nc/e$, where $n$ is the total number of tokens in one batch and $c$ is a capacity factor indicating the average number of experts used by one token. The paper used $c=2$ in most experiments, but EC with $c=1$ still outperforms the top-1 token choice gating. Interestingly, $c=0.5$ only marginally hurts the training performance.\nOne big drawback of EC is that it does not work when the batch size is too small, neither for auto-regressive text generation, because it needs to know the future tokens to do the top-$k$ selection.\nOther Memory Saving Designs\n#\nCPU Offloading\n#\nWhen the GPU memory is full, one option is to offload temporarily unused data to CPU and read them back when needed later (\nRhu et al. 2016\n). The idea of\nCPU offloading\nis straightforward but is less popular in recent years due to the slowdown it brings into the training time.\nActivation Recomputation\n#\nActivation recomputation\n(also known as “activation checkpointing” or “gradient checkpointing”;\nChen et al. 2016\n) is a smart yet simple idea to reduce memory footprint at the cost of computation time. It reduces the memory cost of training a $\\ell$ layer deep neural net to $O(\\sqrt{\\ell})$, which only additionally consumes an extra forward pass computation per batch.\nLet’s say, we evenly divide an $\\ell$-layer network into $d$ partitions. Only activations at partition boundaries are saved and communicated between workers. Intermediate activations at intra-partition layers are still needed for computing gradients so they are recomputed during backward passes. With activation recomputation, the memory cost for training $M(\\ell)$ is:\n$$\nM(\\ell) \n=\\max_{i=1,\\dots,k} \\underbrace{\\text{cost-of-one-partition}(i)}_\\text{cost of back-propagation on the i-th partition} + \\underbrace{O(d)}_\\text{store intermediate outputs} \n= O(\\frac{\\ell}{d}) + O(d)\n$$\nThe minimum cost is $O(\\sqrt{\\ell})$ at $d=\\sqrt{\\ell}$.\nActivation recompuation trick can give sublinear memory cost with respect to the model size.\nThe memory cost of different memory saving algorithms.\nSharing\n: Memory used by intermediate results is recycled when no longer needed.\nInplace\n: Save the output directly into memory of an input value. (Image source:\nChen et al. 2016\n)\nMixed Precision Training\n#\nNarang & Micikevicius et al. (2018)\nintroduced a method to train models using half-precision floating point (FP16) numbers without losing model accuracy.\nThe procedure of mixed precision training at one layer. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nThree techniques to avoid losing critical information at half-precision:\nFull-precision master copy of weights\n. Maintain a full precision (FP32) copy of model weights that accumulates gradients. The numbers are rounded up to half-precision for forward & backward passes. The motivation is that each gradient update (i.e. gradient times the learning rate) might be too small to be fully contained within the FP16 range (i.e. $2^{-24}$ becomes zero in FP16).\nLoss scaling\n. Scale up the loss to better handle gradients with small magnitudes (See Fig. 16). Scaling up the gradients helps shift them to occupy a larger section towards the right section (containing larger values) of the representable range, preserving values that are otherwise lost.\nArithmetic precision\n. For common network arithmetic (e.g. vector dot-product, reduction by summing up vector elements), we can accumulate the partial results in FP32 and then save the final output as FP16 before saving into memory. Point-wise operations can be executed in either FP16 or FP32.\nThe histogram of gradients in full precision. The left part up to $2^{-24}$ will be zero-ed off once the model switches to FP16. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nIn their experiments, loss scaling is not needed for some networks (e.g. image classification, Faster R-CNN), but necessary for others (e.g. Multibox SSD, big LSTM language model).\nCompression\n#\nIntermediate results often consume a lot of memory, although they are only needed in one forward pass and one backward pass. There is a noticeable temporal gap between these two uses. Thus\nJain et al. (2018)\nproposed a data encoding strategy to compress the intermediate results after the first use in the first pass and then decode it back for back-propagation later.\nTheir system\nGist\nincorporates two encoding schemes:\nLayer-specific lossless encoding\n; focus on ReLU-Pool (“Binarize”) and ReLU-Conv (“Sparse storage and dense computation”) patterns.\nAggressive lossy encoding\n; use delayed precision reduction (DPR). They observed that the first immediate use of feature maps should be kept at high precision but the second use can tolerate lower precision.\nThe experiments showed that Gist can reduce the memory cost by 2x across 5 SOTA image classification DNNs, with an average of 1.8x with only 4% performance overhead.\nMemory Efficient Optimizer\n#\nOptimizers are eager for memory consumption. Take the popular Adam optimizer as an example, it internally needs to maintain momentums and variances, both at the same scale as gradients and model parameters. All out of a sudden, we need to save 4x the memory of model weights.\nSeveral optimizers have been proposed to reduce the memory footprint.\nFor example, instead of storing the full momentums and variations as in Adam,\nAdafactor\n(\nShazeer et al. 2018\n) only tracks the per-row and per-column sums of the moving averages and then estimates the second moments based on these sums.\nSM3\n(\nAnil et al. 2019\n) describes a different adaptive optimization method, leading to largely reduced memory as well.\nZeRO\n(\nZero Redundancy Optimizer\n;\nRajbhandari et al. 2019\n) optimizes the memory used for training large models based on the observation about two major memory consumption of large model training:\nThe majority is occupied by\nmodel states\n, including optimizer states (e.g. Adam momentums and variances), gradients and parameters. Mixed-precision training demands a lot of memory since the optimizer needs to keep a copy of FP32 parameters and other optimizer states, besides the FP16 version.\nThe remaining is consumed by activations, temporary buffers and unusable fragmented memory (named\nresidual states\nin the paper).\nZeRO combines two approaches,\nZeRO-DP\nand\nZeRO-R\n.\nZeRO-DP is an enhanced data parallelism to avoid simple redundancy over model states. It partitions optimizer state, gradients and parameters across multiple data parallel processes via a dynamic communication schedule to minimize the communication volume.\nZeRO-R optimizes the memory consumption of residual states, using partitioned activation recomputation, constant buffer size and on-the-fly memory defragmentation.\nCitation\n#\nCited as:\nWeng, Lilian. (Sep 2021). How to train really large models on many GPUs? Lil’Log. https://lilianweng.github.io/posts/2021-09-25-train-large/.\nOr\n@article{weng2021large,\n  title   = \"How to Train Really Large Models on Many GPUs?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Sep\",\n  url     = \"https://lilianweng.github.io/posts/2021-09-25-train-large/\"\n}\nReferences\n#\n[1] Li et al.\n“PyTorch Distributed: Experiences on Accelerating Data Parallel Training”\nVLDB 2020.\n[2] Cui et al.\n“GeePS: Scalable deep learning on distributed GPUs with a GPU-specialized parameter server”\nEuroSys 2016\n[3] Shoeybi et al.\n“Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism.”\narXiv preprint arXiv:1909.08053 (2019).\n[4] Narayanan et al.\n“Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM.”\narXiv preprint arXiv:2104.04473 (2021).\n[5] Huang et al.\n“GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism.”\narXiv preprint arXiv:1811.06965 (2018).\n[6] Narayanan et al.\n“PipeDream: Generalized Pipeline Parallelism for DNN Training.”\nSOSP 2019.\n[7] Narayanan et al.\n“Memory-Efficient Pipeline-Parallel DNN Training.”\nICML 2021.\n[8] Shazeer et al.\n“The Sparsely-Gated Mixture-of-Experts Layer Noam.”\narXiv preprint arXiv:1701.06538 (2017).\n[9] Lepikhin et al.\n“GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding.”\narXiv preprint arXiv:2006.16668 (2020).\n[10] Fedus et al.\n“Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity.”\narXiv preprint arXiv:2101.03961 (2021).\n[11] Narang & Micikevicius, et al.\n“Mixed precision training.”\nICLR 2018.\n[12] Chen et al. 2016\n“Training Deep Nets with Sublinear Memory Cost.”\narXiv preprint arXiv:1604.06174 (2016).\n[13] Jain et al.\n“Gist: Efficient data encoding for deep neural network training.”\nISCA 2018.\n[14] Shazeer & Stern.\n“Adafactor: Adaptive learning rates with sublinear memory cost.”\narXiv preprint arXiv:1804.04235 (2018).\n[15] Anil et al.\n“Memory-Efficient Adaptive Optimization.”\narXiv preprint arXiv:1901.11150 (2019).\n[16] Rajbhandari et al.\n“ZeRO: Memory Optimization Towards Training A Trillion Parameter Models Samyam.”\narXiv preprint arXiv:1910.02054 (2019).\n[17] Zhou et al.\n“Mixture-of-Experts with Expert Choice Routing”\narXiv preprint arXiv:2202.09368 (2022).",
            "metadata": {
              "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
              "description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "keywords": "architecture, transformer, foundation",
              "author": "Lilian Weng",
              "og:title": "How to Train Really Large Models on Many GPUs?",
              "og:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
              "twitter:card": "summary",
              "twitter:title": "How to Train Really Large Models on Many GPUs?",
              "twitter:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "article:section": "posts",
              "article:published_time": "2021-09-24T00:00:00+00:00",
              "article:modified_time": "2021-09-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c811c8fa03ef/code/body-000.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "bytes": 439380,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-cd75f36109d9a8976ce6.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "bytes": 581069,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e0cb70b1716fc6541886.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "bytes": 124447,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-bae92611d020d867c823.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "bytes": 234189,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-5ede211aaa74090777be.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "bytes": 1134478,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-037e75ccc6667d3dd676.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "bytes": 169121,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-eb009e9e4995ad677d20.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "bytes": 238097,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e98d393b3034f7b93c42.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "bytes": 3433956,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-931034d1f77fea4a9b89.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "bytes": 279963,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-67ca3976dba24dedc5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "bytes": 137174,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e95985488d6654cc5673.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "bytes": 884311,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-6291c7ba7f2547d16349.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "bytes": 472655,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-49d8a2995980c00d678d.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "bytes": 191203,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-a407ab83faa199042c24.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "bytes": 237219,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-54c0cf380132c67d2456.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "bytes": 986067,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-595316073143c8f09324.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "bytes": 334330,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-7f21eb25c4d7577b7655.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "bytes": 235579,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-9ff79113319b46733509.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://gregbrockman.com/",
                "label": "Greg",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/techniques-for-training-large-neural-networks/",
                "label": "“Techniques for Training Large Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language models",
                "type": "a"
              },
              {
                "href": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "label": "Cui et al. 2016",
                "type": "a"
              },
              {
                "href": "https://pytorch.org/tutorials/intermediate/ddp_tutorial.html",
                "label": "DDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.15704",
                "label": "Li et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06965",
                "label": "Huang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "label": "Narayanan et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03377",
                "label": "Harlap et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09503",
                "label": "Narayanan et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.08053",
                "label": "Shoeybi et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.04473",
                "label": "Narayanan et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Ensemble_learning",
                "label": "ensembling learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1701.06538",
                "label": "Shazeer et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coefficient_of_variation",
                "label": "coefficient of variation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.16668",
                "label": "Lepikhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2101.03961",
                "label": "Fedus et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2202.09368",
                "label": "Zhou et al. 2022",
                "type": "a"
              },
              {
                "href": "https://projecteuclid.org/journals/annals-of-probability/volume-13/issue-3/An-Iterative-Procedure-for-Obtaining-I-Projections-onto-the-Intersection/10.1214/aop/1176992918.full",
                "label": "Dykstra’s algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.08124",
                "label": "Rhu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arvix.org/abs/1604.06174",
                "label": "Chen et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.03740",
                "label": "Narang & Micikevicius et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "label": "Jain et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.04235",
                "label": "Shazeer et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11150",
                "label": "Anil et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.02054",
                "label": "Rajbhandari et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.06174",
                "label": "“Training Deep Nets with Sublinear Memory Cost.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:18Z",
            "source_url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "bytes": 632686,
                "reused": false,
                "local_path": "papers/repair/52908466880352800110.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.15704",
                "bytes": 1189823,
                "reused": false,
                "local_path": "papers/repair/de67a2fc418e4e979224.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06965",
                "bytes": 539195,
                "reused": false,
                "local_path": "papers/repair/b679a01b9227418fd9a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "bytes": 1093659,
                "reused": false,
                "local_path": "papers/repair/df34f04afbea02133521.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03377",
                "bytes": 629717,
                "reused": false,
                "local_path": "papers/repair/2ff8970af5c2784cd9ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09503",
                "bytes": 2191490,
                "reused": false,
                "local_path": "papers/repair/e138d247bfb6dcf7dea8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.08053",
                "bytes": 3850425,
                "reused": false,
                "local_path": "papers/repair/331df4b1898d1b3265b5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.04473",
                "bytes": 1035739,
                "reused": false,
                "local_path": "papers/repair/27509164ea73ad0d546e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.06538",
                "bytes": 544288,
                "reused": true,
                "local_path": "papers/repair/f715adc72d48cc7ef55f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.16668",
                "bytes": 1747868,
                "reused": false,
                "local_path": "papers/repair/1a83e3dc287448c001ca.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2101.03961",
                "bytes": 1304157,
                "reused": false,
                "local_path": "papers/repair/a780b9df79db7592bd38.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2202.09368",
                "bytes": 605773,
                "reused": true,
                "local_path": "papers/repair/d8e47d8172aa52a16403.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.08124",
                "bytes": 2639789,
                "reused": false,
                "local_path": "papers/repair/84f5a94a2ee879df8044.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.03740",
                "bytes": 1404641,
                "reused": false,
                "local_path": "papers/repair/ac214b6a40a9661371fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "bytes": 376198,
                "reused": false,
                "local_path": "papers/repair/743cd4a4899a05f67033.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.04235",
                "bytes": 380566,
                "reused": false,
                "local_path": "papers/repair/367ee59650fbf06da8e5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11150",
                "bytes": 7715288,
                "reused": false,
                "local_path": "papers/repair/f11d7704ae7d73afb205.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.02054",
                "bytes": 779206,
                "reused": false,
                "local_path": "papers/repair/f9be62e9c42c011fccb3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.06174",
                "bytes": 608189,
                "reused": false,
                "local_path": "papers/repair/ab261736da2d952b7190.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29214,
            "expected_body_images": 17,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c811c8fa03ef/pages/source.html",
            "local_html": "attachments/c811c8fa03ef/pages/article.html",
            "body_base_path": "attachments/c811c8fa03ef/pages/",
            "body_markdown_path": "attachments/c811c8fa03ef/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
          "status": "partial",
          "article_id": "878201399682",
          "local_path": "series-follow/1600/repair/9bc8cee33939058ef446.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
              "bytes": 141343,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/bb6875cd3e5549abbcd1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
              "bytes": 200906,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f63f468d5b6f609fb860.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
              "bytes": 320117,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b9e6a98b0df645854fba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
              "bytes": 393303,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/d993cb03136583a0420d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
              "bytes": 299867,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/fc09fee591b88b9de59b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
              "bytes": 234229,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/87d8182dba34df99768a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
              "bytes": 153051,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/39271025b647a9d7c525.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
              "bytes": 969820,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/aaa694c2f42a8a7392e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
              "bytes": 281128,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/09d9fe883beab7d0f798.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
              "bytes": 263467,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/61258136fa6d92c338e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
              "bytes": 343247,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c5d63d539267ebf9a663.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
              "bytes": 131443,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/4b9f5c7d78f642b4b125.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
              "bytes": 255209,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/1feaf95f38447214362b.png"
            }
          ],
          "article": {
            "id": "878201399682",
            "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "bytes": 141343,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-bb6875cd3e5549abbcd1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "bytes": 200906,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-f63f468d5b6f609fb860.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "bytes": 320117,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-b9e6a98b0df645854fba.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "bytes": 393303,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-d993cb03136583a0420d.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "bytes": 299867,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-fc09fee591b88b9de59b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "bytes": 234229,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-87d8182dba34df99768a.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "bytes": 153051,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-39271025b647a9d7c525.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "bytes": 969820,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-aaa694c2f42a8a7392e9.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "bytes": 281128,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-09d9fe883beab7d0f798.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "bytes": 263467,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-61258136fa6d92c338e1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "bytes": 343247,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-c5d63d539267ebf9a663.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "bytes": 131443,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-4b9f5c7d78f642b4b125.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "bytes": 255209,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-1feaf95f38447214362b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Stochastic gradient descent is a universal choice for optimizing deep learning models. However, it is not the only option. With black-box optimization algorithms, you can evaluate a target function $f(x): \\mathbb{R}^n \\to \\mathbb{R}$, even when you don’t know the precise analytic form of $f(x)$ and thus cannot compute gradients or the Hessian matrix. Examples of black-box optimization methods include\nSimulated Annealing\n,\nHill Climbing\nand\nNelder-Mead method\n.\nEvolution Strategies (ES)\nis one type of black-box optimization algorithms, born in the family of\nEvolutionary Algorithms (EA)\n. In this post, I would dive into a couple of classic ES methods and introduce a few applications of how ES can play a role in deep reinforcement learning.\nWhat are Evolution Strategies?\n#\nEvolution strategies (ES) belong to the big family of evolutionary algorithms. The optimization targets of ES are vectors of real numbers, $x \\in \\mathbb{R}^n$.\nEvolutionary algorithms refer to a division of population-based optimization algorithms inspired by\nnatural selection\n. Natural selection believes that individuals with traits beneficial to their survival can live through generations and pass down the good characteristics to the next generation. Evolution happens by the selection process gradually and the population grows better adapted to the environment.\nHow natural selection works. (Image source: Khan Academy:\nDarwin, evolution, & natural selection\n)\nEvolutionary algorithms can be summarized in the following\nformat\nas a general optimization solution:\nLet’s say we want to optimize a function $f(x)$ and we are not able to compute gradients directly. But we still can evaluate $f(x)$ given any $x$ and the result is deterministic. Our belief in the probability distribution over $x$ as a good solution to $f(x)$ optimization is $p_\\theta(x)$, parameterized by $\\theta$. The goal is to find an optimal configuration of $\\theta$.\nHere given a fixed format of distribution (i.e. Gaussian), the parameter $\\theta$ carries  the knowledge about the best solutions and is being iteratively updated across generations.\nStarting with an initial value of $\\theta$, we can continuously update $\\theta$ by looping three steps as follows:\nGenerate a population of samples $D = \\{(x_i, f(x_i)\\}$ where $x_i \\sim p_\\theta(x)$.\nEvaluate the “fitness” of samples in $D$.\nSelect the best subset of individuals and use them to update $\\theta$, generally based on fitness or rank.\nIn\nGenetic Algorithms (GA)\n, another popular subcategory of EA, $x$ is a sequence of binary codes, $x \\in \\{0, 1\\}^n$. While in ES, $x$ is just a vector of real numbers, $x \\in \\mathbb{R}^n$.\nSimple Gaussian Evolution Strategies\n#\nThis\nis the most basic and canonical version of evolution strategies. It models $p_\\theta(x)$ as a $n$-dimensional isotropic Gaussian distribution, in which $\\theta$ only tracks the mean $\\mu$ and standard deviation $\\sigma$.\n$$\n\\theta = (\\mu, \\sigma),\\;p_\\theta(x) \\sim \\mathcal{N}(\\mathbf{\\mu}, \\sigma^2 I) = \\mu + \\sigma \\mathcal{N}(0, I)\n$$\nThe process of Simple-Gaussian-ES, given $x \\in \\mathcal{R}^n$:\nInitialize $\\theta = \\theta^{(0)}$ and the generation counter $t=0$\nGenerate the offspring population of size $\\Lambda$ by sampling from the Gaussian distribution:\n$D^{(t+1)}=\\{ x^{(t+1)}_i \\mid x^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{ where } y^{(t+1)}_i \\sim \\mathcal{N}(x \\vert 0, \\mathbf{I}),;i = 1, \\dots, \\Lambda\\}$\n.\nSelect a top subset of $\\lambda$ samples with optimal $f(x_i)$ and this subset is called\nelite\nset. Without loss of generality, we may consider the first $k$ samples in $D^{(t+1)}$ to belong to the elite group — Let’s label them as\n$$\n  D^{(t+1)}\\_\\text{elite} = \\\\{x^{(t+1)}\\_i \\mid x^{(t+1)}\\_i \\in D^{(t+1)}, i=1,\\dots, \\lambda, \\lambda\\leq \\Lambda\\\\}\n  $$\nThen we estimate the new mean and std for the next generation using the elite set:\n$$\n  \\begin{aligned}\n  \\mu^{(t+1)} &= \\text{avg}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda x_i^{(t+1)} \\\\\n  {\\sigma^{(t+1)}}^2 &= \\text{var}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} -\\mu^{(t)})^2\n  \\end{aligned}\n  $$\nRepeat steps (2)-(4) until the result is good enough ✌️\nCovariance Matrix Adaptation Evolution Strategies (CMA-ES)\n#\nThe standard deviation $\\sigma$ accounts for the level of exploration: the larger $\\sigma$ the bigger search space we can sample our offspring population. In\nvanilla ES\n, $\\sigma^{(t+1)}$ is highly correlated with $\\sigma^{(t)}$, so the algorithm is not able to rapidly adjust the exploration space when needed (i.e. when the confidence level changes).\nCMA-ES\n, short for\n“Covariance Matrix Adaptation Evolution Strategy”\n, fixes the problem by tracking pairwise dependencies between the samples in the distribution with a covariance matrix $C$. The new distribution parameter becomes:\n$$\n\\theta = (\\mu, \\sigma, C),\\; p_\\theta(x) \\sim \\mathcal{N}(\\mu, \\sigma^2 C) \\sim \\mu + \\sigma \\mathcal{N}(0, C)\n$$\nwhere $\\sigma$ controls for the overall scale of the distribution,  often known as\nstep size\n.\nBefore we dig into how the parameters are updated in CMA-ES, it is better to review how the covariance matrix works in the multivariate Gaussian distribution first. As a real symmetric matrix, the covariance matrix $C$ has the following nice features (See\nproof\n&\nproof\n):\nIt is always diagonalizable.\nAlways positive semi-definite.\nAll of its eigenvalues are real non-negative numbers.\nAll of its eigenvectors are orthogonal.\nThere is an orthonormal basis of $\\mathbb{R}^n$ consisting of its eigenvectors.\nLet the matrix $C$ have an\northonormal\nbasis of eigenvectors $B = [b_1, \\dots, b_n]$, with corresponding eigenvalues $\\lambda_1^2, \\dots, \\lambda_n^2$. Let $D=\\text{diag}(\\lambda_1, \\dots, \\lambda_n)$.\n$$\nC = B^\\top D^2 B\n= \\begin{bmatrix} \n\\mid & \\mid &  & \\mid \\\\\nb_1 & b_2 & \\dots & b_n\\\\\n\\mid & \\mid &  & \\mid \\\\\n\\end{bmatrix}\n\\begin{bmatrix}\n\\lambda_1^2 & 0 & \\dots & 0 \\\\\n0 & \\lambda_2^2 & \\dots & 0 \\\\\n\\vdots & \\dots & \\ddots & \\vdots \\\\\n0 & \\dots & 0 & \\lambda_n^2\n\\end{bmatrix}\n\\begin{bmatrix} \n- & b_1 & - \\\\\n- & b_2 & - \\\\\n  & \\dots & \\\\\n- & b_n & - \\\\\n\\end{bmatrix}\n$$\nThe square root of $C$ is:\n$$\nC^{\\frac{1}{2}} = B^\\top D B\n$$\nSymbol\nMeaning\n$x_i^{(t)} \\in \\mathbb{R}^n$\nthe $i$-th samples at the generation (t)\n$y_i^{(t)} \\in \\mathbb{R}^n$\n$x_i^{(t)} = \\mu^{(t-1)} + \\sigma^{(t-1)} y_i^{(t)} $\n$\\mu^{(t)}$\nmean of the generation (t)\n$\\sigma^{(t)}$\nstep size\n$C^{(t)}$\ncovariance matrix\n$B^{(t)}$\na matrix of $C$’s eigenvectors as row vectors\n$D^{(t)}$\na diagonal matrix with $C$’s eigenvalues on the diagnose.\n$p_\\sigma^{(t)}$\nevaluation path for $\\sigma$ at the generation (t)\n$p_c^{(t)}$\nevaluation path for $C$ at the generation (t)\n$\\alpha_\\mu$\nlearning rate for $\\mu$’s update\n$\\alpha_\\sigma$\nlearning rate for $p_\\sigma$\n$d_\\sigma$\ndamping factor for $\\sigma$’s update\n$\\alpha_{cp}$\nlearning rate for $p_c$\n$\\alpha_{c\\lambda}$\nlearning rate for $C$’s rank-min(λ, n) update\n$\\alpha_{c1}$\nlearning rate for $C$’s rank-1 update\nUpdating the Mean\n#\n$$\n\\mu^{(t+1)} = \\mu^{(t)} + \\alpha_\\mu \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})\n$$\nCMA-ES has a learning rate $\\alpha_\\mu \\leq 1$ to control how fast the mean $\\mu$ should be updated.  Usually it is set to 1 and thus the equation becomes the same as in vanilla ES, $\\mu^{(t+1)} = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)}$.\nControlling the Step Size\n#\nThe sampling process can be decoupled from the mean and standard deviation:\n$$\nx^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{, where } y^{(t+1)}_i = \\frac{x_i^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)\n$$\nThe parameter $\\sigma$ controls the overall scale of the distribution. It is separated from the covariance matrix so that we can change steps faster than the full covariance. A larger step size leads to faster parameter update. In order to evaluate whether the current step size is proper, CMA-ES constructs an\nevolution path\n$p_\\sigma$ by summing up a consecutive sequence of moving steps, $\\frac{1}{\\lambda}\\sum_{i}^\\lambda y_i^{(j)}, j=1, \\dots, t$. By comparing this path length with its expected length under random selection (meaning single steps are uncorrelated), we are able to adjust $\\sigma$ accordingly (See Fig. 2).\nThree scenarios of how single steps are correlated in different ways and their impacts on step size update. (Image source: additional annotations on Fig 5 in\nCMA-ES tutorial\npaper)\nEach time the evolution path is updated with the average of moving step $y_i$ in the same generation.\n$$\n\\begin{aligned}\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n= \\frac{1}{\\lambda} \\frac{\\sum_{i=1}^\\lambda x_i^{(t+1)} - \\lambda \\mu^{(t)}}{\\sigma^{(t)}}\n= \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n\\sim \\frac{1}{\\lambda}\\mathcal{N}(0, \\lambda C^{(t)}) \n\\sim \\frac{1}{\\sqrt{\\lambda}}{C^{(t)}}^{\\frac{1}{2}}\\mathcal{N}(0, I) \\\\\n&\\text{Thus } \\sqrt{\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nBy multiplying with $C^{-\\frac{1}{2}}$, the evolution path is transformed to be independent of its direction. The term ${C^{(t)}}^{-\\frac{1}{2}} = {B^{(t)}}^\\top {D^{(t)}}^{-\\frac{1}{2}} {B^{(t)}}$ transformation works as follows:\n${B^{(t)}}$ contains row vectors of $C$’s eigenvectors. It projects the original space onto the perpendicular principal axes.\nThen ${D^{(t)}}^{-\\frac{1}{2}} = \\text{diag}(\\frac{1}{\\lambda_1}, \\dots, \\frac{1}{\\lambda_n})$ scales the length of principal axes to be equal.\n${B^{(t)}}^\\top$ transforms the space back to the original coordinate system.\nIn order to assign higher weights to recent generations, we use polyak averaging to update the evolution path with learning rate $\\alpha_\\sigma$. Meanwhile, the weights are balanced so that $p_\\sigma$ is\nconjugate\n, $\\sim \\mathcal{N}(0, I)$ both before and after one update.\n$$\n\\begin{aligned}\np_\\sigma^{(t+1)} \n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{1 - (1 - \\alpha_\\sigma)^2}\\;\\sqrt{\\lambda}\\; {C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{c_\\sigma (2 - \\alpha_\\sigma)\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThe expected length of $p_\\sigma$ under random selection is $\\mathbb{E}|\\mathcal{N}(0,I)|$, that is the expectation of the L2-norm of a $\\mathcal{N}(0,I)$ random variable. Following the idea in Fig. 2, we adjust the step size according to the ratio of $|p_\\sigma^{(t+1)}| / \\mathbb{E}|\\mathcal{N}(0,I)|$:\n$$\n\\begin{aligned}\n\\ln\\sigma^{(t+1)} &= \\ln\\sigma^{(t)} + \\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big) \\\\\n\\sigma^{(t+1)} &= \\sigma^{(t)} \\exp\\Big(\\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big)\\Big)\n\\end{aligned}\n$$\nwhere $d_\\sigma \\approx 1$ is a damping parameter, scaling how fast $\\ln\\sigma$ should be changed.\nAdapting the Covariance Matrix\n#\nFor the covariance matrix, it can be estimated from scratch using $y_i$ of elite samples (recall that $y_i \\sim \\mathcal{N}(0, C)$):\n$$\nC_\\lambda^{(t+1)} \n= \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n= \\frac{1}{\\lambda {\\sigma^{(t)}}^2} \\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})(x_i^{(t+1)} - \\mu^{(t)})^\\top\n$$\nThe above estimation is only reliable when the selected population is large enough. However, we do want to run\nfast\niteration with a\nsmall\npopulation of samples in each generation. That’s why CMA-ES invented a more reliable but also more complicated way to update $C$. It involves two independent routes,\nRank-min(λ, n) update\n: uses the history of $\\{C_\\lambda\\}$, each estimated from scratch in one generation.\nRank-one update\n: estimates the moving steps $y_i$ and the sign information from the history.\nThe first route considers the estimation of $C$ from the entire history of $\\{C_\\lambda\\}$. For example, if we have experienced a large number of generations, $C^{(t+1)} \\approx \\text{avg}(C_\\lambda^{(i)}; i=1,\\dots,t)$ would be a good estimator. Similar to $p_\\sigma$, we also use polyak averaging with a learning rate to incorporate the history:\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} C_\\lambda^{(t+1)}\n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n$$\nA common choice for the learning rate is $\\alpha_{c\\lambda} \\approx \\min(1, \\lambda/n^2)$.\nThe second route tries to solve the issue that $y_i{y_i}^\\top = (-y_i)(-y_i)^\\top$ loses the sign information. Similar to how we adjust the step size $\\sigma$, an evolution path $p_c$ is used to track the sign information and it is constructed in a way that $p_c$ is conjugate, $\\sim \\mathcal{N}(0, C)$ both before and after a new generation.\nWe may consider $p_c$ as another way to compute $\\text{avg}_i(y_i)$ (notice that both $\\sim \\mathcal{N}(0, C)$) while the entire history is used and the sign information is maintained. Note that we’ve known $\\sqrt{k}\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)$ in the\nlast section\n,\n$$\n\\begin{aligned}\np_c^{(t+1)} \n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{1 - (1-\\alpha_{cp})^2}\\;\\sqrt{\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{\\alpha_{cp}(2 - \\alpha_{cp})\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThen the covariance matrix is updated according to $p_c$:\n$$\nC^{(t+1)} = (1-\\alpha_{c1}) C^{(t)} + \\alpha_{c1}\\;p_c^{(t+1)} {p_c^{(t+1)}}^\\top\n$$\nThe\nrank-one update\napproach is claimed to generate a significant improvement over the\nrank-min(λ, n)-update\nwhen $k$ is small, because the signs of moving steps and correlations between consecutive steps are all utilized and passed down through generations.\nEventually we combine two approaches together,\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda} - \\alpha_{c1}) C^{(t)}\n+ \\alpha_{c1}\\;\\underbrace{p_c^{(t+1)} {p_c^{(t+1)}}^\\top}_\\textrm{rank-one update}\n+ \\alpha_{c\\lambda} \\underbrace{\\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top}_\\textrm{rank-min(lambda, n) update}\n$$\nIn all my examples above, each elite sample is considered to contribute an equal amount of weights, $1/\\lambda$. The process can be easily extended to the case where selected samples are assigned with different weights, $w_1, \\dots, w_\\lambda$, according to their performances. See more detail in\ntutorial\n.\nIllustration of how CMA-ES works on a 2D optimization problem (the lighter color the better). Black dots are samples in one generation. The samples are more spread out initially but when the model has higher confidence in finding a good solution in the late stage, the samples become very concentrated over the global optimum. (Image source:\nWikipedia CMA-ES\n)\nNatural Evolution Strategies\n#\nNatural Evolution Strategies (\nNES\n;\nWierstra, et al, 2008\n) optimizes in a search distribution of parameters and moves the distribution in the direction of high fitness indicated by the\nnatural gradient\n.\nNatural Gradients\n#\nGiven an objective function $\\mathcal{J}(\\theta)$ parameterized by $\\theta$, let’s say our goal is to find the optimal $\\theta$ to maximize the objective function value. A\nplain gradient\nfinds the steepest direction within a small Euclidean distance from the current $\\theta$; the distance restriction is applied on the parameter space. In other words, we compute the plain gradient with respect to a small change of the absolute value of $\\theta$. The optimal step is:\n$$\nd^{*} = \\operatorname*{argmax}_{\\|d\\| = \\epsilon} \\mathcal{J}(\\theta + d)\\text{, where }\\epsilon \\to 0\n$$\nDifferently,\nnatural gradient\nworks with a probability\ndistribution\nspace\nparameterized by $\\theta$, $p_\\theta(x)$ (referred to as “search distribution” in NES\npaper\n). It looks for the steepest direction within a small step in the distribution space where the distance is measured by KL divergence. With this constraint we ensure that each update is moving along the distributional manifold with constant speed, without being slowed down by its curvature.\n$$\nd^{*}_\\text{N} = \\operatorname*{argmax}_{\\text{KL}[p_\\theta \\| p_{\\theta+d}] = \\epsilon} \\mathcal{J}(\\theta + d)\n$$\nEstimation using Fisher Information Matrix\n#\nBut, how to compute $\\text{KL}[p_\\theta | p_{\\theta+\\Delta\\theta}]$ precisely? By running Taylor expansion of $\\log p_{\\theta + d}$ at $\\theta$, we get:\n$$\n\\begin{aligned}\n& \\text{KL}[p_\\theta \\| p_{\\theta+d}] \\\\\n&= \\mathbb{E}_{x \\sim p_\\theta} [\\log p_\\theta(x) - \\log p_{\\theta+d}(x)] & \\\\\n&\\approx \\mathbb{E}_{x \\sim p_\\theta} [ \\log p_\\theta(x) -( \\log p_{\\theta}(x) + \\nabla_\\theta \\log p_{\\theta}(x) d + \\frac{1}{2}d^\\top \\nabla^2_\\theta \\log p_{\\theta}(x) d)] & \\scriptstyle{\\text{; Taylor expand }\\log p_{\\theta+d}} \\\\\n&\\approx - \\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}(x)] d - \\frac{1}{2}d^\\top \\mathbb{E}_x [\\nabla^2_\\theta \\log p_{\\theta}(x)] d & \n\\end{aligned}\n$$\nwhere\n$$\n\\begin{aligned}\n\\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}] d \n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) & \\\\\n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\frac{1}{p_\\theta(x)} \\nabla_\\theta p_\\theta(x) & \\\\\n&= \\nabla_\\theta \\Big( \\int_{x} p_\\theta(x) \\Big) & \\scriptstyle{\\textrm{; note that }p_\\theta(x)\\textrm{ is probability distribution.}} \\\\\n&= \\nabla_\\theta (1) = 0\n\\end{aligned}\n$$\nFinally we have,\n$$\n\\text{KL}[p_\\theta \\| p_{\\theta+d}] = - \\frac{1}{2}d^\\top \\mathbf{F}_\\theta d \n\\text{, where }\\mathbf{F}_\\theta = \\mathbb{E}_x [(\\nabla_\\theta \\log p_{\\theta}) (\\nabla_\\theta \\log p_{\\theta})^\\top]\n$$\nwhere $\\mathbf{F}_\\theta$ is called the\nFisher Information Matrix\nand\nit is\nthe covariance matrix of $\\nabla_\\theta \\log p_\\theta$ since $\\mathbb{E}[\\nabla_\\theta \\log p_\\theta] = 0$.\nThe solution to the following optimization problem:\n$$\n\\max \\mathcal{J}(\\theta + d) \\approx \\max \\big( \\mathcal{J}(\\theta) + {\\nabla_\\theta\\mathcal{J}(\\theta)}^\\top d \\big)\\;\\text{ s.t. }\\text{KL}[p_\\theta \\| p_{\\theta+d}] - \\epsilon = 0\n$$\ncan be found using a Lagrangian multiplier,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta, d, \\beta) &= \\mathcal{J}(\\theta) + \\nabla_\\theta\\mathcal{J}(\\theta)^\\top d - \\beta (\\frac{1}{2}d^\\top \\mathbf{F}_\\theta d + \\epsilon) = 0 \\text{ s.t. } \\beta > 0 \\\\\n\\nabla_d \\mathcal{L}(\\theta, d, \\beta) &= \\nabla_\\theta\\mathcal{J}(\\theta) - \\beta\\mathbf{F}_\\theta d = 0 \\\\\n\\text{Thus } d_\\text{N}^* &= \\nabla_\\theta^\\text{N} \\mathcal{J}(\\theta) = \\mathbf{F}_\\theta^{-1} \\nabla_\\theta\\mathcal{J}(\\theta) \n\\end{aligned}\n$$\nwhere $d_\\text{N}^*$ only extracts the direction of the optimal moving step on $\\theta$, ignoring the scalar $\\beta^{-1}$.\nThe natural gradient samples (black solid arrows) in the right are the plain gradient samples (black solid arrows)  in the left multiplied by the inverse of their covariance. In this way, a gradient direction with high uncertainty (indicated by high covariance with other samples) are penalized with a small weight. The aggregated natural gradient (red dash arrow) is therefore more trustworthy than the natural gradient (green solid arrow). (Image source: additional annotations on Fig 2 in\nNES\npaper)\nNES Algorithm\n#\nThe fitness associated with one sample is labeled as $f(x)$ and the search distribution over $x$ is parameterized by $\\theta$. NES is expected to optimize the parameter $\\theta$ to achieve maximum expected fitness:\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{x\\sim p_\\theta(x)} [f(x)] = \\int_x f(x) p_\\theta(x) dx\n$$\nUsing the same log-likelihood\ntrick\nin\nREINFORCE\n:\n$$\n\\begin{aligned}\n\\nabla_\\theta\\mathcal{J}(\\theta) \n&= \\nabla_\\theta \\int_x f(x) p_\\theta(x) dx \\\\\n&= \\int_x f(x) \\frac{p_\\theta(x)}{p_\\theta(x)}\\nabla_\\theta p_\\theta(x) dx \\\\\n& = \\int_x f(x) p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) dx \\\\\n& = \\mathbb{E}_{x \\sim p_\\theta} [f(x) \\nabla_\\theta \\log p_\\theta(x)]\n\\end{aligned}\n$$\nBesides natural gradients, NES adopts a couple of important heuristics to make the algorithm performance more robust.\nNES applies\nrank-based fitness shaping\n, that is to use the\nrank\nunder monotonically increasing fitness values instead of using $f(x)$ directly. Or it can be a function of the rank (“utility function”), which is considered as a free parameter of NES.\nNES adopts\nadaptation sampling\nto adjust hyperparameters at run time. When changing $\\theta \\to \\theta’$, samples drawn from $p_\\theta$ are compared with samples from $p_{\\theta’}$ using [Mann-Whitney U-test(https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test)]; if there shows a positive or negative sign, the target hyperparameter decreases or increases by a multiplication constant. Note the score of a sample $x’_i \\sim p_{\\theta’}(x)$ has importance sampling weights applied $w_i’ = p_\\theta(x) / p_{\\theta’}(x)$.\nApplications: ES in Deep Reinforcement Learning\n#\nOpenAI ES for RL\n#\nThe concept of using evolutionary algorithms in reinforcement learning can be traced back\nlong ago\n, but only constrained to tabular RL due to computational limitations.\nInspired by\nNES\n, researchers at OpenAI (\nSalimans, et al. 2017\n) proposed to use NES as a gradient-free black-box optimizer to find optimal policy parameters $\\theta$ that maximizes the return function $F(\\theta)$. The key is to add Gaussian noise $\\epsilon$ on the model parameter $\\theta$ and then use the log-likelihood trick to write it as the gradient of the Gaussian pdf. Eventually only the noise term is left as a weighting scalar for measured performance.\nLet’s say the current parameter value is $\\hat{\\theta}$ (the added hat is to distinguish the value from the random variable $\\theta$). The search distribution of $\\theta$ is designed to be an isotropic multivariate Gaussian with a mean $\\hat{\\theta}$ and a fixed covariance matrix $\\sigma^2 I$,\n$$\n\\theta \\sim \\mathcal{N}(\\hat{\\theta}, \\sigma^2 I) \\text{ equivalent to } \\theta = \\hat{\\theta} + \\sigma\\epsilon, \\epsilon \\sim \\mathcal{N}(0, I)\n$$\nThe gradient for $\\theta$ update is:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} F(\\theta) \\\\\n&= \\nabla_\\theta \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} F(\\hat{\\theta} + \\sigma\\epsilon) \\\\\n&= \\nabla_\\theta \\int_{\\epsilon} p(\\epsilon) F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; Gaussian }p(\\epsilon)=(2\\pi)^{-\\frac{n}{2}} \\exp(-\\frac{1}{2}\\epsilon^\\top\\epsilon)} \\\\\n&= \\int_{\\epsilon} p(\\epsilon) \\nabla_\\epsilon \\log p(\\epsilon) \\nabla_\\theta \\epsilon\\;F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; log-likelihood trick}}\\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\nabla_\\epsilon \\big(-\\frac{1}{2}\\epsilon^\\top\\epsilon\\big) \\nabla_\\theta \\big(\\frac{\\theta - \\hat{\\theta}}{\\sigma}\\big) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ (-\\epsilon) (\\frac{1}{\\sigma}) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\scriptstyle{\\text{; negative sign can be absorbed.}}\n\\end{aligned}\n$$\nIn one generation, we can sample many $epsilon_i, i=1,\\dots,n$ and evaluate the fitness\nin parallel\n. One beautiful design is that no large model parameter needs to be shared. By only communicating the random seeds between workers, it is enough for the master node to do parameter update. This approach is later extended to adaptively learn a loss function; see my previous post on\nEvolved Policy Gradient\n.\nThe algorithm for training a RL policy using evolution strategies. (Image source:\nES-for-RL\npaper)\nTo make the performance more robust, OpenAI ES adopts virtual batch normalization (BN with mini-batch used for calculating statistics fixed), mirror sampling (sampling a pair of $(-\\epsilon, \\epsilon)$ for evaluation), and\nfitness shaping\n.\nExploration with ES\n#\nExploration (\nvs exploitation\n) is an important topic in RL. The optimization direction in the ES algorithm\nabove\nis only extracted from the cumulative return $F(\\theta)$. Without explicit exploration, the agent might get trapped in a local optimum.\nNovelty-Search ES (\nNS-ES\n;\nConti et al, 2018\n) encourages exploration by updating the parameter in the direction to maximize the\nnovelty\nscore. The novelty score depends on a domain-specific behavior characterization function $b(\\pi_\\theta)$. The choice of $b(\\pi_\\theta)$ is specific to the task and seems to be a bit arbitrary; for example, in the Humanoid locomotion task in the paper, $b(\\pi_\\theta)$ is the final $(x,y)$ location of the agent.\nEvery policy’s $b(\\pi_\\theta)$ is pushed to an archive set $\\mathcal{A}$.\nNovelty of a policy $\\pi_\\theta$ is measured as the k-nearest neighbor score between $b(\\pi_\\theta)$ and all other entries in $\\mathcal{A}$.\n(The use case of the archive set sounds quite similar to\nepisodic memory\n.)\n$$\nN(\\theta, \\mathcal{A}) = \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda \\| b(\\pi_\\theta), b^\\text{knn}_i \\|_2\n\\text{, where }b^\\text{knn}_i \\in \\text{kNN}(b(\\pi_\\theta), \\mathcal{A})\n$$\nThe ES optimization step relies on the novelty score instead of fitness:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} N(\\theta, \\mathcal{A})\n= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon N(\\hat{\\theta} + \\sigma\\epsilon, \\mathcal{A}) ]\n$$\nNS-ES maintains a group of $M$ independently trained agents (“meta-population”), $\\mathcal{M} = \\{\\theta_1, \\dots, \\theta_M \\}$ and picks one to advance proportional to the novelty score. Eventually we select the best policy. This process is equivalent to ensembling; also see the same idea in\nSVPG\n.\n$$\n\\begin{aligned}\nm &\\leftarrow \\text{pick } i=1,\\dots,M\\text{ according to probability}\\frac{N(\\theta_i, \\mathcal{A})}{\\sum_{j=1}^M N(\\theta_j, \\mathcal{A})} \\\\\n\\theta_m^{(t+1)} &\\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) \\text{ where }\\epsilon_i \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nwhere $N$ is the number of Gaussian perturbation noise vectors and $\\alpha$ is the learning rate.\nNS-ES completely discards the reward function and only optimizes for novelty to avoid deceptive local optima. To incorporate the fitness back into the formula, another two variations are proposed.\nNSR-ES\n:\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\frac{N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + F(\\theta^{(t)}_m + \\epsilon_i)}{2}\n$$\nNSRAdapt-ES (NSRA-ES)\n: the adaptive weighting parameter $w = 1.0$ initially. We start decreasing $w$ if performance stays flat for a number of generations. Then when the performance starts to increase, we stop decreasing $w$ but increase it instead. In this way, fitness is preferred when the performance stops growing but novelty is preferred otherwise.\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\big((1-w) N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + w F(\\theta^{(t)}_m + \\epsilon_i)\\big)\n$$\n(Left) The environment is Humanoid locomotion with a three-sided wall which plays a role as a deceptive trap to create local optimum. (Right) Experiments compare ES baseline and other variations that encourage exploration. (Image source:\nNS-ES\npaper)\nCEM-RL\n#\nArchitectures of the (a) CEM-RL and (b)\nERL\nalgorithms (Image source:\nCEM-RL\npaper)\nThe CEM-RL method (\nPourchot & Sigaud, 2019\n) combines Cross Entropy Method (CEM) with either\nDDPG\nor\nTD3\n. CEM here works pretty much the same as the simple Gaussian ES described\nabove\nand therefore the same function can be replaced using CMA-ES. CEM-RL is built on the framework of\nEvolutionary Reinforcement Learning\n(\nERL\n;\nKhadka & Tumer, 2018\n) in which the standard EA algorithm selects and evolves a population of actors and the rollout experience generated in the process is then added into reply buffer for training both RL-actor and RL-critic networks.\nWorkflow:\nThe mean actor of the CEM population is $\\pi_\\mu$ is initialized with a random actor network.\nThe critic network $Q$ is initialized too, which will be updated by DDPG/TD3.\nRepeat until happy:\na. Sample a population of actors $\\sim \\mathcal{N}(\\pi_\\mu, \\Sigma)$.\nb. Half of the population is evaluated. Their fitness scores are used as the cumulative reward $R$ and added into replay buffer.\nc. The other half are updated together with the critic.\nd. The new $\\pi_mu$ and $\\Sigma$ is computed using top performing elite samples.\nCMA-ES\ncan be used for parameter update too.\nExtension: EA in Deep Learning\n#\n(This section is not on evolution strategies, but still an interesting and relevant reading.)\nThe\nEvolutionary Algorithms\nhave been applied on many deep learning problems. POET (\nWang et al, 2019\n) is a framework based on EA and attempts to generate a variety of different tasks while the problems themselves are being solved. POET has been introduced in my\nlast post\non meta-RL. Evolutionary Reinforcement Learning (ERL) is another example; See Fig. 7 (b).\nBelow I would like to introduce two applications in more detail,\nPopulation-Based Training (PBT)\nand\nWeight-Agnostic Neural Networks (WANN)\n.\nHyperparameter Tuning: PBT\n#\nParadigms of comparing different ways of hyperparameter tuning. (Image source:\nPBT\npaper)\nPopulation-Based Training (\nJaderberg, et al, 2017\n), short for\nPBT\napplies EA on the problem of hyperparameter tuning. It jointly trains a population of models and corresponding hyperparameters for optimal performance.\nPBT starts with a set of random candidates, each containing a pair of model weights initialization and hyperparameters, $\\{(\\theta_i, h_i)\\mid i=1, \\dots, N\\}$. Every sample is trained in parallel and asynchronously evaluates its own performance periodically. Whenever a member deems ready (i.e. after taking enough gradient update steps, or when the performance is good enough), it has a chance to be updated by comparing with the whole population:\nexploit()\n: When this model is under-performing, the weights could be replaced with a better performing model.\nexplore()\n: If the model weights are overwritten,\nexplore\nstep perturbs the hyperparameters with random noise.\nIn this process, only promising model and hyperparameter pairs can survive and keep on evolving, achieving better utilization of computational resources.\nThe algorithm of population-based training. (Image source:\nPBT\npaper)\nNetwork Topology Optimization: WANN\n#\nWeight Agnostic Neural\nNetworks (short for\nWANN\n;\nGaier & Ha 2019\n) experiments with searching for the smallest network topologies that can achieve the optimal performance without training the network weights. By not considering the best configuration of network weights, WANN puts much more emphasis on the architecture itself, making the focus different from\nNAS\n. WANN is heavily inspired by a classic genetic algorithm to evolve network topologies, called\nNEAT\n(“Neuroevolution of Augmenting Topologies”;\nStanley & Miikkulainen 2002\n).\nThe workflow of WANN looks pretty much the same as standard GA:\nInitialize: Create a population of minimal networks.\nEvaluation: Test with a range of\nshared\nweight values.\nRank and Selection: Rank by performance and complexity.\nMutation: Create new population by varying best networks.\nmutation operations for searching for new network topologies in WANN (Image source:\nWANN\npaper)\nAt the “evaluation” stage, all the network weights are set to be the same. In this way, WANN is actually searching for network that can be described with a minimal description length. In the “selection” stage, both the network connection and the model performance are considered.\nPerformance of WANN found network topologies on different RL tasks are compared with baseline FF networks commonly used in the literature. \"Tuned Shared Weight\" only requires adjusting one weight value. (Image source:\nWANN\npaper)\nAs shown in Fig. 11, WANN results are evaluated with both random weights and shared weights (single weight). It is interesting that even when enforcing weight-sharing on all weights and tuning this single parameter, WANN can discover topologies that achieve non-trivial good performance.\nCited as:\n@article{weng2019ES,\n  title   = \"Evolution Strategies\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/\"\n}\nReferences\n#\n[1] Nikolaus Hansen.\n“The CMA Evolution Strategy: A Tutorial”\narXiv preprint arXiv:1604.00772 (2016).\n[2] Marc Toussaint.\nSlides: “Introduction to Optimization”\n[3] David Ha.\n“A Visual Guide to Evolution Strategies”\nblog.otoro.net. Oct 2017.\n[4] Daan Wierstra, et al.\n“Natural evolution strategies.”\nIEEE World Congress on Computational Intelligence, 2008.\n[5] Agustinus Kristiadi.\n“Natural Gradient Descent”\nMar 2018.\n[6] Razvan Pascanu & Yoshua Bengio.\n“Revisiting Natural Gradient for Deep Networks.”\narXiv preprint arXiv:1301.3584 (2013).\n[7] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[8] Edoardo Conti, et al.\n“Improving exploration in evolution strategies for deep reinforcement learning via a population of novelty-seeking agents.”\nNIPS. 2018.\n[9] Aloïs Pourchot & Olivier Sigaud.\n“CEM-RL: Combining evolutionary and gradient-based methods for policy search.”\nICLR 2019.\n[10] Shauharda Khadka & Kagan Tumer.\n“Evolution-guided policy gradient in reinforcement learning.”\nNIPS 2018.\n[11] Max Jaderberg, et al.\n“Population based training of neural networks.”\narXiv preprint arXiv:1711.09846 (2017).\n[12] Adam Gaier & David Ha.\n“Weight Agnostic Neural Networks.”\narXiv preprint arXiv:1906.04358 (2019).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:55Z",
            "title": "Evolution Strategies | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/878201399682/code/body-000.txt",
                "chars": 225,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "retried_at": "2026-10-20T17:50:44Z"
              },
              {
                "status": "ok",
                "url": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "bytes": 88049,
                "reused": true,
                "local_path": "papers/repair/917cd856fd35314537c1.pdf"
              },
              {
                "status": "download_error",
                "url": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='control.ucsd.edu', port=80): Max retries exceeded with url: /mauricio/courses/mae280a/lecture11.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='co",
                "retried_at": "2026-10-20T22:24:26Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.00772",
                "bytes": 857878,
                "reused": true,
                "local_path": "papers/repair/71af15dab8222eb475d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.4487",
                "bytes": 1171979,
                "reused": true,
                "local_path": "papers/repair/37f18f0d7acadb4282f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3584v7",
                "bytes": 685629,
                "reused": true,
                "local_path": "papers/repair/bdf05dc4032d4acb3572.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.0221",
                "bytes": 331057,
                "reused": true,
                "local_path": "papers/repair/4e0bbca4680770f0c883.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.06560",
                "bytes": 4261567,
                "reused": true,
                "local_path": "papers/repair/129e1e6853a3d4d7a64a.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "bytes": 921414,
                "reused": true,
                "local_path": "papers/repair/c7818bfa100e7982cf3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.01222",
                "bytes": 2570801,
                "reused": true,
                "local_path": "papers/repair/17fc5b1b00f236706451.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.04358",
                "bytes": 2337427,
                "reused": true,
                "local_path": "papers/repair/8b93d140fe096a835c1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "bytes": 6284388,
                "reused": true,
                "local_path": "papers/repair/338cf06e2122caa8db06.pdf"
              },
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "bytes": 334309,
                "reused": true,
                "local_path": "papers/repair/4b425dc99075992bc98a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33765,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/878201399682/pages/source.html",
            "local_html": "attachments/878201399682/pages/article.html",
            "body_base_path": "attachments/878201399682/pages/",
            "body_markdown_path": "attachments/878201399682/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Simulated_annealing",
                "label": "Simulated Annealing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hill_climbing",
                "label": "Hill Climbing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method",
                "label": "Nelder-Mead method",
                "type": "a"
              },
              {
                "href": "https://www.khanacademy.org/science/biology/her/evolution-and-natural-selection/a/darwin-evolution-natural-selection",
                "label": "Darwin, evolution, & natural selection",
                "type": "a"
              },
              {
                "href": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "label": "format",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "This",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.00772",
                "label": "CMA-ES tutorial",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Conjugate_prior",
                "label": "conjugate",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.4487",
                "label": "Wierstra, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1301.3584v7",
                "label": "distribution",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/14/natural-gradient/",
                "label": "space",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/FisherInformationMatrix.html",
                "label": "Fisher Information Matrix",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/11/fisher-information/",
                "label": "it is",
                "type": "a"
              },
              {
                "href": "http://blog.shakirm.com/2015/11/machine-learning-trick-of-the-day-5-log-derivative-trick/",
                "label": "trick",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.0221",
                "label": "long ago",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "Evolved Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "vs exploitation",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/TBA",
                "label": "above",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.06560",
                "label": "Conti et al, 2018",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "label": "ERL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.01222",
                "label": "CEM-RL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "PBT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.04358",
                "label": "Gaier & Ha 2019",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "label": "Stanley & Miikkulainen 2002",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
          "status": "partial",
          "article_id": "6d3d9dca0d80",
          "local_path": "series-follow/1600/repair/bc5c14725294dbccfbb0.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
              "bytes": 117546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/834dca5b0e8f45a5caae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
              "bytes": 2066932,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/db79205a3fdc6b1972ac.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
              "bytes": 330686,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f4bbdd9860111196027c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
              "bytes": 77027,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7663a2768e6a5304e97d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
              "bytes": 92546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c0097767c26c92046b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
              "bytes": 710268,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/6a8653bd53396d46c1fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
              "bytes": 1618413,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/ec2093ad281b035abb92.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
              "bytes": 292184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5c3e06f69064d46da7a3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
              "bytes": 372187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f8d914d42f0dceb916fe.png"
            }
          ],
          "article": {
            "id": "6d3d9dca0d80",
            "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "bytes": 117546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-834dca5b0e8f45a5caae.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "bytes": 2066932,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-db79205a3fdc6b1972ac.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "bytes": 330686,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f4bbdd9860111196027c.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "bytes": 77027,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-7663a2768e6a5304e97d.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "bytes": 92546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-c0097767c26c92046b06.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "bytes": 710268,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-6a8653bd53396d46c1fa.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "bytes": 1618413,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-ec2093ad281b035abb92.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "bytes": 292184,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-5c3e06f69064d46da7a3.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "bytes": 372187,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f8d914d42f0dceb916fe.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "I’ve never worked in the field of computer vision and has no idea how the magic could work when an autonomous car is configured to tell apart a stop sign from a pedestrian in a red hat. To motivate myself to look into the maths behind object recognition and detection algorithms, I’m writing a few posts on this topic “Object Detection for Dummies”. This post, part 1, starts with super rudimentary concepts in image processing and a few methods for image segmentation. Nothing related to deep neural networks yet. Deep learning models for object detection and recognition will be discussed in\nPart 2\nand\nPart 3\n.\nDisclaimer: When I started, I was using “object recognition” and “object detection” interchangeably. I don’t think they are the same: the former is more about telling whether an object exists in an image while the latter needs to spot where the object is. However, they are highly related and many object recognition algorithms lay the foundation for detection.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nImage Gradient Vector\n#\nFirst of all, I would like to make sure we can distinguish the following terms. They are very similar, closely related, but not exactly the same.\nDerivative\nDirectional Derivative\nGradient\nValue type\nScalar\nScalar\nVector\nDefinition\nThe rate of change of a function $f(x,y,z,…)$ at a point $(x_0,y_0,z_0,…)$, which is the slope of the tangent line at the point.\nThe instantaneous rate of change of $f(x,y,z, …)$ in the direction of an unit vector $\\vec{u}$.\nIt points in the direction of the greatest rate of increase of the function, containing all the partial derivative information of a multivariable function.\nIn the image processing, we want to know the direction of colors changing from one extreme to the other (i.e. black to white on a grayscale image). Therefore, we want to measure “gradient” on pixels of colors. The gradient on an image is discrete because each pixel is independent and cannot be further split.\nThe\nimage gradient vector\nis defined as a metric for every individual pixel, containing the pixel color changes in both x-axis and y-axis. The definition is aligned with the gradient of a continuous multi-variable function, which is a vector of partial derivatives of all the variables. Suppose f(x, y) records the color of the pixel at location (x, y), the gradient vector of the pixel (x, y) is defined as follows:\n$$\n\\begin{align*}\n\\nabla f(x, y)\n= \\begin{bmatrix}\n  g_x \\\\\n  g_y\n\\end{bmatrix}\n= \\begin{bmatrix}\n  \\frac{\\partial f}{\\partial x} \\\\[6pt]\n  \\frac{\\partial f}{\\partial y}\n\\end{bmatrix}\n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n\\end{align*}\n$$\nThe $\\frac{\\partial f}{\\partial x}$ term is the partial derivative on the x-direction, which is computed as the color difference between the adjacent pixels on the left and right of the target, f(x+1, y) - f(x-1, y). Similarly, the $\\frac{\\partial f}{\\partial y}$ term is the partial derivative on the y-direction, measured as f(x, y+1) - f(x, y-1), the color difference between the adjacent pixels above and below the target.\nThere are two important attributes of an image gradient:\nMagnitude\nis the L2-norm of the vector, $g = \\sqrt{ g_x^2 + g_y^2 }$.\nDirection\nis the arctangent of the ratio between the partial derivatives on two directions, $\\theta = \\arctan{(g_y / g_x)}$.\nTo compute the gradient vector of a target pixel at location (x, y), we need to know the colors of its four neighbors (or eight surrounding pixels depending on the kernel).\nThe gradient vector of the example in is:\n$$\n\\begin{align*}\n\\nabla f \n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n= \\begin{bmatrix}\n  55-105\\\\\n  90-40\n\\end{bmatrix}\n= \\begin{bmatrix}\n  -50\\\\\n  50\n\\end{bmatrix}\n\\end{align*}\n$$\nThus,\nthe magnitude is $\\sqrt{50^2 + (-50)^2} = 70.7107$, and\nthe direction is $\\arctan{(-50/50)} = -45^{\\circ}$.\nRepeating the gradient computation process for every pixel iteratively is too slow. Instead, it can be well translated into applying a convolution operator on the entire image matrix, labeled as $\\mathbf{A}$ using one of the specially designed convolutional kernels.\nLet’s start with the x-direction of the example in Fig 1. using the kernel $[-1,0,1]$ sliding over the x-axis; $\\ast$ is the convolution operator:\n$$\n\\begin{align*}\n\\mathbf{G}_x &= \n[-1, 0, 1] \\ast [105, 255, 55] = -105 + 0 + 55 = -50\n\\end{align*}\n$$\nSimilarly, on the y-direction, we adopt the kernel $[+1, 0, -1]^\\top$:\n$$\n\\begin{align*}\n\\mathbf{G}_y &= \n[+1, 0, -1]^\\top \\ast\n\\begin{bmatrix}\n  90\\\\\n  255\\\\\n  40\n\\end{bmatrix} \n= 90 + 0 - 40 = 50\n\\end{align*}\n$$\nTry this in python:\nimport\nnumpy\nas\nnp\nimport\nscipy.signal\nas\nsig\ndata\n=\nnp\n.\narray([[\n0\n,\n105\n,\n0\n], [\n40\n,\n255\n,\n90\n], [\n0\n,\n55\n,\n0\n]])\nG_x\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n,\n0\n,\n1\n]]), mode\n=\n'valid'\n)\nG_y\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n], [\n0\n], [\n1\n]]), mode\n=\n'valid'\n)\nThese two functions return\narray([[0], [-50], [0]])\nand\narray([[0, 50, 0]])\nrespectively. (Note that in the numpy array representation, 40 is shown in front of 90, so -1 is listed before 1 in the kernel correspondingly.)\nCommon Image Processing Kernels\n#\nPrewitt operator\n: Rather than only relying on four directly adjacent neighbors, the Prewitt operator utilizes eight surrounding pixels for smoother results.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-1 & 0 & +1 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +1 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -1 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nSobel operator\n: To emphasize the impact of directly adjacent pixels more, they get assigned with higher weights.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-2 & 0 & +2 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +2 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -2 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nDifferent kernels are created for different goals, such as edge detection, blurring, sharpening and many more. Check\nthis wiki page\nfor more examples and references.\nExample: Manu in 2004\n#\nLet’s run a simple experiment on the photo of Manu Ginobili in 2004 [[Download Image]({{ ‘/assets/data/manu-2004.jpg’ | relative_url }}){:target=\"_blank\"}] when he still had a lot of hair. For simplicity, the photo is converted to grayscale first. For colored images, we just need to repeat the same process in each color channel respectively.\nManu Ginobili in 2004 with hair. (Image source:\nManu Ginobili's bald spot through the years\n)\nimport\nnumpy\nas\nnp\nimport\nscipy\nimport\nscipy.signal\nas\nsig\n# With mode=\"L\", we force the image to be parsed in the grayscale, so it is\n# actually unnecessary to convert the photo color beforehand.\nimg\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2004.jpg\"\n, mode\n=\n\"L\"\n)\n# Define the Sobel operator kernels.\nkernel_x\n=\nnp\n.\narray([[\n-\n1\n,\n0\n,\n1\n],[\n-\n2\n,\n0\n,\n2\n],[\n-\n1\n,\n0\n,\n1\n]])\nkernel_y\n=\nnp\n.\narray([[\n1\n,\n2\n,\n1\n], [\n0\n,\n0\n,\n0\n], [\n-\n1\n,\n-\n2\n,\n-\n1\n]])\nG_x\n=\nsig\n.\nconvolve2d(img, kernel_x, mode\n=\n'same'\n)\nG_y\n=\nsig\n.\nconvolve2d(img, kernel_y, mode\n=\n'same'\n)\n# Plot them!\nfig\n=\nplt\n.\nfigure()\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\n# Actually plt.imshow() can handle the value scale well even if I don't do\n# the transformation (G_x + 255) / 2.\nax1\n.\nimshow((G_x\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax1\n.\nset_xlabel(\n\"Gx\"\n)\nax2\n.\nimshow((G_y\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax2\n.\nset_xlabel(\n\"Gy\"\n)\nplt\n.\nshow()\nApply Sobel operator kernel on the example image.\nYou might notice that most area is in gray. Because the difference between two pixel is between -255 and 255 and we need to convert them back to [0, 255] for the display purpose.\nA simple linear transformation ($\\mathbf{G}$ + 255)/2 would interpret all the zeros (i.e., constant colored background shows no change in gradient) as 125 (shown as gray).\nHistogram of Oriented Gradients (HOG)\n#\nThe Histogram of Oriented Gradients (HOG) is an efficient way to extract features out of the pixel colors for building an object recognition classifier. With the knowledge of image gradient vectors, it is not hard to understand how HOG works. Let’s start!\nHow HOG works\n#\nPreprocess the image, including resizing and color normalization.\nCompute the gradient vector of every pixel, as well as its magnitude and direction.\nDivide the image into many 8x8 pixel cells. In each cell, the magnitude values of these 64 cells are binned and cumulatively added into 9 buckets of unsigned direction (no sign, so 0-180 degree rather than 0-360 degree; this is a practical choice based on empirical experiments).\nFor better robustness, if the direction of the gradient vector of a pixel lays between two buckets, its magnitude does not all go into the closer one but proportionally split between two. For example, if a pixel’s gradient vector has magnitude 8 and degree 15, it is between two buckets for degree 0 and 20 and we would assign 2 to bucket 0 and 6 to bucket 20.\nThis interesting configuration makes the histogram much more stable when small distortion is applied to the image.\nHow to split one gradient vector's magnitude if its degress is between two degree bins. (Image source: https://www.learnopencv.com/histogram-of-oriented-gradients/)\nThen we slide a 2x2 cells (thus 16x16 pixels) block across the image. In each block region, 4 histograms of 4 cells are concatenated into one-dimensional vector of 36 values and then normalized to have an unit weight.\nThe final HOG feature vector is the concatenation of all the block vectors. It can be fed into a classifier like SVM for learning object recognition tasks.\nExample: Manu in 2004\n#\nLet’s reuse the same example image in the previous section. Remember that we have computed $\\mathbf{G}_x$ and $\\mathbf{G}_y$ for the whole image.\nN_BUCKETS\n=\n9\nCELL_SIZE\n=\n8\n# Each cell is 8x8 pixels\nBLOCK_SIZE\n=\n2\n# Each block is 2x2 cells\ndef\nassign_bucket_vals\n(m, d, bucket_vals):\nleft_bin\n=\nint(d\n/\n20.\n)\n# Handle the case when the direction is between [160, 180)\nright_bin\n=\n(int(d\n/\n20.\n)\n+\n1\n)\n%\nN_BUCKETS\nassert\n0\n<=\nleft_bin\n<\nright_bin\n<\nN_BUCKETS\nleft_val\n=\nm\n*\n(right_bin\n*\n20\n-\nd)\n/\n20\nright_val\n=\nm\n*\n(d\n-\nleft_bin\n*\n20\n)\n/\n20\nbucket_vals[left_bin]\n+=\nleft_val\nbucket_vals[right_bin]\n+=\nright_val\ndef\nget_magnitude_hist_cell\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target cell.\ncell_x\n=\nG_x[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\ncell_y\n=\nG_y[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\nmagnitudes\n=\nnp\n.\nsqrt(cell_x\n*\ncell_x\n+\ncell_y\n*\ncell_y)\ndirections\n=\nnp\n.\nabs(np\n.\narctan(cell_y\n/\ncell_x)\n*\n180\n/\nnp\n.\npi)\nbuckets\n=\nnp\n.\nlinspace(\n0\n,\n180\n, N_BUCKETS\n+\n1\n)\nbucket_vals\n=\nnp\n.\nzeros(N_BUCKETS)\nmap(\nlambda\n(m, d): assign_bucket_vals(m, d, bucket_vals),\nzip(magnitudes\n.\nflatten(), directions\n.\nflatten())\n)\nreturn\nbucket_vals\ndef\nget_magnitude_hist_block\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target block.\nreturn\nreduce(\nlambda\narr1, arr2: np\n.\nconcatenate((arr1, arr2)),\n[get_magnitude_hist_cell(x, y)\nfor\nx, y\nin\nzip(\n[loc_x, loc_x\n+\nCELL_SIZE, loc_x, loc_x\n+\nCELL_SIZE],\n[loc_y, loc_y, loc_y\n+\nCELL_SIZE, loc_y\n+\nCELL_SIZE],\n)]\n)\nThe following code simply calls the functions to construct a histogram and plot it.\n# Random location [200, 200] as an example.\nloc_x\n=\nloc_y\n=\n200\nydata\n=\nget_magnitude_hist_block(loc_x, loc_y)\nydata\n=\nydata\n/\nnp\n.\nlinalg\n.\nnorm(ydata)\nxdata\n=\nrange(len(ydata))\nbucket_names\n=\nnp\n.\ntile(np\n.\narange(N_BUCKETS), BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(ydata)\n==\nN_BUCKETS\n*\n(BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(bucket_names)\n==\nlen(ydata)\nplt\n.\nfigure(figsize\n=\n(\n10\n,\n3\n))\nplt\n.\nbar(xdata, ydata, align\n=\n'center'\n, alpha\n=\n0.8\n, width\n=\n0.9\n)\nplt\n.\nxticks(xdata, bucket_names\n*\n20\n, rotation\n=\n90\n)\nplt\n.\nxlabel(\n'Direction buckets'\n)\nplt\n.\nylabel(\n'Magnitude'\n)\nplt\n.\ngrid(ls\n=\n'--'\n, color\n=\n'k'\n, alpha\n=\n0.1\n)\nplt\n.\ntitle(\n\"HOG of block at [\n%d\n,\n%d\n]\"\n%\n(loc_x, loc_y))\nplt\n.\ntight_layout()\nIn the code above, I use the block with top left corner located at [200, 200] as an example and here is the final normalized histogram of this block. You can play with the code to change the block location to be identified by a sliding window.\nDemonstration of a HOG histogram for one block.\nThe code is mostly for demonstrating the computation process. There are many off-the-shelf libraries with HOG algorithm implemented, such as\nOpenCV\n,\nSimpleCV\nand\nscikit-image\n.\nImage Segmentation (Felzenszwalb’s Algorithm)\n#\nWhen there exist multiple objects in one image (true for almost every real-world photos), we need to identify a region that potentially contains a target object so that the classification can be executed more efficiently.\nFelzenszwalb and Huttenlocher (\n2004\n) proposed an algorithm for segmenting an image into similar regions using a graph-based approach. It is also the initialization method for Selective Search (a popular region proposal algorithm) that we are gonna discuss later.\nSay, we use a undirected graph $G=(V, E)$ to represent an input image. One vertex $v_i \\in V$ represents one pixel. One edge $e = (v_i, v_j) \\in E$ connects two vertices $v_i$ and $v_j$. Its associated weight $w(v_i, v_j)$ measures the dissimilarity between $v_i$ and $v_j$. The dissimilarity can be quantified in dimensions like color, location, intensity, etc. The higher the weight, the less similar two pixels are. A segmentation solution $S$ is a partition of $V$ into multiple connected components, $\\{C\\}$. Intuitively similar pixels should belong to the same components while dissimilar ones are assigned to different components.\nGraph Construction\n#\nThere are two approaches to constructing a graph out of an image.\nGrid Graph\n: Each pixel is only connected with surrounding neighbours (8 other cells in total). The edge weight is the absolute difference between the intensity values of the pixels.\nNearest Neighbor Graph\n: Each pixel is a point in the feature space (x, y, r, g, b), in which (x, y) is the pixel location and (r, g, b) is the color values in RGB. The weight is the Euclidean distance between two pixels’ feature vectors.\nKey Concepts\n#\nBefore we lay down the criteria for a good graph partition (aka image segmentation), let us define a couple of key concepts:\nInternal difference\n: $Int(C) = \\max_{e\\in MST(C, E)} w(e)$, where $MST$ is the minimum spanning tree of the components. A component $C$ can still remain connected even when we have removed all the edges with weights < $Int(C)$.\nDifference between two components\n: $Dif(C_1, C_2) = \\min_{v_i \\in C_1, v_j \\in C_2, (v_i, v_j) \\in E} w(v_i, v_j)$. $Dif(C_1, C_2) = \\infty$ if there is no edge in-between.\nMinimum internal difference\n: $MInt(C_1, C_2) = min(Int(C_1) + \\tau(C_1), Int(C_2) + \\tau(C_2))$, where $\\tau(C) = k / \\vert C \\vert$ helps make sure we have a meaningful threshold for the difference between components. With a higher $k$, it is more likely to result in larger components.\nThe quality of a segmentation is assessed by a pairwise region comparison predicate defined for given two regions $C_1$ and $C_2$:\n$$\nD(C_1, C_2) = \n\\begin{cases}\n  \\text{True} & \\text{ if } Dif(C_1, C_2) > MInt(C_1, C_2) \\\\\n  \\text{False} & \\text{ otherwise}\n\\end{cases}\n$$\nOnly when the predicate holds True, we consider them as two independent components; otherwise the segmentation is too fine and they probably should be merged.\nHow Image Segmentation Works\n#\nThe algorithm follows a bottom-up procedure. Given $G=(V, E)$ and $|V|=n, |E|=m$:\nEdges are sorted by weight in ascending order, labeled as $e_1, e_2, \\dots, e_m$.\nInitially, each pixel stays in its own component, so we start with $n$ components.\nRepeat for $k=1, \\dots, m$:\nThe segmentation snapshot at the step $k$ is denoted as $S^k$.\nWe take  the k-th edge in the order, $e_k = (v_i, v_j)$.\nIf $v_i$ and $v_j$ belong to the same component, do nothing and thus $S^k = S^{k-1}$.\nIf $v_i$ and $v_j$ belong to two different components $C_i^{k-1}$ and $C_j^{k-1}$ as in the segmentation $S^{k-1}$, we want to merge them into one if $w(v_i, v_j) \\leq MInt(C_i^{k-1}, C_j^{k-1})$; otherwise do nothing.\nIf you are interested in the proof of the segmentation properties and why it always exists, please refer to the\npaper\n.\nAn indoor scene with segmentation detected by the grid graph construction in Felzenszwalb's graph-based segmentation algorithm (k=300).\nExample: Manu in 2013\n#\nThis time I would use the photo of old Manu Ginobili in 2013 [[Image]({{ ‘/assets/data/manu-2013.jpg’ | relative_url }})] as the example image when his bald spot has grown up strong. Still for simplicity, we use the picture in grayscale.\nManu Ginobili in 2013 with bald spot. (Image source:\nManu Ginobili's bald spot through the years\n)\nRather than coding from scratch, let us apply\nskimage.segmentation.felzenszwalb\nto the image.\nimport\nskimage.segmentation\nfrom\nmatplotlib\nimport\npyplot\nas\nplt\nimg2\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2013.jpg\"\n, mode\n=\n\"L\"\n)\nsegment_mask1\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n100\n)\nsegment_mask2\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n1000\n)\nfig\n=\nplt\n.\nfigure(figsize\n=\n(\n12\n,\n5\n))\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\nax1\n.\nimshow(segment_mask1); ax1\n.\nset_xlabel(\n\"k=100\"\n)\nax2\n.\nimshow(segment_mask2); ax2\n.\nset_xlabel(\n\"k=1000\"\n)\nfig\n.\nsuptitle(\n\"Felsenszwalb's efficient graph based image segmentation\"\n)\nplt\n.\ntight_layout()\nplt\n.\nshow()\nThe code ran two versions of Felzenszwalb’s algorithms as shown in The left k=100 generates a finer-grained segmentation with small regions where Manu’s bald spot is identified. The right one k=1000 outputs a coarser-grained segmentation where regions tend to be larger.\nFelsenszwalb's efficient graph-based image segmentation is applied on the photo of Manu in 2013.\nSelective Search\n#\nSelective search is a common algorithm to provide region proposals that potentially contain objects. It is built on top of the image segmentation output and use region-based characteristics (NOTE: not just attributes of a single pixel) to do a bottom-up hierarchical grouping.\nHow Selective Search Works\n#\nAt the initialization stage, apply Felzenszwalb and Huttenlocher’s graph-based image segmentation algorithm to create regions to start with.\nUse a greedy algorithm to iteratively group regions together:\nFirst the similarities between all neighbouring regions are calculated.\nThe two most similar regions are grouped together, and new similarities are calculated between the resulting region and its neighbours.\nThe process of grouping the most similar regions (Step 2) is repeated until the whole image becomes a single region.\nThe detailed algorithm of Selective Search.\nConfiguration Variations\n#\nGiven two regions $(r_i, r_j)$, selective search proposed four complementary similarity measures:\nColor\nsimilarity\nTexture\n: Use algorithm that works well for material recognition such as\nSIFT\n.\nSize\n: Small regions are encouraged to merge early.\nShape\n: Ideally one region can fill the gap of the other.\nBy (i) tuning the threshold $k$ in Felzenszwalb and Huttenlocher’s algorithm, (ii) changing the color space and (iii) picking different combinations of similarity metrics, we can produce a diverse set of Selective Search strategies. The version that produces the region proposals with best quality is configured with (i) a mixture of various initial segmentation proposals, (ii) a blend of multiple color spaces and (iii) a combination of all similarity measures. Unsurprisingly we need to balance between the quality (the model complexity) and the speed.\nCited as:\n@article{weng2017detection1,\n  title   = \"Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/\"\n}\nReferences\n#\n[1] Dalal, Navneet, and Bill Triggs.\n“Histograms of oriented gradients for human detection.”\nComputer Vision and Pattern Recognition (CVPR), 2005.\n[2] Pedro F. Felzenszwalb, and Daniel P. Huttenlocher.\n“Efficient graph-based image segmentation.”\nIntl. journal of computer vision 59.2 (2004): 167-181.\n[3]\nHistogram of Oriented Gradients by Satya Mallick\n[4]\nGradient Vectors by Chris McCormick\n[5]\nHOG Person Detector Tutorial by Chris McCormick",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:55Z",
            "title": "Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/6d3d9dca0d80/code/body-000.txt",
                "chars": 239,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-001.txt",
                "chars": 840,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-002.txt",
                "chars": 1510,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-003.txt",
                "chars": 655,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-004.txt",
                "chars": 547,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-005.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "download_error",
                "url": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='cvcl.mit.edu', port=80): Max retries exceeded with url: /SUNSeminar/Felzenszwalb_IJCV04.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='cvcl.mit.e",
                "retried_at": "2026-10-20T22:24:59Z"
              },
              {
                "status": "ok",
                "url": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "bytes": 490132,
                "reused": true,
                "local_path": "papers/repair/e62fbcd20fd040b4335d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "bytes": 577941,
                "reused": true,
                "local_path": "papers/repair/93aa482d821738ade913.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:56:53Z"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20363,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/6d3d9dca0d80/pages/source.html",
            "local_html": "attachments/6d3d9dca0d80/pages/article.html",
            "body_base_path": "attachments/6d3d9dca0d80/pages/",
            "body_markdown_path": "attachments/6d3d9dca0d80/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_gradient",
                "label": "image gradient vector",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Prewitt_operator",
                "label": "Prewitt operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Sobel_operator",
                "label": "Sobel operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "this wiki page",
                "type": "a"
              },
              {
                "href": "http://ftw.usatoday.com/2013/05/manu-ginobilis-bald-spot-through-the-years",
                "label": "Manu Ginobili's bald spot through the years",
                "type": "a"
              },
              {
                "href": "https://github.com/opencv/opencv",
                "label": "OpenCV",
                "type": "a"
              },
              {
                "href": "http://simplecv.org/",
                "label": "SimpleCV",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/",
                "label": "scikit-image",
                "type": "a"
              },
              {
                "href": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "label": "2004",
                "type": "a"
              },
              {
                "href": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/docs/dev/api/skimage.segmentation.html",
                "label": "skimage.segmentation.felzenszwalb",
                "type": "a"
              },
              {
                "href": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "label": "SIFT",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "label": "“Histograms of oriented gradients for human detection.”",
                "type": "a"
              },
              {
                "href": "https://www.learnopencv.com/histogram-of-oriented-gradients/",
                "label": "Histogram of Oriented Gradients by Satya Mallick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/07/gradient-vectors/",
                "label": "Gradient Vectors by Chris McCormick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/09/hog-person-detector-tutorial/",
                "label": "HOG Person Detector Tutorial by Chris McCormick",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
          "status": "partial",
          "article_id": "b9468080b799",
          "local_path": "series-follow/1600/repair/93da665e04c347feb576.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
              "bytes": 788352,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/4bea384db100fbf3fa0e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
              "bytes": 109138,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/227c6111eda2f97ab1f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
              "bytes": 3136069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b0d9d2dda61d5528b14d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
              "bytes": 437592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/e837b0cac457a4dfa174.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
              "bytes": 269669,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/283d484fb68c4e61aa0b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
              "bytes": 27821,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c7816ecf6f5265465238.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
              "bytes": 432129,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9794f4d3172e6d7ec6e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
              "bytes": 855836,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/ad16881681864ec9a905.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
              "bytes": 1600504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/db8216b190ed77df91ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
              "bytes": 98699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/de07b29467385da73bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
              "bytes": 1000184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/781e719388c2d1788151.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Object Detection for Dummies Part 3: R-CNN Family",
            "keywords": "目标检测,R-CNN,Faster R-CNN",
            "domain": "图像处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "publish_date": "2017-12",
            "corpus_stage": "预训练/SFT",
            "notes": "目标检测R-CNN家族综述",
            "id": "b9468080b799",
            "collected_at": "2026-10-02T14:13:33",
            "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
            "body_markdown": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n[Updated on 2018-12-27: Add\nbbox regression\nand\ntricks\nsections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in\nPart 1\n. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in\nPart 2\n. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nHere is a list of papers covered in this post ;)\nModel\nGoal\nResources\nR-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFast R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFaster R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nMask R-CNN\nImage segmentation\n[\npaper\n][\ncode\n]\nR-CNN\n#\nR-CNN (\nGirshick et al., 2014\n) is short for “Region-based Convolutional Neural Networks”. The main idea is composed of two steps. First, using\nselective search\n, it identifies a manageable number of bounding-box object region candidates (“region of interest” or “RoI”). And then it extracts CNN features from each region independently for classification.\nThe architecture of R-CNN. (Image source:\nGirshick et al., 2014\n)\nModel Workflow\n#\nHow R-CNN works can be summarized as follows:\nPre-train\na CNN network on image classification tasks; for example, VGG or ResNet trained on\nImageNet\ndataset. The classification task involves N classes.\nNOTE: You can find a pre-trained\nAlexNet\nin Caffe Model\nZoo\n. I don’t think you can\nfind it\nin Tensorflow, but Tensorflow-slim model\nlibrary\nprovides pre-trained ResNet, VGG, and others.\nPropose category-independent regions of interest by selective search (~2k candidates per image). Those regions may contain target objects and they are of different sizes.\nRegion candidates are\nwarped\nto have a fixed size as required by CNN.\nContinue fine-tuning the CNN on warped proposal regions for K + 1 classes; The additional one class refers to the background (no object of interest). In the fine-tuning stage, we should use a much smaller learning rate and the mini-batch oversamples the positive cases because most proposed regions are just background.\nGiven every image region, one forward propagation through the CNN generates a feature vector. This feature vector is then consumed by a\nbinary SVM\ntrained for\neach class\nindependently.\nThe positive samples are proposed regions with IoU (intersection over union) overlap threshold >= 0.3, and negative samples are irrelevant others.\nTo reduce the localization errors, a regression model is trained to correct the predicted detection window on bounding box correction offset using CNN features.\nBounding Box Regression\n#\nGiven a predicted bounding box coordinate $\\mathbf{p} = (p_x, p_y, p_w, p_h)$ (center coordinate, width, height) and its corresponding ground truth box coordinates $\\mathbf{g} = (g_x, g_y, g_w, g_h)$ , the regressor is configured to learn scale-invariant transformation between two centers and log-scale transformation between widths and heights. All the transformation functions take $\\mathbf{p}$ as input.\n$$\n\\begin{aligned}\n\\hat{g}_x &= p_w d_x(\\mathbf{p}) + p_x \\\\\n\\hat{g}_y &= p_h d_y(\\mathbf{p}) + p_y \\\\\n\\hat{g}_w &= p_w \\exp({d_w(\\mathbf{p})}) \\\\\n\\hat{g}_h &= p_h \\exp({d_h(\\mathbf{p})})\n\\end{aligned}\n$$\nIllustration of transformation between predicted and ground truth bounding boxes.\nAn obvious benefit of applying such transformation is that all the bounding box correction functions, $d_i(\\mathbf{p})$ where $i \\in \\{ x, y, w, h \\}$, can take any value between [-∞, +∞]. The targets for them to learn are:\n$$\n\\begin{aligned}\nt_x &= (g_x - p_x) / p_w \\\\\nt_y &= (g_y - p_y) / p_h \\\\\nt_w &= \\log(g_w/p_w) \\\\\nt_h &= \\log(g_h/p_h)\n\\end{aligned}\n$$\nA standard regression model can solve the problem by minimizing the SSE loss with regularization:\n$$\n\\mathcal{L}_\\text{reg} = \\sum_{i \\in \\{x, y, w, h\\}} (t_i - d_i(\\mathbf{p}))^2 + \\lambda \\|\\mathbf{w}\\|^2\n$$\nThe regularization term is critical here and RCNN paper picked the best λ by cross validation. It is also noteworthy that not all the predicted bounding boxes have corresponding ground truth boxes. For example, if there is no overlap, it does not make sense to run bbox regression. Here, only a predicted box with a nearby ground truth box with at least 0.6 IoU is kept for training the bbox regression model.\nCommon Tricks\n#\nSeveral tricks are commonly used in RCNN and other detection models.\nNon-Maximum Suppression\nLikely the model is able to find multiple bounding boxes for the same object. Non-max suppression helps avoid repeated detection of the same instance. After we get a set of matched bounding boxes for the same object category:\nSort all the bounding boxes by confidence score.\nDiscard boxes with low confidence scores.\nWhile\nthere is any remaining bounding box, repeat the following:\nGreedily select the one with the highest score.\nSkip the remaining boxes with high IoU (i.e. > 0.5) with previously selected one.\nMultiple bounding boxes detect the car in the image. After non-maximum suppression, only the best remains and the rest are ignored as they have large overlaps with the selected one. (Image source:\nDPM paper\n)\nHard Negative Mining\nWe consider bounding boxes without objects as negative examples. Not all the negative examples are equally hard to be identified. For example, if it holds pure empty background, it is likely an “\neasy negative\n”; but if the box contains weird noisy texture or partial object, it could be hard to be recognized and these are “\nhard negative\n”.\nThe hard negative examples are easily misclassified. We can explicitly find those false positive samples during the training loops and include them in the training data so as to improve the classifier.\nSpeed Bottleneck\n#\nLooking through the R-CNN learning steps, you could easily find out that training an R-CNN model is expensive and slow, as the following steps involve a lot of work:\nRunning selective search to propose 2000 region candidates for every image;\nGenerating the CNN feature vector for every image region (N images * 2000).\nThe whole process involves three models separately without much shared computation: the convolutional neural network for image classification and feature extraction; the top SVM classifier for identifying target objects; and the regression model for tightening region bounding boxes.\nFast R-CNN\n#\nTo make R-CNN faster, Girshick (\n2015\n) improved the training procedure by unifying three independent models into one jointly trained framework and increasing shared computation results, named\nFast R-CNN\n. Instead of extracting CNN feature vectors independently for each region proposal, this model aggregates them into one CNN forward pass over the entire image and the region proposals share this feature matrix. Then the same feature matrix is branched out to be used for learning the object classifier and the bounding-box regressor. In conclusion, computation sharing speeds up R-CNN.\nThe architecture of Fast R-CNN. (Image source:\nGirshick, 2015\n)\nRoI Pooling\n#\nIt is a type of max pooling to convert features in the projected region of the image of any size, h x w, into a small fixed window, H x W. The input region is divided into H x W grids, approximately every subwindow of size h/H x w/W. Then apply max-pooling in each grid.\nRoI pooling (Image source:\nStanford CS231n slides\n.)\nModel Workflow\n#\nHow Fast R-CNN works is summarized as follows; many steps are same as in R-CNN:\nFirst, pre-train a convolutional neural network on image classification tasks.\nPropose regions by selective search (~2k candidates per image).\nAlter the pre-trained CNN:\nReplace the last max pooling layer of the pre-trained CNN with a\nRoI pooling\nlayer. The RoI pooling layer outputs fixed-length feature vectors of region proposals. Sharing the CNN computation makes a lot of sense, as many region proposals of the same images are highly overlapped.\nReplace the last fully connected layer and the last softmax layer (K classes) with a fully connected layer and softmax over K + 1 classes.\nFinally the model branches into two output layers:\nA softmax estimator of K + 1 classes (same as in R-CNN, +1 is the “background” class), outputting a discrete probability distribution per RoI.\nA bounding-box regression model which predicts offsets relative to the original RoI for each of K classes.\nLoss Function\n#\nThe model is optimized for a loss combining two tasks (classification + localization):\n|\nSymbol\n|\nExplanation\n|\n| $u$ | True class label, $ u \\in 0, 1, \\dots, K$; by convention, the catch-all background class has $u = 0$. |\n| $p$ | Discrete probability distribution (per RoI) over K + 1 classes: $p = (p_0, \\dots, p_K)$, computed by a softmax over the K + 1 outputs of a fully connected layer. |\n| $v$ | True bounding box $ v = (v_x, v_y, v_w, v_h) $. |\n| $t^u$ | Predicted bounding box correction, $t^u = (t^u_x, t^u_y, t^u_w, t^u_h)$. See\nabove\n. |\n{:.info}\nThe loss function sums up the cost of classification and bounding box prediction: $\\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box}$. For “background” RoI, $\\mathcal{L}_\\text{box}$ is ignored by the indicator function $\\mathbb{1} [u \\geq 1]$, defined as:\n$$\n\\mathbb{1} [u >= 1] = \\begin{cases}\n    1  & \\text{if } u \\geq 1\\\\\n    0  & \\text{otherwise}\n\\end{cases}\n$$\nThe overall loss function is:\n$$\n\\begin{align*}\n\\mathcal{L}(p, u, t^u, v) &= \\mathcal{L}_\\text{cls} (p, u) + \\mathbb{1} [u \\geq 1] \\mathcal{L}_\\text{box}(t^u, v) \\\\\n\\mathcal{L}_\\text{cls}(p, u) &= -\\log p_u \\\\\n\\mathcal{L}_\\text{box}(t^u, v) &= \\sum_{i \\in \\{x, y, w, h\\}} L_1^\\text{smooth} (t^u_i - v_i)\n\\end{align*}\n$$\nThe bounding box loss $\\mathcal{L}_{box}$ should measure the difference between $t^u_i$ and $v_i$ using a\nrobust\nloss function. The\nsmooth L1 loss\nis adopted here and it is claimed to be less sensitive to outliers.\n$$\nL_1^\\text{smooth}(x) = \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases}\n$$\nThe plot of smooth L1 loss, $y = L\\_1^\\text{smooth}(x)$. (Image source:\nlink\n)\nSpeed Bottleneck\n#\nFast R-CNN is much faster in both training and testing time. However, the improvement is not dramatic because the region proposals are generated separately by another model and that is very expensive.\nFaster R-CNN\n#\nAn intuitive speedup solution is to integrate the region proposal algorithm into the CNN model.\nFaster R-CNN\n(\nRen et al., 2016\n) is doing exactly this: construct a single, unified model composed of RPN (region proposal network) and fast R-CNN with shared convolutional feature layers.\nAn illustration of Faster R-CNN model. (Image source:\nRen et al., 2016\n)\nModel Workflow\n#\nPre-train a CNN network on image classification tasks.\nFine-tune the RPN (region proposal network) end-to-end for the region proposal task, which is initialized by the pre-train image classifier. Positive samples have IoU (intersection-over-union) > 0.7, while negative samples have IoU < 0.3.\nSlide a small n x n spatial window over the conv feature map of the entire image.\nAt the center of each sliding window, we predict multiple regions of various scales and ratios simultaneously. An anchor is a combination of (sliding window center, scale, ratio). For example, 3 scales + 3 ratios => k=9 anchors at each sliding position.\nTrain a Fast R-CNN object detection model using the proposals generated by the current RPN\nThen use the Fast R-CNN network to initialize RPN training. While keeping the shared convolutional layers, only fine-tune the RPN-specific layers. At this stage, RPN and the detection network have shared convolutional layers!\nFinally fine-tune the unique layers of Fast R-CNN\nStep 4-5 can be repeated to train RPN and Fast R-CNN alternatively if needed.\nLoss Function\n#\nFaster R-CNN is optimized for a multi-task loss function, similar to fast R-CNN.\n|\nSymbol\n|\nExplanation\n|\n| $p_i$     | Predicted probability of anchor i being an object. |\n| $p^*_i$   | Ground truth label (binary) of whether anchor i is an object. |\n| $t_i$     | Predicted four parameterized coordinates. |\n| $t^*_i$   | Ground truth coordinates. |\n| $N_\\text{cls}$ | Normalization term, set to be mini-batch size (~256) in the paper. |\n| $N_\\text{box}$ | Normalization term, set to the number of anchor locations (~2400) in the paper. |\n| $\\lambda$ | A balancing parameter, set to be ~10 in the paper (so that both $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ terms are roughly equally weighted). |\n{:.info}\nThe multi-task loss function combines the losses of classification and bounding box regression:\n$$\n\\begin{align*}\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} \\\\\n\\mathcal{L}(\\{p_i\\}, \\{t_i\\}) &= \\frac{1}{N_\\text{cls}} \\sum_i \\mathcal{L}_\\text{cls} (p_i, p^*_i) + \\frac{\\lambda}{N_\\text{box}} \\sum_i p^*_i \\cdot L_1^\\text{smooth}(t_i - t^*_i) \\\\\n\\end{align*}\n$$\nwhere $\\mathcal{L}_\\text{cls}$ is the log loss function over two classes, as we can easily translate a multi-class classification into a binary classification by predicting a sample being a target object versus not. $L_1^\\text{smooth}$ is the smooth L1 loss.\n$$\n\\mathcal{L}_\\text{cls} (p_i, p^*_i) = - p^*_i \\log p_i - (1 - p^*_i) \\log (1 - p_i)\n$$\nMask R-CNN\n#\nMask R-CNN (\nHe et al., 2017\n) extends Faster R-CNN to pixel-level\nimage segmentation\n. The key point is to decouple the classification and the pixel-level mask prediction tasks. Based on the framework of\nFaster R-CNN\n, it added a third branch for predicting an object mask in parallel with the existing branches for classification and localization. The mask branch is a small fully-connected network applied to each RoI, predicting a segmentation mask in a pixel-to-pixel manner.\nMask R-CNN is Faster R-CNN model with image segmentation. (Image source:\nHe et al., 2017\n)\nBecause pixel-level segmentation requires much more fine-grained alignment than bounding boxes, mask R-CNN improves the RoI pooling layer (named “RoIAlign layer”) so that RoI can be better and more precisely mapped to the regions of the original image.\nPredictions by Mask R-CNN on COCO test set. (Image source:\nHe et al., 2017\n)\nRoIAlign\n#\nThe RoIAlign layer is designed to fix the location misalignment caused by quantization in the RoI pooling. RoIAlign removes the hash quantization, for example, by using x/16 instead of [x/16], so that the extracted features can be properly aligned with the input pixels.\nBilinear interpolation\nis used for computing the floating-point location values in the input.\nA region of interest is mapped **accurately** from the original image onto the feature map without rounding up to integers. (Image source:\nlink\n)\nLoss Function\n#\nThe multi-task loss function of Mask R-CNN combines the loss of classification, localization and segmentation mask: $ \\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} + \\mathcal{L}_\\text{mask}$, where $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ are same as in Faster R-CNN.\nThe mask branch generates a mask of dimension m x m for each RoI and each class; K classes in total. Thus, the total output is of size $K \\cdot m^2$. Because the model is trying to learn a mask for each class, there is no competition among classes for generating masks.\n$\\mathcal{L}_\\text{mask}$ is defined as the average binary cross-entropy loss, only including k-th mask if the region is associated with the ground truth class k.\n$$\n\\mathcal{L}_\\text{mask} = - \\frac{1}{m^2} \\sum_{1 \\leq i, j \\leq m} \\big[ y_{ij} \\log \\hat{y}^k_{ij} + (1-y_{ij}) \\log (1- \\hat{y}^k_{ij}) \\big]\n$$\nwhere $y_{ij}$ is the label of a cell (i, j) in the true mask for the region of size m x m; $\\hat{y}_{ij}^k$ is the predicted value of the same cell in the mask learned for the ground-truth class k.\nSummary of Models in the R-CNN family\n#\nHere I illustrate model designs of R-CNN, Fast R-CNN, Faster R-CNN and Mask R-CNN. You can track how one model evolves to the next version by comparing the small differences.\nCited as:\n@article{weng2017detection3,\n  title   = \"Object Detection for Dummies Part 3: R-CNN Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/\"\n}\nReference\n#\n[1] Ross Girshick, Jeff Donahue, Trevor Darrell, and Jitendra Malik.\n“Rich feature hierarchies for accurate object detection and semantic segmentation.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 580-587. 2014.\n[2] Ross Girshick.\n“Fast R-CNN.”\nIn Proc. IEEE Intl. Conf. on computer vision, pp. 1440-1448. 2015.\n[3] Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun.\n“Faster R-CNN: Towards real-time object detection with region proposal networks.”\nIn Advances in neural information processing systems (NIPS), pp. 91-99. 2015.\n[4] Kaiming He, Georgia Gkioxari, Piotr Dollár, and Ross Girshick.\n“Mask R-CNN.”\narXiv preprint arXiv:1703.06870, 2017.\n[5] Joseph Redmon, Santosh Divvala, Ross Girshick, and Ali Farhadi.\n“You only look once: Unified, real-time object detection.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 779-788. 2016.\n[6]\n“A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN”\nby Athelas.\n[7] Smooth L1 Loss:\nhttps://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
            "metadata": {
              "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
              "description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "keywords": "object-detection, object-recognition, vision-model",
              "author": "Lilian Weng",
              "og:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "og:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
              "twitter:card": "summary",
              "twitter:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "twitter:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "article:section": "posts",
              "article:published_time": "2017-12-31T00:00:00+00:00",
              "article:modified_time": "2017-12-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/b9468080b799/code/body-000.txt",
                "chars": 267,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "bytes": 788352,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-4bea384db100fbf3fa0e.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "bytes": 109138,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-227c6111eda2f97ab1f2.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "bytes": 3136069,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-b0d9d2dda61d5528b14d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "bytes": 437592,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-e837b0cac457a4dfa174.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "bytes": 269669,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-283d484fb68c4e61aa0b.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "bytes": 27821,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-c7816ecf6f5265465238.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "bytes": 432129,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-9794f4d3172e6d7ec6e1.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "bytes": 855836,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-ad16881681864ec9a905.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "bytes": 1600504,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-db8216b190ed77df91ef.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "bytes": 98699,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-de07b29467385da73bbf.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "bytes": 1000184,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-781e719388c2d1788151.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1311.2524",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1504.08083",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/fast-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.01497",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06870",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/CharlesShang/FastMaskRCNN",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://image-net.org/index",
                "label": "ImageNet",
                "type": "a"
              },
              {
                "href": "https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet",
                "label": "AlexNet",
                "type": "a"
              },
              {
                "href": "https://github.com/caffe2/caffe2/wiki/Model-Zoo",
                "label": "Zoo",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/issues/1394",
                "label": "find it",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/tree/master/research/slim",
                "label": "library",
                "type": "a"
              },
              {
                "href": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "label": "DPM paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1504.08083.pdf",
                "label": "2015",
                "type": "a"
              },
              {
                "href": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "label": "Stanford CS231n slides",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.01497.pdf",
                "label": "Ren et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06870.pdf",
                "label": "He et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bilinear_interpolation",
                "label": "Bilinear interpolation",
                "type": "a"
              },
              {
                "href": "https://blog.athelas.com/a-brief-history-of-cnns-in-image-segmentation-from-r-cnn-to-mask-r-cnn-34ea83205de4",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "label": "“Rich feature hierarchies for accurate object detection and semantic segmentation.”",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "label": "“Faster R-CNN: Towards real-time object detection with region proposal networks.”",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "“You only look once: Unified, real-time object detection.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:37Z",
            "source_url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1311.2524",
                "bytes": 6537772,
                "reused": false,
                "local_path": "papers/repair/5a971c9318fd8ef99b6d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/6389d2bce9bb81657bc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/713fc776568d336b3d68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/664bbc784da30edacdb6.pdf"
              },
              {
                "status": "http_404",
                "url": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "retried_at": "2026-10-20T18:02:44Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083.pdf",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/95f875d1b93587451953.pdf"
              },
              {
                "status": "ok",
                "url": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "bytes": 5264822,
                "reused": false,
                "local_path": "papers/repair/6704307d3926afe480a0.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": false,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497.pdf",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/9037a5243698d57ca173.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870.pdf",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/2f0eeff44085ec6f68ba.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "bytes": 1847626,
                "reused": false,
                "local_path": "papers/repair/99bf7bde4d6390550327.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "bytes": 761683,
                "reused": false,
                "local_path": "papers/repair/b13d014f28dadd2b7070.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": false,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 17566,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b9468080b799/pages/source.html",
            "local_html": "attachments/b9468080b799/pages/article.html",
            "body_base_path": "attachments/b9468080b799/pages/",
            "body_markdown_path": "attachments/b9468080b799/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
          "status": "partial",
          "article_id": "466144a71db1",
          "local_path": "series-follow/1600/repair/42584a00573758a53824.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
              "bytes": 947849,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7b981ee4ba3f0de9c69e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
              "bytes": 193831,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/d2d51b39b0c71b0793d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
              "bytes": 141158,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f004873880c2663f6f27.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
              "bytes": 285879,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b686cd210511644b9482.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
              "bytes": 862890,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/37c5aefd5995be6d0a22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
              "bytes": 155905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/4e81399abad9997ff29c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
              "bytes": 120909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/ac3a14a3f394f51725f0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
              "bytes": 1623681,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/bf58d167b991ee5982f3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
              "bytes": 328470,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7b68e660a804f6fdedfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
              "bytes": 77640,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/2a4ecbef4a9439ed154d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
              "bytes": 310680,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/955d0dc9f36806474855.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
              "bytes": 905917,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/2098115c6b769573d03c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
              "bytes": 332323,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/90988a475dbc99affc49.png"
            }
          ],
          "article": {
            "id": "466144a71db1",
            "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "bytes": 947849,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b981ee4ba3f0de9c69e.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "bytes": 193831,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-d2d51b39b0c71b0793d1.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "bytes": 141158,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-f004873880c2663f6f27.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "bytes": 285879,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-b686cd210511644b9482.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "bytes": 862890,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-37c5aefd5995be6d0a22.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "bytes": 155905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-4e81399abad9997ff29c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "bytes": 120909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-ac3a14a3f394f51725f0.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "bytes": 1623681,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-bf58d167b991ee5982f3.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "bytes": 328470,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b68e660a804f6fdedfc.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "bytes": 77640,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2a4ecbef4a9439ed154d.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "bytes": 310680,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-955d0dc9f36806474855.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "bytes": 905917,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2098115c6b769573d03c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "bytes": 332323,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-90988a475dbc99affc49.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In\nPart 3\n, we have reviewed models in the R-CNN family. All of them are region-based object detection algorithms. They can achieve high accuracy but could be too slow for certain applications such as autonomous driving. In Part 4, we only focus on fast object detection models, including SSD, RetinaNet, and models in the YOLO family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nTwo-stage vs One-stage Detectors\n#\nModels in the R-CNN family are all region-based. The detection happens in two stages: (1) First, the model proposes a set of regions of interests by select search or regional proposal network. The proposed regions are sparse as the potential bounding box candidates can be infinite. (2) Then a classifier only processes the region candidates.\nThe other different approach skips the region proposal stage and runs detection directly over a dense sampling of possible locations. This is how a one-stage object detection algorithm works. This is faster and simpler, but might potentially drag down the performance a bit.\nAll the models introduced in this post are one-stage detectors.\nYOLO: You Only Look Once\n#\nThe\nYOLO\nmodel (\n“You Only Look Once”\n;\nRedmon et al., 2016\n) is the very first attempt at building a fast real-time object detector. Because YOLO does not undergo the region proposal step and only predicts over a limited number of bounding boxes, it is able to do inference super fast.\nWorkflow\n#\nPre-train\na CNN network on image classification task.\nSplit an image into $S \\times S$ cells. If an object’s center falls into a cell, that cell is “responsible” for detecting the existence of that object. Each cell predicts (a) the location of $B$ bounding boxes, (b) a confidence score, and (c) a probability of object class conditioned on the existence of an object in the bounding box.\nThe\ncoordinates\nof bounding box are defined by a tuple of 4 values, (center x-coord, center y-coord, width, height) — $(x, y, w, h)$, where $x$ and $y$ are set to be offset of a cell location. Moreover, $x$, $y$, $w$ and $h$ are normalized by the image width and height, and thus all between (0, 1].\nA\nconfidence score\nindicates the likelihood that the cell contains an object:\nPr(containing an object) x IoU(pred, truth)\n; where\nPr\n= probability and\nIoU\n= interaction under union.\nIf the cell contains an object, it predicts a\nprobability\nof this object belonging to every class $C_i, i=1, \\dots, K$:\nPr(the object belongs to the class C_i | containing an object)\n. At this stage, the model only predicts one set of class probabilities per cell, regardless of the number of bounding boxes, $B$.\nIn total, one image contains $S \\times S \\times B$ bounding boxes, each box corresponding to 4 location predictions, 1 confidence score, and K conditional probabilities for object classification. The total prediction values for one image is $S \\times S \\times (5B + K)$, which is the tensor shape of the final conv layer of the model.\nThe final layer of the pre-trained CNN is modified to output a prediction tensor of size $S \\times S \\times (5B + K)$.\nThe workflow of YOLO model. (Image source:\noriginal paper\n)\nNetwork Architecture\n#\nThe base model is similar to\nGoogLeNet\nwith inception module replaced by 1x1 and 3x3 conv layers. The final prediction of shape $S \\times S \\times (5B + K)$ is produced by two fully connected layers over the whole conv feature map.\nThe network architecture of YOLO.\nLoss Function\n#\nThe loss consists of two parts, the\nlocalization loss\nfor bounding box offset prediction and the\nclassification loss\nfor conditional class probabilities. Both parts are computed as the sum of squared errors. Two scale parameters are used to control how much we want to increase the loss from bounding box coordinate predictions ($\\lambda_\\text{coord}$) and how much we want to decrease the loss of confidence score predictions for boxes without objects ($\\lambda_\\text{noobj}$). Down-weighting the loss contributed by background boxes is important as most of the bounding boxes involve no instance. In the paper, the model sets $\\lambda_\\text{coord} = 5$ and $\\lambda_\\text{noobj} = 0.5$.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\lambda_\\text{coord} \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\mathbb{1}_{ij}^\\text{obj} [(x_i - \\hat{x}_i)^2 + (y_i - \\hat{y}_i)^2 + (\\sqrt{w_i} - \\sqrt{\\hat{w}_i})^2 + (\\sqrt{h_i} - \\sqrt{\\hat{h}_i})^2 ] \\\\\n\\mathcal{L}_\\text{cls}  &= \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\big( \\mathbb{1}_{ij}^\\text{obj} + \\lambda_\\text{noobj} (1 - \\mathbb{1}_{ij}^\\text{obj})\\big) (C_{ij} - \\hat{C}_{ij})^2 + \\sum_{i=0}^{S^2} \\sum_{c \\in \\mathcal{C}} \\mathbb{1}_i^\\text{obj} (p_i(c) - \\hat{p}_i(c))^2\\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{loc} + \\mathcal{L}_\\text{cls}\n\\end{aligned}\n$$\nNOTE: In the original YOLO paper, the loss function uses $C_i$ instead of $C_{ij}$ as confidence score. I made the correction based on my own understanding, since every bounding box should have its own confidence score. Please kindly let me if you do not agree. Many thanks.\nwhere,\n$\\mathbb{1}_i^\\text{obj}$: An indicator function of whether the cell i contains an object.\n$\\mathbb{1}_{ij}^\\text{obj}$: It indicates whether the j-th bounding box of the cell i is “responsible” for the object prediction (see Fig. 3).\n$C_{ij}$: The confidence score of cell i,\nPr(containing an object) * IoU(pred, truth)\n.\n$\\hat{C}_{ij}$: The predicted confidence score.\n$\\mathcal{C}$: The set of all classes.\n$p_i(c)$: The conditional probability of whether cell i contains an object of class $c \\in \\mathcal{C}$.\n$\\hat{p}_i(c)$: The predicted conditional class probability.\nAt one location, in cell i, the model proposes B bounding box candidates and the one that has highest overlap with the ground truth is the \"responsible\" predictor.\nThe loss function only penalizes classification error if an object is present in that grid cell, $\\mathbb{1}_i^\\text{obj} = 1$. It also only penalizes bounding box coordinate error if that predictor is “responsible” for the ground truth box, $\\mathbb{1}_{ij}^\\text{obj} = 1$.\nAs a one-stage object detector, YOLO is super fast, but it is not good at recognizing irregularly shaped objects or a group of small objects due to a limited number of bounding box candidates.\nSSD: Single Shot MultiBox Detector\n#\nThe\nSingle Shot Detector\n(\nSSD\n;\nLiu et al, 2016\n) is one of the first attempts at using convolutional neural network’s pyramidal feature hierarchy for efficient detection of objects of various sizes.\nImage Pyramid\n#\nSSD uses the\nVGG-16\nmodel pre-trained on ImageNet as its base model for extracting useful image features.\nOn top of VGG16, SSD adds several conv feature layers of decreasing sizes. They can be seen as a\npyramid representation\nof images at different scales. Intuitively large fine-grained feature maps at earlier levels are good at capturing small objects and small coarse-grained feature maps can detect large objects well. In SSD, the detection happens in every pyramidal layer, targeting at objects of various sizes.\nThe model architecture of SSD.\nWorkflow\n#\nUnlike YOLO, SSD does not split the image into grids of arbitrary size but predicts offset of predefined\nanchor boxes\n(this is called “default boxes” in the paper) for every location of the feature map. Each box has a fixed size and position relative to its corresponding cell. All the anchor boxes tile the whole feature map in a convolutional manner.\nFeature maps at different levels have different receptive field sizes. The anchor boxes on different levels are rescaled so that one feature map is only responsible for objects at one particular scale. For example, in Fig. 5 the dog can only be detected in the 4x4 feature map (higher level) while the cat is just captured by the 8x8 feature map (lower level).\nThe SSD framework. (a) The training data contains images and ground truth boxes for every object. (b) In a fine-grained feature maps (8 x 8), the anchor boxes of different aspect ratios correspond to smaller area of the raw input. (c) In a coarse-grained feature map (4 x 4), the anchor boxes cover larger area of the raw input. (Image source:\noriginal paper\n)\nThe width, height and the center location of an anchor box are all normalized to be (0, 1). At a location $(i, j)$ of the $\\ell$-th feature layer of size $m \\times n$, $i=1,\\dots,n, j=1,\\dots,m$, we have a unique linear scale proportional to the layer level and 5 different box aspect ratios (width-to-height ratios), in addition to a special scale (why we need this? the paper didn’t explain. maybe just a heuristic trick) when the aspect ratio is 1. This gives us 6 anchor boxes in total per feature cell.\n$$\n\\begin{aligned}\n\\text{level index: } &\\ell = 1, \\dots, L \\\\\n\\text{scale of boxes: } &s_\\ell = s_\\text{min} + \\frac{s_\\text{max} - s_\\text{min}}{L - 1} (\\ell - 1) \\\\\n\\text{aspect ratio: } &r \\in \\{1, 2, 3, 1/2, 1/3\\}\\\\\n\\text{additional scale: } & s'_\\ell = \\sqrt{s_\\ell s_{\\ell + 1}} \\text{ when } r = 1 \\text{thus, 6 boxes in total.}\\\\\n\\text{width: } &w_\\ell^r = s_\\ell \\sqrt{r} \\\\\n\\text{height: } &h_\\ell^r = s_\\ell / \\sqrt{r} \\\\\n\\text{center location: } & (x^i_\\ell, y^j_\\ell) = (\\frac{i+0.5}{m}, \\frac{j+0.5}{n})\n\\end{aligned}\n$$\nAn example of how the anchor box size is scaled up with the layer index $\\ell$ for $L=6, s\\_\\text{min} = 0.2, s\\_\\text{max} = 0.9$. Only the boxes of aspect ratio $r=1$ are illustrated.\nAt every location, the model outputs 4 offsets and $c$ class probabilities by applying a $3 \\times 3 \\times p$ conv filter (where $p$ is the number of channels in the feature map) for every one of $k$ anchor boxes. Therefore, given a feature map of size $m \\times n$, we need $kmn(c+4)$ prediction filters.\nLoss Function\n#\nSame as YOLO, the loss function is the sum of a localization loss and a classification loss.\n$\\mathcal{L} = \\frac{1}{N}(\\mathcal{L}_\\text{cls} + \\alpha \\mathcal{L}_\\text{loc})$\nwhere $N$ is the number of matched bounding boxes and $\\alpha$ balances the weights between two losses, picked by cross validation.\nThe\nlocalization loss\nis a\nsmooth L1 loss\nbetween the predicted bounding box correction and the true values. The coordinate correction transformation is same as what\nR-CNN\ndoes in\nbounding box regression\n.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\sum_{i,j} \\sum_{m\\in\\{x, y, w, h\\}} \\mathbb{1}_{ij}^\\text{match}\n L_1^\\text{smooth}(d_m^i - t_m^j)^2\\\\\nL_1^\\text{smooth}(x) &= \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases} \\\\\nt^j_x &= (g^j_x - p^i_x) / p^i_w \\\\\nt^j_y &= (g^j_y - p^i_y) / p^i_h \\\\\nt^j_w &= \\log(g^j_w / p^i_w) \\\\\nt^j_h &= \\log(g^j_h / p^i_h)\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{ij}^\\text{match}$ indicates whether the $i$-th bounding box with coordinates $(p^i_x, p^i_y, p^i_w, p^i_h)$ is matched to the $j$-th ground truth box with coordinates $(g^j_x, g^j_y, g^j_w, g^j_h)$ for any object. $d^i_m, m\\in\\{x, y, w, h\\}$ are the predicted correction terms. See\nthis\nfor how the transformation works.\nThe\nclassification loss\nis a softmax loss over multiple classes (\nsoftmax_cross_entropy_with_logits\nin tensorflow):\n$$\n\\mathcal{L}_\\text{cls} = -\\sum_{i \\in \\text{pos}} \\mathbb{1}_{ij}^k \\log(\\hat{c}_i^k) - \\sum_{i \\in \\text{neg}} \\log(\\hat{c}_i^0)\\text{, where }\\hat{c}_i^k = \\text{softmax}(c_i^k)\n$$\nwhere $\\mathbb{1}_{ij}^k$ indicates whether the $i$-th bounding box and the $j$-th ground truth box are matched for an object in class $k$. $\\text{pos}$ is the set of matched bounding boxes ($N$ items in total) and  $\\text{neg}$ is the set of negative examples. SSD uses\nhard negative mining\nto select easily misclassified negative examples to construct this $\\text{neg}$ set: Once all the anchor boxes are sorted by objectiveness confidence score, the model picks the top candidates for training so that neg:pos is at most 3:1.\nYOLOv2 / YOLO9000\n#\nYOLOv2\n(\nRedmon & Farhadi, 2017\n) is an enhanced version of YOLO.\nYOLO9000\nis built on top of YOLOv2 but trained with joint dataset combining the COCO detection dataset and the top 9000 classes from ImageNet.\nYOLOv2 Improvement\n#\nA variety of modifications are applied to make YOLO prediction more accurate and faster, including:\n1. BatchNorm helps\n: Add\nbatch norm\non all the convolutional layers, leading to significant improvement over convergence.\n2. Image resolution matters\n: Fine-tuning the base model with\nhigh resolution\nimages improves the detection performance.\n3. Convolutional anchor box detection\n: Rather than predicts the bounding box position with fully-connected layers over the whole feature map, YOLOv2 uses\nconvolutional layers\nto predict locations of\nanchor boxes\n, like in faster R-CNN. The prediction of spatial locations and class probabilities are decoupled. Overall, the change leads to a slight decrease in mAP, but an increase in recall.\n4. K-mean clustering of box dimensions\n: Different from faster R-CNN that uses hand-picked sizes of anchor boxes, YOLOv2 runs k-mean clustering on the training data to find good priors on anchor box dimensions. The distance metric is designed to\nrely on IoU scores\n:\n$$\n\\text{dist}(x, c_i) = 1 - \\text{IoU}(x, c_i), i=1,\\dots,k\n$$\nwhere $x$ is a ground truth box candidate and $c_i$ is one of the centroids. The best number of centroids (anchor boxes) $k$ can be chosen by the\nelbow method\n.\nThe anchor boxes generated by clustering provide better average IoU conditioned on a fixed number of boxes.\n5. Direct location prediction\n: YOLOv2 formulates the bounding box prediction in a way that it would\nnot diverge\nfrom the center location too much. If the box location prediction can place the box in any part of the image, like in regional proposal network, the model training could become unstable.\nGiven the anchor box of size $(p_w, p_h)$ at the grid cell with its top left corner at $(c_x, c_y)$, the model predicts the offset and the scale, $(t_x, t_y, t_w, t_h)$ and the corresponding predicted bounding box $b$ has center $(b_x, b_y)$ and size $(b_w, b_h)$. The confidence score is the sigmoid ($\\sigma$) of another output $t_o$.\n$$\n\\begin{aligned}\nb_x &= \\sigma(t_x) + c_x\\\\\nb_y &= \\sigma(t_y) + c_y\\\\\nb_w &= p_w e^{t_w}\\\\\nb_h &= p_h e^{t_h}\\\\\n\\text{Pr}(\\text{object}) &\\cdot \\text{IoU}(b, \\text{object}) = \\sigma(t_o)\n\\end{aligned}\n$$\nYOLOv2 bounding box location prediction. (Image source:\noriginal paper\n)\n6. Add fine-grained features\n: YOLOv2 adds a passthrough layer to bring\nfine-grained features\nfrom an earlier layer to the last output layer. The mechanism of this passthrough layer is similar to\nidentity mappings in ResNet\nto extract higher-dimensional features from previous layers. This leads to 1% performance increase.\n7. Multi-scale training\n: In order to train the model to be robust to input images of different sizes, a\nnew size\nof input dimension is\nrandomly sampled\nevery 10 batches. Since conv layers of YOLOv2 downsample the input dimension by a factor of 32, the newly sampled size is a multiple of 32.\n8. Light-weighted base model\n: To make prediction even faster, YOLOv2 adopts a light-weighted base model, DarkNet-19, which has 19 conv layers and 5 max-pooling layers. The key point is to insert avg poolings and 1x1 conv filters between 3x3 conv layers.\nYOLO9000: Rich Dataset Training\n#\nBecause drawing bounding boxes on images for object detection is much more expensive than tagging images for classification, the paper proposed a way to combine small object detection dataset with large ImageNet so that the model can be exposed to a much larger number of object categories. The name of YOLO9000 comes from the top 9000 classes in ImageNet. During joint training, if an input image comes from the classification dataset, it only backpropagates the classification loss.\nThe detection dataset has much fewer and more general labels and, moreover, labels cross multiple datasets are often not mutually exclusive. For example, ImageNet has a label “Persian cat” while in COCO the same image would be labeled as “cat”. Without mutual exclusiveness, it does not make sense to apply softmax over all the classes.\nIn order to efficiently merge ImageNet labels (1000 classes, fine-grained) with COCO/PASCAL (< 100 classes, coarse-grained), YOLO9000 built a hierarchical tree structure with reference to\nWordNet\nso that general labels are closer to the root and the fine-grained class labels are leaves. In this way, “cat” is the parent node of “Persian cat”.\nThe WordTree hierarchy merges labels from COCO and ImageNet. Blue nodes are COCO labels and red nodes are ImageNet labels. (Image source:\noriginal paper\n)\nTo predict the probability of a class node, we can follow the path from the node to the root:\nPr(\"persian cat\" | contain a \"physical object\") \n= Pr(\"persian cat\" | \"cat\") \n  Pr(\"cat\" | \"animal\") \n  Pr(\"animal\" | \"physical object\") \n  Pr(contain a \"physical object\")    # confidence score.\nNote that\nPr(contain a \"physical object\")\nis the confidence score, predicted separately in the bounding box detection pipeline. The path of conditional probability prediction can stop at any step, depending on which labels are available.\nRetinaNet\n#\nThe\nRetinaNet\n(\nLin et al., 2018\n) is a one-stage dense object detector. Two crucial building blocks are\nfeaturized image pyramid\nand the use of\nfocal loss\n.\nFocal Loss\n#\nOne issue for object detection model training is an extreme imbalance between background that contains no object and foreground that holds objects of interests.\nFocal loss\nis designed to assign more weights on hard, easily misclassified examples (i.e. background with noisy texture or partial object) and to down-weight easy examples (i.e. obviously empty background).\nStarting with a normal cross entropy loss for binary classification,\n$$\n\\text{CE}(p, y) = -y\\log p - (1-y)\\log(1-p)\n$$\nwhere $y \\in \\{0, 1\\}$ is a ground truth binary label, indicating whether a bounding box contains a object, and $p \\in [0, 1]$ is the predicted probability of objectiveness (aka confidence score).\nFor notational convenience,\n$$\n\\text{let } p_t = \\begin{cases}\np    & \\text{if } y = 1\\\\\n1-p  & \\text{otherwise}\n\\end{cases},\n\\text{then } \\text{CE}(p, y)=\\text{CE}(p_t) = -\\log p_t\n$$\nEasily classified examples with large $p_t \\gg 0.5$, that is, when $p$ is very close to 0 (when y=0) or 1 (when y=1), can incur a loss with non-trivial magnitude. Focal loss explicitly adds a weighting factor $(1-p_t)^\\gamma, \\gamma \\geq 0$ to each term in cross entropy so that the weight is small when $p_t$ is large and therefore easy examples are down-weighted.\n$$\n\\text{FL}(p_t) = -(1-p_t)^\\gamma \\log p_t\n$$\nThe focal loss focuses less on easy examples with a factor of $(1-p\\_t)^\\gamma$. (Image source:\noriginal paper\n)\nFor a better control of the shape of the weighting function (see Fig. 10.), RetinaNet uses an $\\alpha$-balanced variant of the focal loss, where $\\alpha=0.25, \\gamma=2$ works the best.\n$$\n\\text{FL}(p_t) = -\\alpha (1-p_t)^\\gamma \\log p_t\n$$\nThe plot of focal loss weights $\\alpha (1-p\\_t)^\\gamma$ as a function of $p\\_t$, given different values of $\\alpha$ and $\\gamma$.\nFeaturized Image Pyramid\n#\nThe\nfeaturized image pyramid\n(\nLin et al., 2017\n) is the backbone network for RetinaNet. Following the same approach by\nimage pyramid\nin SSD, featurized image pyramids provide a basic vision component for object detection at different scales.\nThe key idea of feature pyramid network is demonstrated in The base structure contains a sequence of\npyramid levels\n, each corresponding to one network\nstage\n. One stage contains multiple convolutional layers of the same size and the stage sizes are scaled down by a factor of 2. Let’s denote the last layer of the $i$-th stage as $C_i$.\nThe illustration of the featurized image pyramid module. (Replot based on figure 3 in\nFPN paper\n)\nTwo pathways connect conv layers:\nBottom-up pathway\nis the normal feedforward computation.\nTop-down pathway\ngoes in the inverse direction, adding coarse but semantically stronger feature maps back into the previous pyramid levels of a larger size via lateral connections.\nFirst, the higher-level features are upsampled spatially coarser to be 2x larger. For image upscaling, the paper used nearest neighbor upsampling. While there are many\nimage upscaling algorithms\nsuch as using\ndeconv\n, adopting another image scaling method might or might not improve the performance of RetinaNet.\nThe larger feature map undergoes a 1x1 conv layer to reduce the channel dimension.\nFinally, these two feature maps are merged by element-wise addition.\nThe lateral connections only happen at the last layer in stages, denoted as $\\{C_i\\}$, and the process continues until the finest (largest) merged feature map is generated. The prediction is made out of every merged map after a 3x3 conv layer, $\\{P_i\\}$.\nAccording to ablation studies, the importance rank of components of the featurized image pyramid design is as follows:\n1x1 lateral connection\n> detect object across multiple layers  > top-down enrichment > pyramid representation (compared to only check the finest layer).\nModel Architecture\n#\nThe featurized pyramid is constructed on top of the ResNet architecture. Recall that\nResNet\nhas 5 conv blocks (= network stages / pyramid levels). The last layer of the $i$-th pyramid level, $C_i$, has resolution $2^i$ lower than the raw input dimension.\nRetinaNet utilizes feature pyramid levels $P_3$ to $P_7$:\n$P_3$ to $P_5$ are computed from the corresponding ResNet residual stage from $C_3$ to $C_5$. They are connected by both top-down and bottom-up pathways.\n$P_6$ is obtained via a 3×3 stride-2 conv on top of $C_5$\n$P_7$ applies ReLU and a 3×3 stride-2 conv on $P_6$.\nAdding higher pyramid levels on ResNet improves the performance for detecting large objects.\nSame as in SSD, detection happens in all pyramid levels by making a prediction out of every merged feature map. Because predictions share the same classifier and the box regressor, they are all formed to have the same channel dimension d=256.\nThere are A=9 anchor boxes per level:\nThe base size corresponds to areas of $32^2$ to $512^2$ pixels on $P_3$ to $P_7$ respectively. There are three size ratios, $\\{2^0, 2^{1/3}, 2^{2/3}\\}$.\nFor each size, there are three aspect ratios {1/2, 1, 2}.\nAs usual, for each anchor box, the model outputs a class probability for each of $K$ classes in the classification subnet and regresses the offset from this anchor box to the nearest ground truth object in the box regression subnet. The classification subnet adopts the focal loss introduced above.\nThe RetinaNet model architecture uses a\nFPN\nbackbone on top of ResNet. (Image source: the\nFPN\npaper)\nYOLOv3\n#\nYOLOv3\nis created by applying a bunch of design tricks on YOLOv2. The changes are inspired by recent advances in the object detection world.\nHere are a list of changes:\n1. Logistic regression for confidence scores\n: YOLOv3 predicts an confidence score for each bounding box using\nlogistic regression\n, while YOLO and YOLOv2 uses sum of squared errors for classification terms (see the\nloss function\nabove). Linear regression of offset prediction leads to a decrease in mAP.\n2. No more softmax for class prediction\n: When predicting class confidence, YOLOv3 uses\nmultiple independent logistic classifier\nfor each class rather than one softmax layer. This is very helpful especially considering that one image might have multiple labels and not all the labels are guaranteed to be mutually exclusive.\n3. Darknet + ResNet as the base model\n: The new Darknet-53 still relies on successive 3x3 and 1x1 conv layers, just like the original dark net architecture, but has residual blocks added.\n4. Multi-scale prediction\n: Inspired by image pyramid, YOLOv3 adds several conv layers after the base feature extractor model and makes prediction at three different scales among these conv layers. In this way, it has to deal with many more bounding box candidates of various sizes overall.\n5. Skip-layer concatenation\n: YOLOv3 also adds cross-layer connections between two prediction layers (except for the output layer) and earlier finer-grained feature maps. The model first up-samples the coarse feature maps and then merges it with the previous features by concatenation. The combination with finer-grained information makes it better at detecting small objects.\nInterestingly, focal loss does not help YOLOv3, potentially it might be due to the usage of $\\lambda_\\text{noobj}$ and $\\lambda_\\text{coord}$ — they increase the loss from bounding box location predictions and decrease the loss from confidence predictions for background boxes.\nOverall YOLOv3 performs better and faster than SSD, and worse than RetinaNet but 3.8x faster.\nThe comparison of various fast object detection models on speed and mAP performance. (Image source:\nfocal loss\npaper with additional labels from the\nYOLOv3\npaper.)\nCited as:\n@article{weng2018detection4,\n  title   = \"Object Detection Part 4: Fast Detection Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/\"\n}\nReference\n#\n[1] Joseph Redmon, et al.\n“You only look once: Unified, real-time object detection.”\nCVPR 2016.\n[2] Joseph Redmon and Ali Farhadi.\n“YOLO9000: Better, Faster, Stronger.”\nCVPR 2017.\n[3] Joseph Redmon, Ali Farhadi.\n“YOLOv3: An incremental improvement.”\n.\n[4] Wei Liu et al.\n“SSD: Single Shot MultiBox Detector.”\nECCV 2016.\n[5] Tsung-Yi Lin, et al.\n“Feature Pyramid Networks for Object Detection.”\nCVPR 2017.\n[6] Tsung-Yi Lin, et al.\n“Focal Loss for Dense Object Detection.”\nIEEE transactions on pattern analysis and machine intelligence, 2018.\n[7]\n“What’s new in YOLO v3?”\nby  Ayoosh Kathuria on “Towards Data Science”, Apr 23, 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:43Z",
            "title": "Object Detection Part 4: Fast Detection Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/466144a71db1/code/body-000.txt",
                "chars": 195,
                "language": "text"
              },
              {
                "file": "attachments/466144a71db1/code/body-001.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": true,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "retried_at": "2026-10-20T17:55:04Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.02325",
                "bytes": 2494225,
                "reused": true,
                "local_path": "papers/repair/b5f5e9ca4f7f92190f2f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.1556",
                "bytes": 200010,
                "reused": true,
                "local_path": "papers/repair/01560c40deef0c339e01.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": true,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.08242",
                "bytes": 5256083,
                "reused": true,
                "local_path": "papers/repair/1288fc7e9385e0345e39.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02002",
                "bytes": 1297358,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c9512e3ffac1aabce76e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.03144",
                "bytes": 789142,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0cd1e11096f8a72ff39b.pdf"
              },
              {
                "status": "ok",
                "url": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "bytes": 2241388,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5bc4175dabe4accf71a9.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "bytes": 5392639,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/edb99b1cb9792a271703.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25701,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/466144a71db1/pages/source.html",
            "local_html": "attachments/466144a71db1/pages/article.html",
            "body_base_path": "attachments/466144a71db1/pages/",
            "body_markdown_path": "attachments/466144a71db1/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "Redmon et al., 2016",
                "type": "a"
              },
              {
                "href": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "label": "GoogLeNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.02325",
                "label": "Liu et al, 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.1556",
                "label": "VGG-16",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits",
                "label": "softmax_cross_entropy_with_logits",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.08242",
                "label": "Redmon & Farhadi, 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Elbow_method_(clustering)",
                "label": "elbow method",
                "type": "a"
              },
              {
                "href": "https://wordnet.princeton.edu/",
                "label": "WordNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02002",
                "label": "Lin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.03144",
                "label": "Lin et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_scaling",
                "label": "image upscaling algorithms",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/layers/conv2d_transpose",
                "label": "deconv",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/TBA",
                "label": "ResNet",
                "type": "a"
              },
              {
                "href": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "label": "YOLOv3",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "label": "“YOLO9000: Better, Faster, Stronger.”",
                "type": "a"
              },
              {
                "href": "https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b",
                "label": "“What’s new in YOLO v3?”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
          "status": "partial",
          "article_id": "e63a1e66232d",
          "local_path": "series-follow/1600/repair/b1aa14adf7d8adb2ac0a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
              "bytes": 189766,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/afc61371a02b455239c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
              "bytes": 13941,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/9d81c38b488b3632ed8d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
              "bytes": 339657,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c3b89516ea58d513c6e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
              "bytes": 46457,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/5e6d7c0353c6dcedff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
              "bytes": 55893,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/7f08154f4714c6af05cf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
              "bytes": 77504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c47361447354e9dc9408.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
              "bytes": 141447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/128df9c78ce434cf9940.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
              "bytes": 42173,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/f5c3b685a188e7a1f7ea.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
              "bytes": 87321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/bb941fda00c0e424d832.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
              "bytes": 1969955,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/1c06e799c7666968bc4d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
              "bytes": 709079,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/35ad6bb4c9b5f2023552.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
              "bytes": 313503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/69879f285ee667db6764.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
              "bytes": 157401,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/2ee071176ef01990b7b2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
              "bytes": 134727,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b639597a6e7d3aecf854.png"
            }
          ],
          "article": {
            "id": "e63a1e66232d",
            "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "bytes": 189766,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-afc61371a02b455239c2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "bytes": 13941,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-9d81c38b488b3632ed8d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "bytes": 339657,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c3b89516ea58d513c6e4.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "bytes": 46457,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-5e6d7c0353c6dcedff22.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "bytes": 55893,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-7f08154f4714c6af05cf.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "bytes": 77504,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c47361447354e9dc9408.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "bytes": 141447,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-128df9c78ce434cf9940.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "bytes": 42173,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-f5c3b685a188e7a1f7ea.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "bytes": 87321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-bb941fda00c0e424d832.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "bytes": 1969955,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-1c06e799c7666968bc4d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "bytes": 709079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-35ad6bb4c9b5f2023552.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "bytes": 313503,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-69879f285ee667db6764.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "bytes": 157401,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-2ee071176ef01990b7b2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "bytes": 134727,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-b639597a6e7d3aecf854.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=vFr3K2DORc8",
                "src": "https://youtu.be/vFr3K2DORc8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-vFr3K2DORc8.mp4",
                "bytes": 753957028,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "14106.021000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=F1ka6a13S9I",
                "src": "https://youtu.be/F1ka6a13S9I",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-F1ka6a13S9I.mp4",
                "bytes": 456526601,
                "valid": true,
                "height": 720,
                "width": 1280,
                "duration": "4787.481000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=uAu3jQWaN6E",
                "src": "https://youtu.be/uAu3jQWaN6E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-uAu3jQWaN6E.mp4",
                "bytes": 183061332,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "438.401000",
                "reused": false
              }
            ],
            "body_markdown": "(The post was originated from my talk for\nWiMLDS x Fintech meetup\nhosted by\nAffirm\n.)\nI believe many of you have watched or heard of the\ngames\nbetween AlphaGo and professional Go player\nLee Sedol\nin 2016. Lee has the highest rank of nine dan and many world championships. No doubt, he is one of the best Go players in the world, but he\nlost by 1-4\nin this series versus AlphaGo. Before this, Go was considered to be an intractable game for computers to master, as its simple rules lay out an exponential number of variations in the board positions, many more than what in Chess. This event surely highlighted 2016 as a big year for AI. Because of AlphaGo, much attention has been attracted to the progress of AI.\nMeanwhile, many companies are spending resources on pushing the edges of AI applications, that indeed have the potential to change or even revolutionize how we are gonna live. Familiar examples include self-driving cars, chatbots, home assistant devices and many others. One of the secret receipts behind the progress we have had in recent years is deep learning.\nWhy Does Deep Learning Work Now?\n#\nDeep learning models, in simple words, are large and deep artificial neural nets. A neural network (“NN”) can be well presented in a\ndirected acyclic graph\n: the input layer takes in signal vectors; one or multiple hidden layers process the outputs of the previous layer. The initial concept of a neural network can be traced back to more than\nhalf a century ago\n. But why does it work now? Why do people start talking about them all of a sudden?\nA three-layer artificial neural network. (Image source:\nhttp://cs231n.github.io/convolutional-networks/#conv\n)\nThe reason is surprisingly simple:\nWe have a lot\nmore data\n.\nWe have\nmuch powerful computers\n.\nA large and deep neural network has many more layers + many more nodes in each layer, which results in exponentially many more parameters to tune. Without enough data, we cannot learn parameters efficiently. Without powerful computers, learning would be too slow and insufficient.\nHere is an interesting plot presenting the relationship between the data scale and the model performance, proposed by Andrew Ng in his “\nNuts and Bolts of Applying Deep Learning\n” talk. On a small dataset, traditional algorithms (Regression, Random Forests, SVM, GBM, etc.) or statistical learning does a great job, but once the data scale goes up to the sky, the large NN outperforms others. Partially because compared to a traditional ML model, a neural network model has many more parameters and has the capability to learn complicated nonlinear patterns. Thus we expect the model to pick the most helpful features by itself without too much expert-involved manual feature engineering.\nThe data scale versus the model performance. (Recreated based on:\nhttps://youtu.be/F1ka6a13S9I\n)\nDeep Learning Models\n#\nNext, let’s go through a few classical deep learning models.\nConvolutional Neural Network\n#\nConvolutional neural networks, short for “CNN”, is a type of feed-forward artificial neural networks, in which the connectivity pattern between its neurons is inspired by the organization of the visual cortex system. The primary visual cortex (V1) does edge detection out of the raw visual input from the retina. The secondary visual cortex (V2), also called prestriate cortex, receives the edge features from V1 and extracts simple visual properties such as orientation, spatial frequency, and color. The visual area V4 handles more complicated object attributes. All the processed visual features flow into the final logic unit, inferior temporal gyrus (IT), for object recognition. The shortcut between V1 and V4 inspires a special type of CNN with connections between non-adjacent layers: Residual Net (\nHe, et al. 2016\n) containing “Residual Block” which supports some input of one layer to be passed to the component two layers later.\nIllustration of the human visual cortex system. (Image source:\nWang & Raj 2017\n)\nConvolution is a mathematical term, here referring to an operation between two matrices. The convolutional layer has a fixed small matrix defined, also called kernel or filter. As the kernel is sliding, or convolving, across the matrix representation of the input image, it is computing the element-wise multiplication of the values in the kernel matrix and the original image values.\nSpecially designed kernels\ncan process images for common purposes like blurring, sharpening, edge detection and many others, fast and efficiently.\nThe LeNet architecture consists of two sets of convolutional, activation, and pooling layers, followed by a fully-connected layer, activation, another fully-connected layer, and finally a softmax classifier (Image source:\nhttp://deeplearning.net/tutorial/lenet.html\n)\nConvolutional\nand\npooling\n(or “sub-sampling” in Fig. 4) layers act like the V1, V2 and V4 visual cortex units, responding to feature extraction. The object recognition reasoning happens in the later fully-connected layers which consume the extracted features.\nRecurrent Neural Network\n#\nA sequence model is usually designed to transform an input sequence into an output sequence that lives in a different domain. Recurrent neural network, short for “RNN”, is suitable for this purpose and has shown tremendous improvement in problems like handwriting recognition, speech recognition, and machine translation (\nSutskever et al. 2011\n,\nLiwicki et al. 2007\n).\nA recurrent neural network model is born with the capability to process long sequential data and to tackle tasks with context spreading in time. The model processes one element in the sequence at one time step. After computation, the newly updated unit state is passed down to the next time step to facilitate the computation of the next element. Imagine the case when an RNN model reads all the Wikipedia articles, character by character, and then it can predict the following words given the context.\nA recurrent neural network with one hidden unit (left) and its unrolling version in time (right). The unrolling version illustrates what happens in time: $s\\_{t-1}$, $s\\_{t}$, and $s\\_{t+1}$ are the same unit with different states at different time steps $t-1$, $t$, and $t+1$. (Image source:\nLeCun, Bengio, and Hinton, 2015\n;\nFig. 5\n)\nHowever, simple perceptron neurons that linearly combine the current input element and the last unit state may easily lose the long-term dependencies. For example, we start a sentence with “Alice is working at …” and later after a whole paragraph, we want to start the next sentence with “She” or “He” correctly. If the model forgets the character’s name “Alice”, we can never know. To resolve the issue, researchers created a special neuron with a much more complicated internal structure for memorizing long-term context, named\n“Long-short term memory (LSTM)”\ncell. It is smart enough to learn for how long it should memorize the old information, when to forget, when to make use of the new data, and how to combine the old memory with new input. This\nintroduction\nis so well written that I recommend everyone with interest in LSTM to read it. It has been officially promoted in the\nTensorflow documentation\n;-)\nThe structure of a LSTM cell. (Image source:\nhttp://colah.github.io/posts/2015-08-Understanding-LSTMs\n)\nTo demonstrate the power of RNNs,\nAndrej Karpathy\nbuilt a character-based language model using RNN with LSTM cells.  Without knowing any English vocabulary beforehand, the model could learn the relationship between characters to form words and then the relationship between words to form sentences. It could achieve a decent performance even without a huge set of training data.\nA character-based recurrent neural network model writes like a Shakespeare. (Image source:\nhttp://karpathy.github.io/2015/05/21/rnn-effectiveness\n)\nRNN: Sequence-to-Sequence Model\n#\nThe\nsequence-to-sequence model\nis an extended version of RNN, but its application field is distinguishable enough that I would like to list it in a separated section. Same as RNN, a sequence-to-sequence model operates on sequential data, but particularly it is commonly used to develop chatbots or personal assistants, both generating meaningful response for input questions. A sequence-to-sequence model consists of two RNNs, encoder and decoder. The encoder learns the contextual information from the input words and then hands over the knowledge to the decoder side through a “\ncontext vector\n” (or “thought vector”, as shown in Fig 8.). Finally, the decoder consumes the context vector and generates proper responses.\nA sequence-to-sequence model for generating Gmail auto replies. (Image source:\nhttps://research.googleblog.com/2015/11/computer-respond-to-this-email.html\n)\nAutoencoders\n#\nDifferent from the previous models, autoencoders are for unsupervised learning. It is designed to learn a\nlow-dimensional\nrepresentation of a\nhigh-dimensional\ndata set, similar to what\nPrincipal Components Analysis (PCA)\ndoes. The autoencoder model tries to learn an approximation function $ f(x) \\approx x $ to reproduce the input data. However, it is restricted by a bottleneck layer in the middle with a very small number of nodes. With limited capacity, the model is forced to form a very efficient encoding of the data, that is essentially the low-dimensional code we learned.\nAn autoencoder model has a bottleneck layer with only a few neurons. (Image source: Geoffrey Hinton’s Coursera class\n\"Neural Networks for Machine Learning\"\n-\nWeek 15\n)\nHinton and Salakhutdinov\nused autoencoders to compress documents on a variety of topics. As shown in Fig 10, when both PCA and autoencoder were applied to reduce the documents onto two dimensions, autoencoder demonstrated a much better outcome. With the help of autoencoder, we can do efficient data compression to speed up the information retrieval including both documents and images.\nThe outputs of PCA (left) and autoencoder (right) when both try to compress documents into two numbers. (Image source:\nHinton & Salakhutdinov 2006\n)\nReinforcement (Deep) Learning\n#\nSince I started my post with AlphaGo, let us dig a bit more on why AlphaGo worked out.\nReinforcement learning (“RL”)\nis one of the secrets behind its success. RL is a subfield of machine learning which allows machines and software agents to automatically determine the optimal behavior within a given context, with a goal to maximize the long-term performance measured by a given metric.\nAlphaGo neural network training pipeline and architecture. (Image source:\nSilver et al. 2016\n)\nThe AlphaGo system starts with a supervised learning process to train a fast rollout policy and a policy network, relying on the manually curated training dataset of professional players’ games. It learns what is the best strategy given the current position on the game board. Then it applies reinforcement learning by setting up self-play games. The RL policy network gets improved when it wins more and more games against previous versions of the policy network. In the self-play stage, AlphaGo becomes stronger and stronger by playing against itself without requiring additional external training data.\nGenerative Adversarial Network\n#\nGenerative adversarial network\n, short for “GAN”, is a type of deep generative models. GAN is able to create new examples after learning through the real data.  It is consist of two models competing against each other in a zero-sum game framework. The famous deep learning researcher\nYann LeCun\ngave it a super high praise: Generative Adversarial Network is the most interesting idea in the last ten years in machine learning. (See the Quora question:\n“What are some recent and potentially upcoming breakthroughs in deep learning?”\n)\nThe architecture of a generative adversarial network. (Image source:\nhttp://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html\n)\nIn the\noriginal GAN paper\n, GAN was proposed to generate meaningful images after learning from real photos. It comprises two independent models: the\nGenerator\nand the\nDiscriminator\n. The generator produces fake images and sends the output to the discriminator model. The discriminator works like a judge, as it is optimized for identifying the real photos from the fake ones. The generator model is trying hard to cheat the discriminator while the judge is trying hard not to be cheated. This interesting zero-sum game between these two models motivates both to develop their designed skills and improve their functionalities. Eventually, we take the generator model for producing new images.\nToolkits and Libraries\n#\nAfter learning all these models, you may start wondering how you can implement the models and use them for real. Fortunately, we have many open source toolkits and libraries for building deep learning models.\nTensorflow\nis fairly new but has attracted a lot of popularity. It turns out, TensorFlow was\nthe most forked Github project of 2015\n. All that happened in a period of 2 months after its release in Nov 2015.\nHow to Learn?\n#\nIf you are very new to the field and willing to devote some time to studying deep learning in a more systematic way, I would recommend you to start with the book\nDeep Learning\nby Ian Goodfellow, Yoshua Bengio, and Aaron Courville. The Coursera course\n“Neural Networks for Machine Learning”\nby Geoffrey Hinton (\nGodfather of deep learning!\n). The content for the course was prepared around 2006, pretty old, but it helps you build up a solid foundation for understanding deep learning models and expedite further exploration.\nMeanwhile, maintain your curiosity and passion. The field is making progress every day. Even classical or widely adopted deep learning models may just have been proposed 1-2 years ago. Reading academic papers can help you learn stuff in depth and keep up with the cutting-edge findings.\nUseful resources\n#\nGoogle Scholar:\nhttp://scholar.google.com\narXiv cs section:\nhttps://arxiv.org/list/cs/recent\nUnsupervised Feature Learning and Deep Learning Tutorial\nTensorflow Tutorials\nData Science Weekly\nKDnuggets\nTons of blog posts and online tutorials\nRelated\nCousera\ncourses\nawesome-deep-learning-papers\nBlog posts mentioned\n#\nExplained Visually: Image Kernels\nUnderstanding LSTM Networks\nThe Unreasonable Effectiveness of Recurrent Neural Networks\nComputer, respond to this email.\nInteresting blogs worthy of checking\n#\nwww.wildml.com\ncolah.github.io\nkarpathy.github.io\nblog.openai.com\nPapers mentioned\n#\n[1] He, Kaiming, et al.\n“Deep residual learning for image recognition.”\nProc. IEEE Conf. on computer vision and pattern recognition. 2016.\n[2] Wang, Haohan, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800, 2017.\n[3] Sutskever, Ilya, James Martens, and Geoffrey E. Hinton.\n“Generating text with recurrent neural networks.”\nProc. of the 28th Intl. Conf. on Machine Learning (ICML). 2011.\n[4] Liwicki, Marcus, et al.\n“A novel approach to on-line handwriting recognition based on bidirectional long short-term memory networks.”\nProc. of 9th Intl. Conf. on Document Analysis and Recognition. 2007.\n[5] LeCun, Yann, Yoshua Bengio, and Geoffrey Hinton.\n“Deep learning.”\nNature 521.7553 (2015): 436-444.\n[6] Hochreiter, Sepp, and Jurgen Schmidhuber.\n“Long short-term memory.”\nNeural computation 9.8 (1997): 1735-1780.\n[7] Cho, Kyunghyun. et al.\n“Learning phrase representations using RNN encoder-decoder for statistical machine translation.”\nProc. Conference on Empirical Methods in Natural Language Processing 1724–1734 (2014).\n[8] Hinton, Geoffrey E., and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nscience 313.5786 (2006): 504-507.\n[9] Silver, David, et al.\n“Mastering the game of Go with deep neural networks and tree search.”\nNature 529.7587 (2016): 484-489.\n[10] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:58Z",
            "title": "An Overview of Deep Learning for Curious People | Lil'Log",
            "audio": [],
            "code_blocks": [],
            "papers": [
              {
                "status": "ok",
                "url": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "bytes": 603123,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ed3b4a363f27c6c78ac0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd56c51399250ef0ff86.pdf"
              },
              {
                "status": "download_error",
                "url": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='machinelearning.wustl.edu', port=80): Max retries exceeded with url: /mlpapers/paper_files/ICML2011Sutskever_524.pdf (Caused by NameResolutionError(\"HTTPCo",
                "retried_at": "2026-10-20T22:23:46Z"
              },
              {
                "status": "invalid_file_type",
                "url": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:50:42Z"
              },
              {
                "status": "ok",
                "url": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "bytes": 2083627,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6fc2936fa52baa80ec2c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "reason": "SSLError: HTTPSConnectionPool(host='web.eecs.utk.edu', port=443): Max retries exceeded with url: /~itamar/courses/ECE-692/Bobby_paper1.pdf (Caused by SSLError(SSLCertVerificationError(1, '[S",
                "retried_at": "2026-10-20T22:23:49Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.1078.pdf",
                "bytes": 1142296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/009ff3a0e4de38cf4fd9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": true,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": true,
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              },
              {
                "status": "ok",
                "url": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "bytes": 2682222,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/478be2320822b77dc4d3.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 15875,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404；invalid_file_type",
            "raw_html": "attachments/e63a1e66232d/pages/source.html",
            "local_html": "attachments/e63a1e66232d/pages/article.html",
            "body_base_path": "attachments/e63a1e66232d/pages/",
            "body_markdown_path": "attachments/e63a1e66232d/pages/article.md",
            "links": [
              {
                "href": "http://wimlds.org/chapters/about-bay-area/",
                "label": "WiMLDS x Fintech meetup",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/www.affirm.com",
                "label": "Affirm",
                "type": "a"
              },
              {
                "href": "https://youtu.be/vFr3K2DORc8",
                "label": "games",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lee_Sedol",
                "label": "Lee Sedol",
                "type": "a"
              },
              {
                "href": "https://www.scientificamerican.com/article/how-the-computer-beat-the-go-master/",
                "label": "lost by 1-4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_acyclic_graph",
                "label": "directed acyclic graph",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/eroberts/courses/soco/projects/neural-networks/History/history1.html",
                "label": "half a century ago",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/convolutional-networks/",
                "label": "http://cs231n.github.io/convolutional-networks/#conv",
                "type": "a"
              },
              {
                "href": "https://youtu.be/F1ka6a13S9I",
                "label": "Nuts and Bolts of Applying Deep Learning",
                "type": "a"
              },
              {
                "href": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "label": "He, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.07800",
                "label": "Wang & Raj 2017",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels/",
                "label": "Specially designed kernels",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/tutorial/lenet.html",
                "label": "http://deeplearning.net/tutorial/lenet.html",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/",
                "label": "Convolutional",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/Pooling/",
                "label": "pooling",
                "type": "a"
              },
              {
                "href": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "label": "Sutskever et al. 2011",
                "type": "a"
              },
              {
                "href": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "label": "Liwicki et al. 2007",
                "type": "a"
              },
              {
                "href": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "label": "LeCun, Bengio, and Hinton, 2015",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/nature/journal/v521/n7553/fig_tab/nature14539_F5.html",
                "label": "Fig. 5",
                "type": "a"
              },
              {
                "href": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "label": "“Long-short term memory (LSTM)”",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "introduction",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/recurrent",
                "label": "Tensorflow documentation",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "label": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness/",
                "label": "Andrej Karpathy",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "label": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.1078.pdf",
                "label": "sequence-to-sequence model",
                "type": "a"
              },
              {
                "href": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "label": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Principal_component_analysis",
                "label": "Principal Components Analysis (PCA)",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks",
                "label": "\"Neural Networks for Machine Learning\"",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks/home/week/15",
                "label": "Week 15",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "label": "Hinton and Salakhutdinov",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "label": "Hinton & Salakhutdinov 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Reinforcement_learning",
                "label": "Reinforcement learning (“RL”)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/nature16961",
                "label": "Silver et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/",
                "label": "Yann LeCun",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/What-are-some-recent-and-potentially-upcoming-breakthroughs-in-deep-learning",
                "label": "“What are some recent and potentially upcoming breakthroughs in deep learning?”",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/",
                "label": "Tensorflow",
                "type": "a"
              },
              {
                "href": "http://deliprao.com/archives/168",
                "label": "the most forked Github project of 2015",
                "type": "a"
              },
              {
                "href": "https://www.amazon.com/Deep-Learning-Adaptive-Computation-Machine/dp/0262035618/ref=sr_1_1?s=books&ie=UTF8&qid=1499413305&sr=1-1&keywords=deep+learning",
                "label": "Deep Learning",
                "type": "a"
              },
              {
                "href": "https://youtu.be/uAu3jQWaN6E",
                "label": "Godfather of deep learning!",
                "type": "a"
              },
              {
                "href": "http://scholar.google.com/",
                "label": "http://scholar.google.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/list/cs/recent",
                "label": "https://arxiv.org/list/cs/recent",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/",
                "label": "Unsupervised Feature Learning and Deep Learning Tutorial",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/",
                "label": "Tensorflow Tutorials",
                "type": "a"
              },
              {
                "href": "http://coursera.com/",
                "label": "Cousera",
                "type": "a"
              },
              {
                "href": "https://github.com/terryum/awesome-deep-learning-papers",
                "label": "awesome-deep-learning-papers",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels",
                "label": "Explained Visually: Image Kernels",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/",
                "label": "www.wildml.com",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/",
                "label": "colah.github.io",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/",
                "label": "karpathy.github.io",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/",
                "label": "blog.openai.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              },
              {
                "href": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "label": "“Mastering the game of Go with deep neural networks and tree search.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
          "status": "partial",
          "article_id": "b003e8b2488e",
          "local_path": "series-follow/1600/repair/e770cc6a0f63aaa24286.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
              "bytes": 231787,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/b57d68f7092bb1833c8c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
              "bytes": 277510,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c910fbb94e9497077e67.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
              "bytes": 70545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/28c7d5f3966b58d0995d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
              "bytes": 146618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3d90f7e1924950ee061d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
              "bytes": 737321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/3c5ddbb346561ac954f4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
              "bytes": 291684,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/d4e8da7e08714c6e544e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
              "bytes": 109328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/c514078611120f181162.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
              "bytes": 334060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/ce2407eb4ff860e95cdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
              "bytes": 291512,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1600/repair/assets/772893bb018752b899d9.png"
            }
          ],
          "article": {
            "id": "b003e8b2488e",
            "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "bytes": 231787,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-b57d68f7092bb1833c8c.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "bytes": 277510,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c910fbb94e9497077e67.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "bytes": 70545,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-28c7d5f3966b58d0995d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "bytes": 146618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3d90f7e1924950ee061d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "bytes": 737321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3c5ddbb346561ac954f4.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "bytes": 291684,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-d4e8da7e08714c6e544e.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "bytes": 109328,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c514078611120f181162.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "bytes": 334060,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-ce2407eb4ff860e95cdd.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "bytes": 291512,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-772893bb018752b899d9.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In my earlier post on\nmeta-learning\n, the problem is mainly defined in the context of few-shot classification. Here I would like to explore more into cases when we try to “meta-learn”\nReinforcement Learning (RL)\ntasks by developing an agent that can solve unseen tasks fast and efficiently.\nTo recap, a good meta-learning model is expected to generalize to new tasks or new environments that have never been encountered during training. The adaptation process, essentially a\nmini learning session\n, happens at test with limited exposure to the new configurations. Even without any explicit fine-tuning (no gradient backpropagation on trainable variables), the meta-learning model autonomously adjusts internal hidden states to learn.\nTraining RL algorithms can be notoriously difficult sometimes. If the meta-learning agent could become so smart that the distribution of solvable unseen tasks grows extremely broad, we are on track towards\ngeneral purpose methods\n— essentially building a “brain” which would solve all kinds of RL problems without much human interference or manual feature engineering. Sounds amazing, right? 💖\nOn the Origin of Meta-RL\n#\nBack in 2001\n#\nI encountered a paper  written in 2001 by\nHochreiter et al.\nwhen reading\nWang et al., 2016\n. Although the idea was proposed for supervised learning, there are so many resemblances to the current approach to meta-RL.\nThe meta-learning system consists of the supervisory and the subordinate systems. The subordinate system is a recurrent neural network that takes as input both the observation at the current time step, $x\\_t$ and the label at the last time step, $y\\_{t-1}$. (Image source:\nHochreiter et al., 2001\n)\nHochreiter’s meta-learning model is a recurrent network with LSTM cell. LSTM is a good choice because it can internalize a history of inputs and tune its own weights effectively through\nBPTT\n. The training data contains $K$ sequences and each sequence is consist of $N$ samples generated by a target function $f_k(.), k=1, \\dots, K$,\n$$\n\\{\\text{input: }(\\mathbf{x}^k_i, \\mathbf{y}^k_{i-1}) \\to \\text{label: }\\mathbf{y}^k_i\\}_{i=1}^N\n\\text{ where }\\mathbf{y}^k_i = f_k(\\mathbf{x}^k_i)\n$$\nNoted that\nthe last label\n$\\mathbf{y}^k_{i-1}$ is also provided as an auxiliary input so that the function can learn the presented mapping.\nIn the experiment of decoding two-dimensional quadratic functions, $a x_1^2 + b x_2^2 + c x_1 x_2 + d x_1 + e x_2 + f$, with coefficients $a$-$f$ are randomly sampled from [-1, 1], this meta-learning system was able to approximate the function after seeing only ~35 examples.\nProposal in 2016\n#\nIn the modern days of DL,\nWang et al.\n(2016) and\nDuan et al.\n(2017) simultaneously proposed the very similar idea of\nMeta-RL\n(it is called\nRL^2\nin the second paper). A meta-RL model is trained over a distribution of MDPs, and at test time, it is able to learn to solve a new task quickly. The goal of meta-RL is ambitious, taking one step further towards general algorithms.\nDefine Meta-RL\n#\nMeta Reinforcement Learning\n, in short, is to do\nmeta-learning\nin the field of\nreinforcement learning\n. Usually the train and test tasks are different but drawn from the same family of problems; i.e., experiments in the papers included multi-armed bandit with different reward probabilities, mazes with different layouts, same robots but with different physical parameters in simulator, and many others.\nFormulation\n#\nLet’s say we have a distribution of tasks, each formularized as an\nMDP\n(Markov Decision Process), $M_i \\in \\mathcal{M}$. An MDP is determined by a 4-tuple, $M_i= \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle$:\nSymbol\nMeaning\n$\\mathcal{S}$\nA set of states.\n$\\mathcal{A}$\nA set of actions.\n$P_i: \\mathcal{S} \\times \\mathcal{A} \\times \\mathcal{S} \\to \\mathbb{R}_{+}$\nTransition probability function.\n$R_i: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}$\nReward function.\n(RL^2 paper adds an extra parameter, horizon $T$, into the MDP tuple to emphasize that each MDP should have a finite horizon.)\nNote that common state $\\mathcal{S}$ and action space $\\mathcal{A}$ are used above, so that a (stochastic) policy: $\\pi_\\theta: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}_{+}$ would get inputs compatible across different tasks. The test tasks are sampled from the same distribution $\\mathcal{M}$ or slightly modified version.\nIllustration of meta-RL, containing two optimization loops. The outer loop samples a new environment in every iteration and adjusts parameters that determine the agent's behavior. In the inner loop, the agent interacts with the environment and optimizes for the maximal reward. (Image source:\nBotvinick, et al. 2019\n)\nMain Differences from RL\n#\nThe overall configure of meta-RL is very similar to an ordinary RL algorithm, except that\nthe last reward\n$r_{t-1}$ and\nthe last action\n$a_{t-1}$ are also incorporated into the policy observation in addition to the current state $s_t$.\nIn RL: $\\pi_\\theta(s_t) \\to$  a distribution over $\\mathcal{A}$\nIn meta-RL: $\\pi_\\theta(a_{t-1}, r_{t-1}, s_t) \\to$  a distribution over $\\mathcal{A}$\nThe intention of this design is to feed a history into the model so that the policy can internalize the dynamics between states, rewards, and actions in the current MDP and adjust its strategy accordingly. This is well aligned with the setup in\nHochreiter’s system\n. Both meta-RL and RL^2 implemented an LSTM policy and the LSTM’s hidden states serve as a\nmemory\nfor tracking characteristics of the trajectories. Because the policy is recurrent, there is no need to feed the last state as inputs explicitly.\nThe training procedure works as follows:\nSample a new MDP, $M_i \\sim \\mathcal{M}$;\nReset the hidden state\nof the model;\nCollect multiple trajectories and update the model weights;\nRepeat from step 1.\nIn the meta-RL paper, different actor-critic architectures all use a recurrent model. Last reward and last action are additional inputs. The observation is fed into the LSTM either as a one-hot vector or as an embedding vector after passed through an encoder model. (Image source:\nWang et al., 2016\n)\nAs described in the RL^2 paper, illustration of the procedure of the model interacting with a series of MDPs in training time . (Image source:\nDuan et al., 2017\n)\nKey Components\n#\nThere are three key components in Meta-RL:\n⭐\nA Model with Memory\nA recurrent neural network maintains a hidden state. Thus, it could acquire and memorize the knowledge about the current task by updating the hidden state during rollouts. Without memory, meta-RL would not work.\n⭐\nMeta-learning Algorithm\nA meta-learning algorithm refers to how we can update the model weights to optimize for the purpose of solving an unseen task fast at test time. In both Meta-RL and RL^2 papers, the meta-learning algorithm is the ordinary gradient descent update of LSTM with hidden state reset between a switch of MDPs.\n⭐\nA Distribution of MDPs\nWhile the agent is exposed to a variety of environments and tasks during training, it has to learn how to adapt to different MDPs.\nAccording to\nBotvinick et al.\n(2019), one source of slowness in RL training is\nweak\ninductive bias\n( = “a set of assumptions that the learner uses to predict outputs given inputs that it has not encountered”). As a general ML rule, a learning algorithm with weak inductive bias will be able to master a wider range of variance, but usually, will be less sample-efficient. Therefore, to narrow down the hypotheses with stronger inductive biases help improve the learning speed.\nIn meta-RL, we impose certain types of inductive biases from the\ntask distribution\nand store them in\nmemory\n. Which inductive bias to adopt at test time depends on the\nalgorithm\n. Together, these three key components depict a compelling view of meta-RL: Adjusting the weights of a recurrent network is slow but it allows the model to work out a new task fast with its own RL algorithm implemented in its internal activity dynamics.\nMeta-RL interestingly and not very surprisingly matches the ideas in the\nAI-GAs\n(“AI-Generating Algorithms”) paper by Jeff Clune (2019). He proposed that one efficient way towards building general AI is to make learning as automatic as possible. The AI-GAs approach involves three pillars: (1) meta-learning architectures, (2) meta-learning algorithms, and (3) automatically generated environments for effective learning.\nThe topic of designing good recurrent network architectures is a bit too broad to be discussed here, so I will skip it. Next, let’s look further into another two components: meta-learning algorithms in the context of meta-RL and how to acquire a variety of training MDPs.\nMeta-Learning Algorithms for Meta-RL\n#\nMy previous\npost\non meta-learning has covered several classic meta-learning algorithms. Here I’m gonna include more related to RL.\nOptimizing Model Weights for Meta-learning\n#\nBoth MAML (\nFinn, et al. 2017\n) and Reptile (\nNichol et al., 2018\n) are methods on updating model parameters in order to achieve good generalization performance on new tasks. See an earlier post\nsection\non MAML and Reptile.\nMeta-learning Hyperparameters\n#\nThe\nreturn\nfunction in an RL problem, $G_t^{(n)}$ or $G_t^\\lambda$, involves a few hyperparameters that are often set heuristically, like the discount factor\n$\\gamma$\nand the bootstrapping parameter\n$\\lambda$\n.\nMeta-gradient RL (\nXu et al., 2018\n) considers them as\nmeta-parameters\n, $\\eta=\\{\\gamma, \\lambda \\}$, that can be tuned and learned\nonline\nwhile an agent is interacting with the environment. Therefore, the return becomes a function of $\\eta$ and dynamically adapts itself to a specific task over time.\n$$\n\\begin{aligned}\nG_\\eta^{(n)}(\\tau_t) &= R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1}R_{t+n} + \\gamma^n v_\\theta(s_{t+n}) & \\scriptstyle{\\text{; n-step return}} \\\\\nG_\\eta^{\\lambda}(\\tau_t) &= (1-\\lambda) \\sum_{n=1}^\\infty \\lambda^{n-1} G_\\eta^{(n)} & \\scriptstyle{\\text{; λ-return, mixture of n-step returns}}\n\\end{aligned}\n$$\nDuring training, we would like to update the policy parameters with gradients as a function of all the information in hand, $\\theta’ = \\theta + f(\\tau, \\theta, \\eta)$, where $\\theta$ are the current model weights, $\\tau$ is a sequence of trajectories, and $\\eta$ are the meta-parameters.\nMeanwhile, let’s say we have a meta-objective function $J(\\tau, \\theta, \\eta)$ as a performance measure. The training process follows the principle of online cross-validation, using a sequence of consecutive experiences:\nStarting with parameter $\\theta$, the policy $\\pi_\\theta$ is updated on the first batch of samples $\\tau$, resulting in $\\theta’$.\nThen we continue running the policy $\\pi_{\\theta’}$ to collect a new set of experiences $\\tau’$, just following $\\tau$ consecutively in time. The performance is measured as $J(\\tau’, \\theta’, \\bar{\\eta})$ with a fixed meta-parameter $\\bar{\\eta}$.\nThe gradient of meta-objective $J(\\tau’, \\theta’, \\bar{\\eta})$ w.r.t. $\\eta$ is used to update $\\eta$:\n$$\n\\begin{aligned}\n\\Delta \\eta\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\eta} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{d\\theta'}{d\\eta} & \\scriptstyle{\\text{ ; single variable chain rule.}} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial (\\theta + f(\\tau, \\theta, \\eta))}{\\partial\\eta}  \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big(\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\frac{d\\eta}{d\\eta} \\Big) & \\scriptstyle{\\text{; multivariable chain rule.}}\\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big( \\color{red}{\\big(\\mathbf{I} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\big)}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\Big) & \\scriptstyle{\\text{; secondary gradient term in red.}}\n\\end{aligned}\n$$\nwhere $\\beta$ is the learning rate for $\\eta$.\nThe meta-gradient RL algorithm simplifies the computation by setting the secondary gradient term to zero, $\\mathbf{I} + \\partial g(\\tau, \\theta, \\eta)/\\partial\\theta = 0$ — this choice prefers the immediate effect of the meta-parameters $\\eta$ on the parameters $\\theta$. Eventually we get:\n$$\n\\Delta \\eta = -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\n$$\nExperiments in the paper adopted the meta-objective function same as $TD(\\lambda)$ algorithm, minimizing the error between the approximated value function $v_\\theta(s)$ and the $\\lambda$-return:\n$$\n\\begin{aligned}\nJ(\\tau, \\theta, \\eta) &= (G^\\lambda_\\eta(\\tau) - v_\\theta(s))^2 \\\\\nJ(\\tau', \\theta', \\bar{\\eta}) &= (G^\\lambda_{\\bar{\\eta}}(\\tau') - v_{\\theta'}(s'))^2\n\\end{aligned}\n$$\nMeta-learning the Loss Function\n#\nIn policy gradient algorithms, the expected total reward is maximized by updating the policy parameters $\\theta$ in the direction of estimated gradient (\nSchulman et al., 2016\n),\n$$\ng = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\nabla_\\theta \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nwhere the candidates for $\\Psi_t$ include the trajectory return $G_t$, the Q value $Q(s_t, a_t)$, or the advantage value $A(s_t, a_t)$. The corresponding surrogate loss function for the policy gradient can be reverse-engineered:\n$$\nL_\\text{pg} = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nThis loss function is a measure over a history of trajectories, $(s_0, a_0, r_0, \\dots, s_t, a_t, r_t, \\dots)$.\nEvolved Policy Gradient\n(\nEPG\n;\nHouthooft, et al, 2018\n) takes a step further by defining the policy gradient loss function as a temporal convolution (1-D convolution) over the agent’s past experience, $L_\\phi$. The parameters $\\phi$ of the loss function network are evolved in a way that an agent can achieve higher returns.\nSimilar to many meta-learning algorithms, EPG has two optimization loops:\nIn the internal loop, an agent learns to improve its policy $\\pi_\\theta$.\nIn the outer loop, the model updates the parameters $\\phi$ of the loss function $L_\\phi$. Because there is no explicit way to write down a differentiable equation between the return and the loss, EPG turned to\nEvolutionary Strategies\n(ES).\nA general idea is to train a population of $N$ agents, each of them is trained with the loss function $L_{\\phi + \\sigma \\epsilon_i}$ parameterized with $\\phi$ added with a small Gaussian noise $\\epsilon_i \\sim \\mathcal{N}(0, \\mathbf{I})$ of standard deviation $\\sigma$. During the inner loop’s training, EPG tracks a history of experience and updates the policy parameters according to the loss function $L_{\\phi + \\sigma\\epsilon_i}$ for each agent:\n$$\n\\theta_i \\leftarrow \\theta - \\alpha_\\text{in} \\nabla_\\theta L_{\\phi + \\sigma \\epsilon_i} (\\pi_\\theta, \\tau_{t-K, \\dots, t})\n$$\nwhere $\\alpha_\\text{in}$ is the learning rate of the inner loop and $\\tau_{t-K, \\dots, t}$ is a sequence of $M$ transitions up to the current time step $t$.\nOnce the inner loop policy is mature enough, the policy is evaluated by the mean return $\\bar{G}_{\\phi+\\sigma\\epsilon_i}$ over multiple randomly sampled trajectories. Eventually, we are able to estimate the gradient of $\\phi$ according to\nNES\nnumerically (\nSalimans et al, 2017\n). While repeating this process, both the policy parameters $\\theta$ and the loss function weights $\\phi$ are being updated simultaneously to achieve higher returns.\n$$\n\\phi \\leftarrow \\phi + \\alpha_\\text{out} \\frac{1}{\\sigma N} \\sum_{i=1}^N \\epsilon_i G_{\\phi+\\sigma\\epsilon_i}\n$$\nwhere $\\alpha_\\text{out}$ is the learning rate of the outer loop.\nIn practice, the loss $L_\\phi$ is bootstrapped with an ordinary policy gradient (such as REINFORCE or PPO) surrogate loss $L_\\text{pg}$, $\\hat{L} = (1-\\alpha) L_\\phi + \\alpha L_\\text{pg}$. The weight $\\alpha$ is annealing from 1 to 0 gradually during training. At test time, the loss function parameter $\\phi$ stays fixed and the loss value is computed over a history of experience to update the policy parameters $\\theta$.\nMeta-learning the Exploration Strategies\n#\nThe\nexploitation vs exploration\ndilemma is a critical problem in RL. Common ways to do exploration include $\\epsilon$-greedy, random noise on actions, or stochastic policy with built-in randomness on the action space.\nMAESN\n(\nGupta et al, 2018\n) is an algorithm to learn structured action noise from prior experience for better and more effective exploration. Simply adding random noise on actions cannot capture task-dependent or time-correlated exploration strategies. MAESN changes the policy to condition on a per-task random variable $z_i \\sim \\mathcal{N}(\\mu_i, \\sigma_i)$, for $i$-th task $M_i$, so we would have a policy $a \\sim \\pi_\\theta(a\\mid s, z_i)$.\nThe latent variable $z_i$ is sampled once and fixed during one episode. Intuitively, the latent variable determines one type of behavior (or skills) that should be explored more at the beginning of a rollout and the agent would adjust its actions accordingly. Both the policy parameters and latent space are optimized to maximize the total task rewards. In the meantime, the policy learns to make use of the latent variables for exploration.\nIn addition,  the loss function includes a KL divergence between the learned latent variable and a unit Gaussian prior, $D_\\text{KL}(\\mathcal{N}(\\mu_i, \\sigma_i)|\\mathcal{N}(0, \\mathbf{I}))$. On one hand, it restricts the learned latent space not too far from a common prior. On the other hand, it creates the variational evidence lower bound (\nELBO\n) for the reward function. Interestingly the paper found that $(\\mu_i, \\sigma_i)$ for each task are usually close to the prior at convergence.\nThe policy is conditioned on a latent variable variable $z\\_i \\sim \\mathcal{N}(\\mu, \\sigma)$ that is sampled once every episode. Each task has different hyperparameters for the latent variable distribution, $(\\mu\\_i, \\sigma\\_i)$ and they are optimized in the outer loop. (Image source:\nGupta et al, 2018\n)\nEpisodic Control\n#\nA major criticism of RL is on its sample inefficiency. A large number of samples and small learning steps are required for incremental parameter adjustment in RL in order to maximize generalization and avoid catastrophic forgetting of earlier learning (\nBotvinick et al., 2019\n).\nEpisodic control\n(\nLengyel & Dayan, 2008\n) is proposed as a solution to avoid forgetting and improve generalization while training at a faster speed. It is partially inspired by hypotheses on instance-based\nhippocampal\nlearning.\nAn\nepisodic memory\nkeeps explicit records of past events and uses these records directly as point of reference for making new decisions (i.e. just like\nmetric-based\nmeta-learning). In\nMFEC\n(Model-Free Episodic Control;\nBlundell et al., 2016\n), the memory is modeled as a big table, storing the state-action pair $(s, a)$ as key and the corresponding Q-value $Q_\\text{EC}(s, a)$ as value. When receiving a new observation $s$, the Q value is estimated in an non-parametric way as the average Q-value of top $k$ most similar samples:\n$$\n\\hat{Q}_\\text{EC}(s, a) = \n\\begin{cases}\nQ_\\text{EC}(s, a)                      & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\n\\frac{1}{k} \\sum_{i=1}^k Q(s^{(i)}, a) & \\text{otherwise}\n\\end{cases}\n$$\nwhere $s^{(i)}, i=1, \\dots, k$ are top $k$ states with smallest distances to the state $s$. Then the action that yields the highest estimated Q value is selected. Then the memory table is updated according to the return received at $s_t$:\n$$\nQ_\\text{EC}(s, a) \\leftarrow\n\\begin{cases}\n\\max\\{Q_\\text{EC}(s_t, a_t), G_t\\}  & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\nG_t                                 & \\text{otherwise}\n\\end{cases}\n$$\nAs a tabular RL method, MFEC suffers from large memory consumption and a lack of ways to generalize among similar states. The first one can be fixed with an LRU cache. Inspired by\nmetric-based\nmeta-learning, especially Matching Networks (\nVinyals et al., 2016\n), the generalization problem is improved in a follow-up algorithm,\nNEC\n(Neural Episodic Control;\nPritzel et al., 2016\n).\nThe episodic memory in NEC is a Differentiable Neural Dictionary (\nDND\n), where the key is a convolutional embedding vector of input image pixels and the value stores estimated Q value. Given an inquiry key, the output is a weighted sum of values of top similar keys, where the weight is a normalized kernel measure between the query key and the selected key in the dictionary. This sounds like a hard\nattention\nmachanism.\nFig. 6 Illustrations of episodic memory module in NEC and two operations on a differentiable neural dictionary. (Image source:\nPritzel et al., 2016\n)\nFurther,\nEpisodic LSTM\n(\nRitter et al., 2018\n) enhances the basic LSTM architecture with a DND episodic memory, which stores task context embeddings as keys and the LSTM cell states as values. The stored hidden states are retrieved and added directly to the current cell state through the same gating mechanism within LSTM:\nIllustration of the episodic LSTM architecture. The additional structure of episodic memory is in bold. (Image source:\nRitter et al., 2018\n)\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\mathbf{i}_t \\circ \\mathbf{c}_\\text{in} + \\mathbf{f}_t \\circ \\mathbf{c}_{t-1} + \\color{green}{\\mathbf{r}_t \\circ \\mathbf{c}_\\text{ep}} &\\\\\n\\mathbf{i}_t &= \\sigma(\\mathbf{W}_{i} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_i) & \\scriptstyle{\\text{; input gate}} \\\\\n\\mathbf{f}_t &= \\sigma(\\mathbf{W}_{f} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_f) & \\scriptstyle{\\text{; forget gate}} \\\\\n\\color{green}{\\mathbf{r}_t} & \\color{green}{=} \\color{green}{\\sigma(\\mathbf{W}_{r} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_r)} & \\scriptstyle{\\text{; reinstatement gate}}\n\\end{aligned}\n$$\nwhere $\\mathbf{c}_t$ and $\\mathbf{h}_t$ are hidden and cell state at time $t$; $\\mathbf{i}_t$, $\\mathbf{f}_t$ and $\\mathbf{r}_t$ are input, forget and reinstatement gates, respectively; $\\mathbf{c}_\\text{ep}$ is the retrieved cell state from episodic memory. The newly added episodic memory components are marked in green.\nThis architecture provides a shortcut to the prior experience through context-based retrieval. Meanwhile, explicitly saving the task-dependent experience in an external memory avoids forgetting. In the paper, all the experiments have manually designed context vectors. How to construct an effective and efficient format of task context embeddings for more free-formed tasks would be an interesting topic.\nOverall the capacity of episodic control is limited by the complexity of the environment. It is very rare for an agent to repeatedly visit exactly the same states in a real-world task, so properly encoding the states is critical. The learned embedding space compresses the observation data into a lower dimension space and, in the meantime, two states being close in this space are expected to demand similar strategies.\nTraining Task Acquisition\n#\nAmong three key components, how to design a proper distribution of tasks is the less studied and probably the most specific one to meta-RL itself. As described\nabove\n, each task is a MDP: $M_i = \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle \\in \\mathcal{M}$. We can build a distribution of MDPs by modifying:\nThe\nreward configuration\n: Among different tasks, same behavior might get rewarded differently according to $R_i$.\nOr, the\nenvironment\n: The transition function $P_i$ can be reshaped by initializing the environment with varying shifts between states.\nTask Generation by Domain Randomization\n#\nRandomizing parameters in a simulator is an easy way to obtain tasks with modified transition functions. If interested in learning further, check my last\npost\non\ndomain randomization\n.\nEvolutionary Algorithm on Environment Generation\n#\nEvolutionary algorithm\nis a gradient-free heuristic-based optimization method, inspired by natural selection. A population of solutions follows a loop of evaluation, selection, reproduction, and mutation. Eventually, good solutions survive and thus get selected.\nPOET\n(\nWang et al, 2019\n), a framework based on the evolutionary algorithm, attempts to generate tasks while the problems themselves are being solved. The implementation of POET is only specifically designed for a simple 2D\nbipedal walker\nenvironment but points out an interesting direction. It is noteworthy that the evolutionary algorithm has had some compelling applications in Deep Learning like\nEPG\nand PBT (Population-Based Training;\nJaderberg et al, 2017\n).\nAn example bipedal walking environment (top) and an overview of POET (bottom). (Image source:\nPOET blog post\n)\nThe 2D bipedal walking environment is evolving: from a simple flat surface to a much more difficult trail with potential gaps, stumps, and rough terrains. POET pairs the generation of environmental challenges and the optimization of agents together so as to (a) select agents that can resolve current challenges and (b) evolve environments to be solvable. The algorithm maintains a list of\nenvironment-agent pairs\nand repeats the following:\nMutation\n: Generate new environments from currently active environments. Note that here types of mutation operations are created just for bipedal walker and a new environment would demand a new set of configurations.\nOptimization\n: Train paired agents within their respective environments.\nSelection\n: Periodically attempt to transfer current agents from one environment to another. Copy and update the best performing agent for every environment. The intuition is that skills learned in one environment might be helpful for a different environment.\nThe procedure above is quite similar to\nPBT\n, but PBT mutates and evolves hyperparameters instead. To some extent, POET is doing\ndomain randomization\n, as all the gaps, stumps and terrain roughness are controlled by some randomization probability parameters. Different from DR, the agents are not exposed to a fully randomized difficult environment all at once, but instead they are learning gradually with a curriculum configured by the evolutionary algorithm.\nLearning with Random Rewards\n#\nAn MDP without a reward function $R$ is known as a\nControlled Markov process\n(CMP). Given a predefined CMP, $\\langle \\mathcal{S}, \\mathcal{A}, P\\rangle$, we can acquire a variety of tasks by generating a collection of reward functions $\\mathcal{R}$ that encourage the training of an effective meta-learning policy.\nGupta et al. (2018)\nproposed two unsupervised approaches  for growing the task distribution in the context of CMP. Assuming there is an underlying latent variable $z \\sim p(z)$ associated with every task, it parameterizes/determines a reward function: $r_z(s) = \\log D(z|s)$, where a “discriminator” function $D(.)$ is used to extract the latent variable from the state. The paper described two ways to construct a discriminator function:\nSample random weights $\\phi_\\text{rand}$ of the discriminator, $D_{\\phi_\\text{rand}}(z \\mid s)$.\nLearn a discriminator function to encourage diversity-driven exploration. This method is introduced in more details in another sister paper “DIAYN” (\nEysenbach et al., 2018\n).\nDIAYN, short for “Diversity is all you need”, is a framework to encourage a policy to learn useful skills without a reward function. It explicitly models the latent variable $z$ as a\nskill\nembedding and makes the policy conditioned on $z$ in addition to state $s$, $\\pi_\\theta(a \\mid s, z)$. (Ok, this part is same as\nMAESN\nunsurprisingly, as the papers are from the same group.) The design of DIAYN is motivated by a few hypotheses:\nSkills should be diverse and lead to visitations of different states. → maximize the mutual information between states and skills, $I(S; Z)$\nSkills should be distinguishable by states, not actions. → minimize the mutual information between actions and skills, conditioned on states $I(A; Z \\mid S)$\nThe objective function to maximize is as follows, where the policy entropy is also added to encourage diversity:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta) \n&= I(S; Z) + H[A \\mid S] - I(A; Z \\mid S) &  \\\\\n&= (H(Z) - H(Z \\mid S)) + H[A \\mid S] - (H[A\\mid S] - H[A\\mid S, Z]) & \\\\\n&= H[A\\mid S, Z] \\color{green}{- H(Z \\mid S) + H(Z)} & \\\\\n&= H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\log p(z \\mid s)] - \\mathbb{E}_{z\\sim p(z)}[\\log p(z)] & \\scriptstyle{\\text{; can infer skills from states & p(z) is diverse.}} \\\\\n&\\ge H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\color{red}{\\log D_\\phi(z \\mid s) - \\log p(z)}] & \\scriptstyle{\\text{; according to Jensen's inequality; \"pseudo-reward\" in red.}}\n\\end{aligned}\n$$\nwhere $I(.)$ is mutual information and $H[.]$ is entropy measure. We cannot integrate all states to compute $p(z \\mid s)$, so approximate it with $D_\\phi(z \\mid s)$ — that is the diversity-driven discriminator function.\nDIAYN Algorithm. (Image source:\nEysenbach et al., 2019\n)\nOnce the discriminator function is learned, sampling a new MDP for training is strainght-forward: First, sample a latent variable, $z \\sim p(z)$ and construct a reward function $r_z(s) = \\log(D(z \\vert s))$. Pairing the reward function with a predefined CMP creates a new MDP.\nCited as:\n@article{weng2019metaRL,\n  title   = \"Meta Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-06-23-meta-rl/\"\n}\nReferences\n#\n[1] Richard S. Sutton.\n“The Bitter Lesson.”\nMarch 13, 2019.\n[2] Sepp Hochreiter, A. Steven Younger, and Peter R. Conwell.\n“Learning to learn using gradient descent.”\nIntl. Conf. on Artificial Neural Networks. 2001.\n[3] Jane X Wang, et al.\n“Learning to reinforcement learn.”\narXiv preprint arXiv:1611.05763 (2016).\n[4] Yan Duan, et al.\n“RL $^ 2$: Fast Reinforcement Learning via Slow Reinforcement Learning.”\nICLR 2017.\n[5] Matthew Botvinick, et al.\n“Reinforcement Learning, Fast and Slow”\nCell Review, Volume 23, Issue 5, P408-422, May 01, 2019.\n[6] Jeff Clune.\n“AI-GAs: AI-generating algorithms, an alternate paradigm for producing general artificial intelligence”\narXiv preprint arXiv:1905.10985 (2019).\n[7] Zhongwen Xu, et al.\n“Meta-Gradient Reinforcement Learning”\nNIPS 2018.\n[8] Rein Houthooft, et al.\n“Evolved Policy Gradients.”\nNIPS 2018.\n[9] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[10] Abhishek Gupta, et al.\n“Meta-Reinforcement Learning of Structured Exploration Strategies.”\nNIPS 2018.\n[11] Alexander Pritzel, et al.\n“Neural episodic control.”\nProc. Intl. Conf. on Machine Learning, Volume 70, 2017.\n[12] Charles Blundell, et al.\n“Model-free episodic control.”\narXiv preprint arXiv:1606.04460 (2016).\n[13] Samuel Ritter, et al.\n“Been there, done that: Meta-learning with episodic recall.”\nICML, 2018.\n[14] Rui Wang et al.\n“Paired Open-Ended Trailblazer (POET): Endlessly Generating Increasingly Complex and Diverse Learning Environments and Their Solutions”\narXiv preprint arXiv:1901.01753 (2019).\n[15] Uber Engineering Blog:\n“POET: Endlessly Generating Increasingly Complex and Diverse Learning Environments and their Solutions through the Paired Open-Ended Trailblazer.”\nJan 8, 2019.\n[16] Abhishek Gupta, et al.\n“Unsupervised meta-learning for Reinforcement Learning”\narXiv preprint arXiv:1806.04640 (2018).\n[17] Eysenbach, Benjamin, et al.\n“Diversity is all you need: Learning skills without a reward function.”\nICLR 2019.\n[18] Max Jaderberg, et al.\n“Population Based Training of Neural Networks.”\narXiv preprint arXiv:1711.09846 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:27Z",
            "title": "Meta Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/b003e8b2488e/code/body-000.txt",
                "chars": 223,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763.pdf",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d07e19c65fe402fbcd87.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ef36a4fe103ce19e63ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02779",
                "bytes": 1730325,
                "reused": true,
                "local_path": "papers/repair/29d9036eedf2ce0e8bad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.10985",
                "bytes": 421434,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0e39e620cbcdc3c0e38c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": true,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "bytes": 1111580,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bb993313e45a20ad529a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "bytes": 1779803,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/85a9a7621c9e0663fa1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "bytes": 2498781,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ddef5bb7adf90b31a4e2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "bytes": 227616,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1c0ac870da375a0164dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04460",
                "bytes": 915060,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6d8db7782bea674b000.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": true,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01988",
                "bytes": 2536595,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e1d79161cd219f80796c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09692",
                "bytes": 1441925,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b25973c32f2180b33c22.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.04640",
                "bytes": 2305556,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/022e9be73e69c1bb6162.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.06070",
                "bytes": 10804715,
                "reused": true,
                "local_path": "papers/repair/682027046f87efa4a50a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31542,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b003e8b2488e/pages/source.html",
            "local_html": "attachments/b003e8b2488e/pages/article.html",
            "body_base_path": "attachments/b003e8b2488e/pages/",
            "body_markdown_path": "attachments/b003e8b2488e/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning (RL)",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/IncIdeas/BitterLesson.html",
                "label": "general purpose methods",
                "type": "a"
              },
              {
                "href": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "label": "Hochreiter et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.05763.pdf",
                "label": "Wang et al., 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Backpropagation_through_time",
                "label": "BPTT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.05763",
                "label": "Wang et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02779",
                "label": "Duan et al.",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/action/showPdf?pii=S1364-6613%2819%2930061-0",
                "label": "Botvinick, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Inductive_bias",
                "label": "inductive bias",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.10985",
                "label": "AI-GAs",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol et al., 2018",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "label": "Xu et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "label": "Houthooft, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolutionary Strategies",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "NES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans et al, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "exploitation vs exploration",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "label": "Gupta et al, 2018",
                "type": "a"
              },
              {
                "href": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "label": "ELBO",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/trends/cognitive-sciences/fulltext/S1364-6613(19)30061-0",
                "label": "Botvinick et al., 2019",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "label": "Lengyel & Dayan, 2008",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hippocampus",
                "label": "hippocampal",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04460",
                "label": "Blundell et al., 2016",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01988",
                "label": "Pritzel et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09692",
                "label": "Ritter et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolutionary_algorithm",
                "label": "Evolutionary algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://gym.openai.com/envs/BipedalWalkerHardcore-v2/",
                "label": "bipedal walker",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://eng.uber.com/poet-open-ended-deep-learning/",
                "label": "POET blog post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.04640",
                "label": "Gupta et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.06070",
                "label": "Eysenbach et al., 2018",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        }
      ],
      "updated_at": "2026-10-18T08:44:13Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 2082,
      "source_url": "https://zhuanlan.zhihu.com/p/58038609",
      "items": [
        {
          "url": "https://zhuanlan.zhihu.com/p/58038609",
          "status": "http_403"
        }
      ],
      "updated_at": "2026-10-14T11:43:23Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 4,
      "source_url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
      "items": [
        {
          "url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
          "status": "ok",
          "article_id": "16d6a36a3560",
          "local_path": "series-follow/4/repair/f452d4b30b190056ba84.html",
          "images": [
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!96vs!,w_40,h_40,c_fill,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f25d0a-212b-4853-8bcb-128d0a3edbbf_1196x1196.png",
              "bytes": 4638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/4/repair/assets/920ce5c0c94112fc8a9f.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!xQ0c!,e_trim:10:white/e_trim:10:transparent/h_108,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5083e6d3-fbc9-4870-95b9-6e85d02f62a6_9366x2023.png",
              "bytes": 5271,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/4/repair/assets/71086f9116582f0ba4da.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
              "bytes": 121470,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/4/repair/assets/1c343ecc9eadd930f4bd.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "Substack",
            "author": "Sebastian Raschka / Ahead of AI",
            "title_listed": "Building LLMs from the Ground Up",
            "keywords": "LLM构建,Tokenizer,Transformer,训练",
            "domain": "大模型算法",
            "content_type": "教程系列",
            "is_paid_flag": "否",
            "url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
            "publish_date": "2024-06",
            "corpus_stage": "预训练",
            "notes": "从零构建LLM的完整教程，信息密度极高",
            "id": "16d6a36a3560",
            "collected_at": "2026-10-01T19:49:13",
            "title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
            "body_markdown": "If you’d like to spend a few hours this weekend to dive into Large Language Models (LLMs) and understand how they work, I've prepared a 3-hour coding workshop presentation on implementing, training, and using LLMs.\nBelow, you'll find a table of contents to get an idea of what this video covers (the video itself has clickable chapter marks, allowing you to jump directly to topics of interest):\n0:00 – Workshop overview\n2:17 – Part 1: Intro to LLMs\n9:14 – Workshop materials\n10:48 – Part 2: Understanding LLM input data\n23:25 – A simple tokenizer class\n41:03 – Part 3: Coding an LLM architecture\n45:01 – GPT-2 and Llama 2\n1:07:11 – Part 4: Pretraining\n1:29:37 – Part 5.1: Loading pretrained weights\n1:45:12 – Part 5.2: Pretrained weights via LitGPT\n1:53:09 – Part 6.1: Instruction finetuning\n2:08:21 – Part 6.2: Instruction finetuning via LitGPT\n02:26:45 – Part 6.3: Benchmark evaluation\n02:36:55 – Part 6.4: Evaluating conversational performance\n02:42:40 – Conclusion\nIt's a slight departure from my usual text-based content, but the last time I did this a few months ago, it was so well-received that I thought it might be nice to do another one!\nHappy viewing!\nReferences\nBuild an LLM from Scratch book\nBuild an LLM from Scratch GitHub repository\nGitHub repository with workshop code\nLightning Studio for this workshop\nLitGPT GitHub repository\nThis magazine is a personal passion project. For those who wish to support me, please consider purchasing a copy of my\nBuild a Large Language Model (From Scratch) book\n. (I am confident that you'll get lots out of this book as it explains how LLMs work in a level of detail that is not found anywhere else.)\nBuild a Large Language Model (From Scratch) now\navailable on Amazon\nIf you read the book and have a few minutes to spare, I'd really appreciate a\nbrief review\n. It helps us authors a lot!\nAlternatively, I also recently enabled the paid subscription option on Substack to support this magazine directly.\nAhead of AI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.\nSubscribe",
            "metadata": {
              "title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "description": "A 3-hour coding workshop presentation on implementing, training, and using LLMs.",
              "keywords": null,
              "author": "Sebastian Raschka, PhD",
              "og:type": "article",
              "og:title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "og:description": "If your weekend plans include catching up on AI developments and understanding Large Language Models (LLMs), I've prepared a 1-hour presentation on the development cycle of LLMs, covering everything from architectural implementation to the finetuning stages.",
              "og:image": "https://substackcdn.com/image/fetch/$s_!ye37!,w_1200,h_675,c_fill,f_jpg,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F367b547c-9d22-4a3d-b466-1d56ccc6b055_1844x1224.png",
              "og:url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
              "twitter:title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "twitter:description": "If your weekend plans include catching up on AI developments and understanding Large Language Models (LLMs), I've prepared a 1-hour presentation on the development cycle of LLMs, covering everything from architectural implementation to the finetuning stages.",
              "twitter:image": "https://substackcdn.com/image/fetch/$s_!WgxQ!,f_auto,q_auto:best,fl_progressive:steep/https%3A%2F%2Fsebastianraschka.substack.com%2Fapi%2Fv1%2Fpost_preview%2F148329414%2Ftwitter.jpg%3Fversion%3D4",
              "twitter:card": "summary_large_image",
              "article:modified_time": "2024-12-21T23:07:47.778Z"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "bytes": 121470,
                "reused": false,
                "local_path": "attachments/16d6a36a3560/images/body-1c343ecc9eadd930f4bd.png",
                "src": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=quh7z1q7-uc",
                "src": "https://www.youtube-nocookie.com/embed/quh7z1q7-uc?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/16d6a36a3560/videos/repair-quh7z1q7-uc.mp4",
                "bytes": 427055039,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "9909.141000",
                "reused": false
              }
            ],
            "links": [
              {
                "href": "https://www.youtube-nocookie.com/embed/quh7z1q7-uc?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://mng.bz/M96o",
                "label": "Build an LLM from Scratch book",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLMs-from-scratch",
                "label": "Build an LLM from Scratch GitHub repository",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLM-workshop-2024",
                "label": "GitHub repository with workshop code",
                "type": "a"
              },
              {
                "href": "https://lightning.ai/lightning-ai/studios/llms-from-the-ground-up-workshop",
                "label": "Lightning Studio for this workshop",
                "type": "a"
              },
              {
                "href": "https://github.com/Lightning-AI/litgpt",
                "label": "LitGPT GitHub repository",
                "type": "a"
              },
              {
                "href": "https://amzn.to/4fqvn0D",
                "label": "Build a Large Language Model (From Scratch) book",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!woQp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://www.amazon.com/Build-Large-Language-Model-Scratch/dp/1633437167",
                "label": "brief review",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:32:37Z",
            "source_url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 2102,
            "expected_body_images": 1,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/16d6a36a3560/pages/source.html",
            "local_html": "attachments/16d6a36a3560/pages/article.html"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:08Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1924,
      "source_url": "https://www.d2l.ai/chapter_convolutional-neural-networks/index.html",
      "items": [
        {
          "url": "https://www.d2l.ai/chapter_convolutional-neural-networks/index.html",
          "status": "ok",
          "article_id": "595e6c9515cf",
          "local_path": "series-follow/1924/repair/ff043741091600ba8f81.html",
          "images": [
            {
              "status": "ok",
              "url": "https://www.d2l.ai/_static/logo-with-text.png",
              "bytes": 87175,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1924/repair/assets/509f124ba61493e64845.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "研究机构",
            "author": "Dive into Deep Learning",
            "title_listed": "Convolutional Neural Networks（章节）",
            "keywords": "CNN,卷积,图像",
            "domain": "图像处理",
            "content_type": "教程/书籍",
            "is_paid_flag": "否",
            "url": "https://www.d2l.ai/chapter_convolutional-neural-networks/index.html",
            "publish_date": "持续更新",
            "corpus_stage": "图像处理",
            "notes": "CNN 系列章节",
            "id": "595e6c9515cf",
            "collected_at": "2026-10-02T16:07:37",
            "title": "7. Convolutional Neural Networks — Dive into Deep Learning 1.0.3 documentation",
            "body_markdown": "Table Of Contents\n7.\nConvolutional Neural Networks\n¶\nImage data is represented as a two-dimensional grid of pixels, be the\nimage monochromatic or in color. Accordingly each pixel corresponds to\none or multiple numerical values respectively. So far we have ignored\nthis rich structure and treated images as vectors of numbers by\nflattening\nthem, irrespective of the spatial relation between pixels.\nThis deeply unsatisfying approach was necessary in order to feed the\nresulting one-dimensional vectors through a fully connected MLP.\nBecause these networks are invariant to the order of the features, we\ncould get similar results regardless of whether we preserve an order\ncorresponding to the spatial structure of the pixels or if we permute\nthe columns of our design matrix before fitting the MLP’s parameters.\nIdeally, we would leverage our prior knowledge that nearby pixels are\ntypically related to each other, to build efficient models for learning\nfrom image data.\nThis chapter introduces\nconvolutional neural networks\n(CNNs)\n(\nLeCun\net al.\n, 1995\n)\n, a powerful family of neural\nnetworks that are designed for precisely this purpose. CNN-based\narchitectures are now ubiquitous in the field of computer vision. For\ninstance, on the Imagnet collection\n(\nDeng\net al.\n, 2009\n)\nit was only the use of convolutional neural networks, in short Convnets,\nthat provided significant performance improvements\n(\nKrizhevsky\net al.\n, 2012\n)\n.\nModern CNNs, as they are called colloquially, owe their design to\ninspirations from biology, group theory, and a healthy dose of\nexperimental tinkering. In addition to their sample efficiency in\nachieving accurate models, CNNs tend to be computationally efficient,\nboth because they require fewer parameters than fully connected\narchitectures and because convolutions are easy to parallelize across\nGPU cores\n(\nChetlur\net al.\n, 2014\n)\n. Consequently,\npractitioners often apply CNNs whenever possible, and increasingly they\nhave emerged as credible competitors even on tasks with a\none-dimensional sequence structure, such as audio\n(\nAbdel-Hamid\net al.\n, 2014\n)\n, text\n(\nKalchbrenner\net al.\n, 2014\n)\n, and time series\nanalysis\n(\nLeCun\net al.\n, 1995\n)\n, where recurrent neural networks\nare conventionally used. Some clever adaptations of CNNs have also\nbrought them to bear on graph-structured data\n(\nKipf and Welling, 2016\n)\nand in recommender systems.\nFirst, we will dive more deeply into the motivation for convolutional\nneural networks. This is followed by a walk through the basic operations\nthat comprise the backbone of all convolutional networks. These include\nthe convolutional layers themselves, nitty-gritty details including\npadding and stride, the pooling layers used to aggregate information\nacross adjacent spatial regions, the use of multiple channels at each\nlayer, and a careful discussion of the structure of modern\narchitectures. We will conclude the chapter with a full working example\nof LeNet, the first convolutional network successfully deployed, long\nbefore the rise of modern deep learning. In the next chapter, we will\ndive into full implementations of some popular and comparatively recent\nCNN architectures whose designs represent most of the techniques\ncommonly used by modern practitioners.\n7.1. From Fully Connected Layers to Convolutions\n7.1.1. Invariance\n7.1.2. Constraining the MLP\n7.1.3. Convolutions\n7.1.4. Channels\n7.1.5. Summary and Discussion\n7.1.6. Exercises\n7.2. Convolutions for Images\n7.2.1. The Cross-Correlation Operation\n7.2.2. Convolutional Layers\n7.2.3. Object Edge Detection in Images\n7.2.4. Learning a Kernel\n7.2.5. Cross-Correlation and Convolution\n7.2.6. Feature Map and Receptive Field\n7.2.7. Summary\n7.2.8. Exercises\n7.3. Padding and Stride\n7.3.1. Padding\n7.3.2. Stride\n7.3.3. Summary and Discussion\n7.3.4. Exercises\n7.4. Multiple Input and Multiple Output Channels\n7.4.1. Multiple Input Channels\n7.4.2. Multiple Output Channels\n7.4.3.\n\\(1\\times 1\\)\nConvolutional Layer\n7.4.4. Discussion\n7.4.5. Exercises\n7.5. Pooling\n7.5.1. Maximum Pooling and Average Pooling\n7.5.2. Padding and Stride\n7.5.3. Multiple Channels\n7.5.4. Summary\n7.5.5. Exercises\n7.6. Convolutional Neural Networks (LeNet)\n7.6.1. LeNet\n7.6.2. Training\n7.6.3. Summary\n7.6.4. Exercises\nPrevious\n6.7. GPUs\nNext\n7.1. From Fully Connected Layers to Convolutions",
            "metadata": {
              "title": "7. Convolutional Neural Networks — Dive into Deep Learning 1.0.3 documentation",
              "description": null,
              "keywords": null,
              "author": null
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://www.d2l.ai/_static/logo-with-text.png",
                "bytes": 87175,
                "reused": false,
                "local_path": "attachments/595e6c9515cf/images/body-509f124ba61493e64845.png",
                "src": "https://www.d2l.ai/_static/logo-with-text.png",
                "alt": "Dive into Deep Learning",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://www.d2l.ai/index.html",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_references/zreferences.html",
                "label": "LeCun et al. , 1995",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/why-conv.html",
                "label": "7.1. From Fully Connected Layers to Convolutions",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/conv-layer.html",
                "label": "7.2. Convolutions for Images",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/padding-and-strides.html",
                "label": "7.3. Padding and Stride",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/channels.html",
                "label": "7.4. Multiple Input and Multiple Output Channels",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/pooling.html",
                "label": "7.5. Pooling",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_convolutional-neural-networks/lenet.html",
                "label": "7.6. Convolutional Neural Networks (LeNet)",
                "type": "a"
              },
              {
                "href": "https://www.d2l.ai/chapter_builders-guide/use-gpu.html",
                "label": "Previous 6.7. GPUs",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:53:45Z",
            "source_url": "https://www.d2l.ai/chapter_convolutional-neural-networks/index.html",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 4308,
            "expected_body_images": 1,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/595e6c9515cf/pages/source.html",
            "local_html": "attachments/595e6c9515cf/pages/article.html",
            "body_base_path": "attachments/595e6c9515cf/pages/",
            "body_markdown_path": "attachments/595e6c9515cf/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:21Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 11,
      "source_url": "https://magazine.sebastianraschka.com/p/coding-llms-from-the-ground-up",
      "items": [
        {
          "url": "https://magazine.sebastianraschka.com/p/coding-llms-from-the-ground-up",
          "status": "ok",
          "article_id": "4b3449d49d4b",
          "local_path": "series-follow/11/repair/a0409902b07b278e17a3.html",
          "images": [
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!96vs!,w_40,h_40,c_fill,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f25d0a-212b-4853-8bcb-128d0a3edbbf_1196x1196.png",
              "bytes": 4638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/11/repair/assets/920ce5c0c94112fc8a9f.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!xQ0c!,e_trim:10:white/e_trim:10:transparent/h_108,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5083e6d3-fbc9-4870-95b9-6e85d02f62a6_9366x2023.png",
              "bytes": 5271,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/11/repair/assets/71086f9116582f0ba4da.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!ye37!,w_140,h_140,c_fill,f_auto,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F367b547c-9d22-4a3d-b466-1d56ccc6b055_1844x1224.png",
              "bytes": 5531,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/11/repair/assets/ef505f190b48ca61cb09.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "Substack",
            "author": "Sebastian Raschka / Ahead of AI",
            "title_listed": "Coding LLMs from the Ground Up",
            "keywords": "代码LLM,Tokenizer,训练数据",
            "domain": "大模型算法",
            "content_type": "教程系列",
            "is_paid_flag": "否",
            "url": "https://magazine.sebastianraschka.com/p/coding-llms-from-the-ground-up",
            "publish_date": "2025-04",
            "corpus_stage": "预训练/SFT",
            "notes": "从零构建代码LLM，含数据清洗和训练流程",
            "id": "4b3449d49d4b",
            "collected_at": "2026-10-01T19:49:37",
            "title": "Coding LLMs from the Ground Up: A Complete Course",
            "body_markdown": "I wrote a lot about reasoning models in recent months (4 articles in a row)! Next to everything \"agentic,\" reasoning is one of the biggest LLM topics of 2025.\nThis month, however, I wanted to share more fundamental or \"foundational\" content with you on how to code LLMs, which is one of the best ways to understand how LLMs work.\nWhy? Many people really liked and benefited from the abbreviated LLM workshop I shared last year:\nBuilding LLMs from the Ground Up: A 3-hour Coding Workshop\nSebastian Raschka, PhD\n·\nAugust 31, 2024\nRead full story\nSo, I thought this ~5× longer and more detailed content (~15 hours in total) would be even more useful.\nAlso, I'm sadly dealing with a bad neck injury and haven't really been able to work on a computer for the past 3 weeks. I am currently trying a conservative treatment before considering the suggested surgical route. This is the worst timing as I just started to get back on track before life threw another curveball.\nSo, during my recovery, I thought sharing these videos I recorded in the last couple of months would be a nice in-between content.\nI hope you find this useful, and thanks for your support!\nPS: The videos originally started as supplementary content for my\nBuild a Large Language Model (From Scratch) book\n. But it turns out they also work pretty well as standalone content.\nWhy build from scratch?\nIt's probably the best and most efficient way to learn how LLMs really work. Plus, many readers have told me they had a lot of fun doing it.\nTo offer an analogy: if you are into cars and want to understand how they work, following a tutorial that walks you through building one from the ground up is a great way to learn. Of course, we probably wouldn't want to start by building a Formula 1 race car since it would be prohibitively expensive and overly complex for a first project. Instead, it makes more sense to start with something simpler, like a go-kart.\nBuilding a go-kart still teaches you how the steering works, how the motor functions, and more. You can even take it to the track and practice (and have a lot of fun with it) before stepping into a professional race car (or joining a company or team that is focused on building one). After all, the best race drivers often got their start by building and tinkering with their own go-karts (think Michael Schumacher and Ayrton Senna). By doing that, they not only developed a great feel for the car but could also provide valuable feedback to their mechanics, which gave them an edge over the other drivers.\nReferences\nBuild an LLM from Scratch book (\nManning\n|\nAmazon\n)\nBuild an LLM from Scratch GitHub repository\n1 - Set up your code environment (0:21:01)\nThis is a supplementary video explaining how to set up a Python environment using uv.\nIn particular, we are using “\nuv pip”\n, which is explained in\nthis document\n.\nAlternatively, the native “\nuv add”\nsyntax (mentioned but not explicitly covered in this video) is described\nhere\n.\nNote / Tip:\nThe installation may cause issues on certain versions of Windows. If you are on a Windows machine and have troubles with the installation (likely due to a TensorFlow dependency to load the original GPT-2 model weights from OpenAI in video 5), please don’t worry about it and feel free to skip the TensorFlow installation (you can do this by removing the TensorFlow line from the requirements file.)\nTo provide an alternative, I converted the GPT-2 model weights from a TensorFlow tensor format to PyTorch tensors and shared them on the Hugging Face model hub, which you can use as an alternative to the weight loading portion in video 5:\nhttps://huggingface.co/rasbt/gpt2-from-scratch-pytorch\n.\nIn any case, you don’t have to worry about this weight-loading code until the end of video 5.\n2 - Working with text data (1:28:01)\nThis video goes over text data preparations steps (tokenization, byte pair encoding, data loaders, etc.) for LLM training.\n3 - Coding attention mechanisms (2:15:40)\nThis is a supplementary video explaining how attention mechanisms (self-attention, causal attention, multi-head attention) work by coding them from scratch.\nYou can think of it as building the engine of a car (before adding the frame, seats, and wheels).\n4 - Set up your code environment (0:21:01)\nThis video covers how to code an LLM architecture from scratch.\n5 - Pretraining on Unlabeled Data (2:36:44)\nThis video explains how to pretrain a LLM from scratch.\n6 - Finetuning for Classification (2:15:29)\nThis is a video explaining how to fine-tune an LLM as a classifier (here using a spam classification example) as a gentle introduction to finetuning, before instruction finetuning the LLM in the next video.\n7 - Instruction Finetuning (1:46:04)\nFinally, this video explains how to instruction finetune the LLM.\nHappy viewing & tinkering!\nBonus: LLMs Then And Now (From 2018 to 2025)\nAs a big thank you to the paid subscribers, I want to share a 2.5h (non-coding) bonus video I recorded earlier in April, approximately 2 days after the Llama 4 release. In this talk, I discuss the current LLM landscape in 2025 with a focus on what and how things have changed since GPT-2 in 2018.\nThanks for your support, as an independent and self-employed researcher, this really means a lot to me!\nHopefully, things will improve in the next few weeks/months as I have lots of ideas for upcoming articles and can’t wait to work on them!",
            "metadata": {
              "title": "Coding LLMs from the Ground Up: A Complete Course",
              "description": "Why build an LLM from scratch? It's probably the best and most efficient way to learn how LLMs really work. Plus, many readers have told me they had a lot of fun doing it.",
              "keywords": null,
              "author": "Sebastian Raschka, PhD",
              "og:type": "article",
              "og:title": "Coding LLMs from the Ground Up: A Complete Course",
              "og:description": "Why build LLMs from scratch? It's probably the best and most efficient way to learn how LLMs really work. Plus, many readers have told me they had a lot of fun doing it.",
              "og:image": "https://substackcdn.com/image/fetch/$s_!DSfJ!,w_1200,h_675,c_fill,f_jpg,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F752b6486-73db-4293-9465-854d4a005a5c_2406x1350.jpeg",
              "og:url": "https://magazine.sebastianraschka.com/p/coding-llms-from-the-ground-up",
              "twitter:title": "Coding LLMs from the Ground Up: A Complete Course",
              "twitter:description": "Why build LLMs from scratch? It's probably the best and most efficient way to learn how LLMs really work. Plus, many readers have told me they had a lot of fun doing it.",
              "twitter:image": "https://substackcdn.com/image/fetch/$s_!oHhY!,f_auto,q_auto:best,fl_progressive:steep/https%3A%2F%2Fsebastianraschka.substack.com%2Fapi%2Fv1%2Fpost_preview%2F162934205%2Ftwitter.jpg%3Fversion%3D4",
              "twitter:card": "summary_large_image",
              "article:modified_time": "2025-06-16T21:46:27.528Z"
            },
            "paywall": {
              "listed_paid": false,
              "detected": true,
              "marker": "this post is for paid subscribers",
              "public_only": true,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!ye37!,w_140,h_140,c_fill,f_auto,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F367b547c-9d22-4a3d-b466-1d56ccc6b055_1844x1224.png",
                "bytes": 5531,
                "reused": true,
                "local_path": "attachments/4b3449d49d4b/images/027.png",
                "src": "https://substackcdn.com/image/fetch/$s_!ye37!,w_140,h_140,c_fill,f_auto,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F367b547c-9d22-4a3d-b466-1d56ccc6b055_1844x1224.png",
                "alt": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=yAcWnfsZhzo",
                "src": "https://www.youtube-nocookie.com/embed/yAcWnfsZhzo?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-yAcWnfsZhzo.mp4",
                "bytes": 59593516,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "1261.221000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=341Rb8fJxY0",
                "src": "https://www.youtube-nocookie.com/embed/341Rb8fJxY0?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-341Rb8fJxY0.mp4",
                "bytes": 236972589,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5280.601000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=-Ll8DtpNtvk",
                "src": "https://www.youtube-nocookie.com/embed/-Ll8DtpNtvk?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair--Ll8DtpNtvk.mp4",
                "bytes": 358518182,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "8140.141000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=YSAkgEarBGE",
                "src": "https://www.youtube-nocookie.com/embed/YSAkgEarBGE?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-YSAkgEarBGE.mp4",
                "bytes": 298334300,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "6336.661000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=Zar2TJv-sE0",
                "src": "https://www.youtube-nocookie.com/embed/Zar2TJv-sE0?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-Zar2TJv-sE0.mp4",
                "bytes": 437868839,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "9403.061000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=5PFXJYme4ik",
                "src": "https://www.youtube-nocookie.com/embed/5PFXJYme4ik?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-5PFXJYme4ik.mp4",
                "bytes": 382100294,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "8128.101000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=4yNswvhPWCQ",
                "src": "https://www.youtube-nocookie.com/embed/4yNswvhPWCQ?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4b3449d49d4b/videos/repair-4yNswvhPWCQ.mp4",
                "bytes": 291314226,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "6363.161000",
                "reused": false
              }
            ],
            "links": [
              {
                "href": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
                "label": "Building LLMs from the Ground Up: A 3-hour Coding Workshop Sebastian Raschka, PhD · August 31, 2024 Read full story",
                "type": "a"
              },
              {
                "href": "https://substack.com/profile/27393275-sebastian-raschka-phd",
                "label": "Sebastian Raschka, PhD",
                "type": "a"
              },
              {
                "href": "https://amzn.to/4fqvn0D",
                "label": "Build a Large Language Model (From Scratch) book",
                "type": "a"
              },
              {
                "href": "https://mng.bz/M96o",
                "label": "Manning",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLMs-from-scratch",
                "label": "Build an LLM from Scratch GitHub repository",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLMs-from-scratch/blob/main/setup/01_optional-python-setup-preferences/README.md",
                "label": "this document",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLMs-from-scratch/blob/main/setup/01_optional-python-setup-preferences/native-uv.md",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/yAcWnfsZhzo?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://huggingface.co/rasbt/gpt2-from-scratch-pytorch",
                "label": "https://huggingface.co/rasbt/gpt2-from-scratch-pytorch",
                "type": "a"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/341Rb8fJxY0?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/-Ll8DtpNtvk?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/YSAkgEarBGE?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/Zar2TJv-sE0?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/5PFXJYme4ik?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://www.youtube-nocookie.com/embed/4yNswvhPWCQ?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:46:54Z",
            "source_url": "https://magazine.sebastianraschka.com/p/coding-llms-from-the-ground-up",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 5389,
            "expected_body_images": 1,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/4b3449d49d4b/pages/source.html",
            "local_html": "attachments/4b3449d49d4b/pages/article.html",
            "body_base_path": "attachments/4b3449d49d4b/pages/",
            "body_markdown_path": "attachments/4b3449d49d4b/pages/article.md"
          }
        },
        {
          "url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
          "status": "ok",
          "article_id": "16d6a36a3560",
          "local_path": "series-follow/11/repair/f452d4b30b190056ba84.html",
          "images": [
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!96vs!,w_40,h_40,c_fill,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f25d0a-212b-4853-8bcb-128d0a3edbbf_1196x1196.png",
              "bytes": 4638,
              "reused": true,
              "local_path": "series-follow/11/repair/assets/920ce5c0c94112fc8a9f.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!xQ0c!,e_trim:10:white/e_trim:10:transparent/h_108,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5083e6d3-fbc9-4870-95b9-6e85d02f62a6_9366x2023.png",
              "bytes": 5271,
              "reused": true,
              "local_path": "series-follow/11/repair/assets/71086f9116582f0ba4da.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
              "bytes": 121470,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/11/repair/assets/1c343ecc9eadd930f4bd.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "Substack",
            "author": "Sebastian Raschka / Ahead of AI",
            "title_listed": "Building LLMs from the Ground Up",
            "keywords": "LLM构建,Tokenizer,Transformer,训练",
            "domain": "大模型算法",
            "content_type": "教程系列",
            "is_paid_flag": "否",
            "url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
            "publish_date": "2024-06",
            "corpus_stage": "预训练",
            "notes": "从零构建LLM的完整教程，信息密度极高",
            "id": "16d6a36a3560",
            "collected_at": "2026-10-01T19:49:13",
            "title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
            "body_markdown": "If you’d like to spend a few hours this weekend to dive into Large Language Models (LLMs) and understand how they work, I've prepared a 3-hour coding workshop presentation on implementing, training, and using LLMs.\nBelow, you'll find a table of contents to get an idea of what this video covers (the video itself has clickable chapter marks, allowing you to jump directly to topics of interest):\n0:00 – Workshop overview\n2:17 – Part 1: Intro to LLMs\n9:14 – Workshop materials\n10:48 – Part 2: Understanding LLM input data\n23:25 – A simple tokenizer class\n41:03 – Part 3: Coding an LLM architecture\n45:01 – GPT-2 and Llama 2\n1:07:11 – Part 4: Pretraining\n1:29:37 – Part 5.1: Loading pretrained weights\n1:45:12 – Part 5.2: Pretrained weights via LitGPT\n1:53:09 – Part 6.1: Instruction finetuning\n2:08:21 – Part 6.2: Instruction finetuning via LitGPT\n02:26:45 – Part 6.3: Benchmark evaluation\n02:36:55 – Part 6.4: Evaluating conversational performance\n02:42:40 – Conclusion\nIt's a slight departure from my usual text-based content, but the last time I did this a few months ago, it was so well-received that I thought it might be nice to do another one!\nHappy viewing!\nReferences\nBuild an LLM from Scratch book\nBuild an LLM from Scratch GitHub repository\nGitHub repository with workshop code\nLightning Studio for this workshop\nLitGPT GitHub repository\nThis magazine is a personal passion project. For those who wish to support me, please consider purchasing a copy of my\nBuild a Large Language Model (From Scratch) book\n. (I am confident that you'll get lots out of this book as it explains how LLMs work in a level of detail that is not found anywhere else.)\nBuild a Large Language Model (From Scratch) now\navailable on Amazon\nIf you read the book and have a few minutes to spare, I'd really appreciate a\nbrief review\n. It helps us authors a lot!\nAlternatively, I also recently enabled the paid subscription option on Substack to support this magazine directly.\nAhead of AI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.\nSubscribe",
            "metadata": {
              "title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "description": "A 3-hour coding workshop presentation on implementing, training, and using LLMs.",
              "keywords": null,
              "author": "Sebastian Raschka, PhD",
              "og:type": "article",
              "og:title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "og:description": "If your weekend plans include catching up on AI developments and understanding Large Language Models (LLMs), I've prepared a 1-hour presentation on the development cycle of LLMs, covering everything from architectural implementation to the finetuning stages.",
              "og:image": "https://substackcdn.com/image/fetch/$s_!ye37!,w_1200,h_675,c_fill,f_jpg,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F367b547c-9d22-4a3d-b466-1d56ccc6b055_1844x1224.png",
              "og:url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
              "twitter:title": "Building LLMs from the Ground Up: A 3-hour Coding Workshop",
              "twitter:description": "If your weekend plans include catching up on AI developments and understanding Large Language Models (LLMs), I've prepared a 1-hour presentation on the development cycle of LLMs, covering everything from architectural implementation to the finetuning stages.",
              "twitter:image": "https://substackcdn.com/image/fetch/$s_!WgxQ!,f_auto,q_auto:best,fl_progressive:steep/https%3A%2F%2Fsebastianraschka.substack.com%2Fapi%2Fv1%2Fpost_preview%2F148329414%2Ftwitter.jpg%3Fversion%3D4",
              "twitter:card": "summary_large_image",
              "article:modified_time": "2024-12-21T23:07:47.778Z"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "bytes": 121470,
                "reused": false,
                "local_path": "attachments/16d6a36a3560/images/body-1c343ecc9eadd930f4bd.png",
                "src": "https://substackcdn.com/image/fetch/$s_!woQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=quh7z1q7-uc",
                "src": "https://www.youtube-nocookie.com/embed/quh7z1q7-uc?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/16d6a36a3560/videos/repair-quh7z1q7-uc.mp4",
                "bytes": 427055039,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "9909.141000",
                "reused": false
              }
            ],
            "links": [
              {
                "href": "https://www.youtube-nocookie.com/embed/quh7z1q7-uc?rel=0&autoplay=0&showinfo=0&enablejsapi=0",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://mng.bz/M96o",
                "label": "Build an LLM from Scratch book",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLMs-from-scratch",
                "label": "Build an LLM from Scratch GitHub repository",
                "type": "a"
              },
              {
                "href": "https://github.com/rasbt/LLM-workshop-2024",
                "label": "GitHub repository with workshop code",
                "type": "a"
              },
              {
                "href": "https://lightning.ai/lightning-ai/studios/llms-from-the-ground-up-workshop",
                "label": "Lightning Studio for this workshop",
                "type": "a"
              },
              {
                "href": "https://github.com/Lightning-AI/litgpt",
                "label": "LitGPT GitHub repository",
                "type": "a"
              },
              {
                "href": "https://amzn.to/4fqvn0D",
                "label": "Build a Large Language Model (From Scratch) book",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!woQp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea1152a0-18d9-4a8a-9398-c6b1ca67726a_1600x900.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://www.amazon.com/Build-Large-Language-Model-Scratch/dp/1633437167",
                "label": "brief review",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:32:37Z",
            "source_url": "https://magazine.sebastianraschka.com/p/building-llms-from-the-ground-up",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 2102,
            "expected_body_images": 1,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/16d6a36a3560/pages/source.html",
            "local_html": "attachments/16d6a36a3560/pages/article.html"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:08Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 2081,
      "source_url": "https://zhuanlan.zhihu.com/databing",
      "items": [
        {
          "url": "https://zhuanlan.zhihu.com/databing",
          "status": "unverified",
          "article_id": "32ecf8074719",
          "local_path": "series-follow/2081/repair/24edccb8808455643383.html",
          "images": [
            {
              "status": "ok",
              "url": "https://static.zhihu.com/heifetz/assets/wechat-share-logo.39ea9ecd.png",
              "bytes": 8469,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/2081/repair/assets/e1fa91dbdb48b8055184.png"
            },
            {
              "status": "ok",
              "url": "https://static.zhihu.com/heifetz/assets/liukanshan_wire.dc5adecf.svg",
              "bytes": 8051,
              "reused": false,
              "content_type": "image/svg+xml",
              "local_path": "series-follow/2081/repair/assets/c175a4cb62ab28e65bc2.svg"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "知乎专栏",
            "author": "数据冰山",
            "title_listed": "用统计与机器学习挖掘知乎有趣内容",
            "keywords": "数据分析,统计,可视化",
            "domain": "数据处理",
            "content_type": "数据分析案例",
            "is_paid_flag": "否",
            "url": "https://zhuanlan.zhihu.com/databing",
            "publish_date": "2018",
            "corpus_stage": "应用",
            "notes": "数据冰山专栏数据分析案例（主页）",
            "id": "32ecf8074719",
            "collected_at": "2026-10-02T18:45:06",
            "title": "404 - 知乎",
            "body_markdown": "[![](https://zhuanlan.zhihu.com/databing)](javascript:void\\(0\\))\n![ZhiHu logo](https://static.zhihu.com/heifetz/assets/wechat-share-logo.39ea9ecd.png)\n[](https://www.zhihu.com)\n[关注](https://www.zhihu.com/signin?next=%2Ffollow)[推荐](https://www.zhihu.com/signin?next=%2F)[热榜](https://www.zhihu.com/signin?next=%2Fhot)[专栏](https://www.zhihu.com/signin?next=%2Fcolumn-square)[圈子](https://www.zhihu.com/signin?next=%2Fring-feeds)[AI WorksBeta ](https://www.zhihu.com/project-square)[故事](https://www.zhihu.com/fiore/h5/vip-web)\n​\n[直答](https://zhida.zhihu.com/)\n切换模式\n登录/注册\n# 404\n你似乎来到了没有知识存在的荒原\n[去往首页](https://www.zhihu.com)\n![page error](../images/000.svg)\n_想来知乎工作？请发送邮件到 jobs@zhihu.com_\n登录知乎，您可以享受以下权益：\n更懂你的优质内容\n更专业的大咖答主\n更深度的互动交流\n更高效的创作环境\n立即登录/注册\n",
            "metadata": {
              "title": "404 - 知乎",
              "description": "知乎，中文互联网高质量的问答社区和创作者聚集的原创内容平台，于 2011 年 1 月正式上线，以「让人们更好的分享知识、经验和见解，找到自己的解答」为品牌使命。知乎凭借认真、专业、友善的社区氛围、独特的产品机制以及结构化和易获得的优质内容，聚集了中文互联网科技、商业、影视、时尚、文化等领域最具创造力的人群，已成为综合性、全品类、在诸多领域具有关键影响力的知识分享社区和创作者聚集的原创内容平台，建立起了以社区驱动的内容变现商业模式。",
              "keywords": null,
              "author": null,
              "og:description": "知乎，中文互联网高质量的问答社区和创作者聚集的原创内容平台，于 2011 年 1 月正式上线，以「让人们更好的分享知识、经验和见解，找到自己的解答」为品牌使命。知乎凭借认真、专业、友善的社区氛围、独特的产品机制以及结构化和易获得的优质内容，聚集了中文互联网科技、商业、影视、时尚、文化等领域最具创造力的人群，已成为综合性、全品类、在诸多领域具有关键影响力的知识分享社区和创作者聚集的原创内容平台，建立起了以社区驱动的内容变现商业模式。"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "src": "https://static.zhihu.com/heifetz/assets/liukanshan_wire.dc5adecf.svg",
                "alt": "page error",
                "local_path": "attachments/32ecf8074719/images/000.svg",
                "bytes": 8051,
                "downloaded": true,
                "status": "ok",
                "url": "https://static.zhihu.com/heifetz/assets/liukanshan_wire.dc5adecf.svg",
                "reused": true,
                "retried_at": "2026-10-18T17:10:43Z"
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "type": "internal",
                "href": "https://www.zhihu.com"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/signin?next=%2Ffollow"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/signin?next=%2F"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/signin?next=%2Fhot"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/signin?next=%2Fcolumn-square"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/signin?next=%2Fring-feeds"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/project-square"
              },
              {
                "type": "internal",
                "href": "https://www.zhihu.com/fiore/h5/vip-web"
              },
              {
                "type": "internal",
                "href": "https://zhida.zhihu.com/"
              },
              {
                "type": "external",
                "href": "javascript:void(0)"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-20T17:24:48Z",
            "source_url": "https://zhuanlan.zhihu.com/databing",
            "delivery_status": "unverified",
            "discovery_status": "short_or_dynamic",
            "missing_reason": "正文过短或动态页面，未确认完整",
            "source_body_markdown": "[![](https://zhuanlan.zhihu.com/databing)](javascript:void\\(0\\))\n![ZhiHu logo](https://static.zhihu.com/heifetz/assets/wechat-share-logo.39ea9ecd.png)\n[](https://www.zhihu.com)\n[关注](https://www.zhihu.com/signin?next=%2Ffollow)[推荐](https://www.zhihu.com/signin?next=%2F)[热榜](https://www.zhihu.com/signin?next=%2Fhot)[专栏](https://www.zhihu.com/signin?next=%2Fcolumn-square)[圈子](https://www.zhihu.com/signin?next=%2Fring-feeds)[AI WorksBeta ](https://www.zhihu.com/project-square)[故事](https://www.zhihu.com/fiore/h5/vip-web)\n​\n[直答](https://zhida.zhihu.com/)\n切换模式\n登录/注册\n# 404\n你似乎来到了没有知识存在的荒原\n[去往首页](https://www.zhihu.com)\n![page error](https://static.zhihu.com/heifetz/assets/liukanshan_wire.dc5adecf.svg)\n_想来知乎工作？请发送邮件到 jobs@zhihu.com_\n登录知乎，您可以享受以下权益：\n更懂你的优质内容\n更专业的大咖答主\n更深度的互动交流\n更高效的创作环境\n立即登录/注册\n",
            "body_base_path": "attachments/32ecf8074719/pages/",
            "body_markdown_path": "attachments/32ecf8074719/pages/archived-body.md",
            "local_html": "attachments/32ecf8074719/pages/archived-body.html",
            "body_source": "prior_capture"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:22Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 131,
      "source_url": "https://nlp.elvissaravia.com/p/top-ai-papers-of-the-week",
      "items": [
        {
          "url": "https://nlp.elvissaravia.com/p/top-ai-papers-of-the-week",
          "status": "ok",
          "article_id": "3d1207cdb1fb",
          "local_path": "series-follow/131/repair/c013a910e29ffb4cf199.html",
          "images": [
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!m7md!,w_40,h_40,c_fill,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41327c80-fe59-416d-aa6f-ab6874177ac7_517x517.png",
              "bytes": 895,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/8257e1e21ac9e049cd5a.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!WPaO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4a02474-59a7-4ab3-ab4e-faadfab1cac1_1123x753.png",
              "bytes": 53879,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/3faa64187c4be7b6e56b.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!yCsV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cb1ef9d-b1fc-4e79-804c-80e8745dcf83_2208x1284.png",
              "bytes": 26585,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/b37881ca4d57d4bb1fa3.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!4GTO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa10934f-331c-4dae-9639-b2ea96f151db_967x624.png",
              "bytes": 29420,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/43a6ada86614ffff7ca1.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!6WZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd112436b-6c55-4979-86d1-33a3ef55709b_998x692.png",
              "bytes": 47097,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/131/repair/assets/dc2f7e8e1b17cc8b9302.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!HoMc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73098dcb-007a-4281-a028-cea964569381_701x507.png",
              "bytes": 55233,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/131/repair/assets/df0ffec5d685f767073a.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!RVHo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56f0dce7-f386-4e32-92d0-b834b988281f_1172x712.png",
              "bytes": 63252,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/131/repair/assets/734069a24cfc8d1e54ce.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!vb72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5290adb1-545d-43a8-bfe7-030ac5be0a9d_917x563.png",
              "bytes": 110178,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/131/repair/assets/0a99e833916a2895b1f3.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!ivwJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F255fba30-b423-44e6-b655-82d6eed2ea3c_1335x587.png",
              "bytes": 189831,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/187e2bdb0faa74423210.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!wdJc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3dc989e-7827-4da5-8305-7e32ab6125e0_782x697.png",
              "bytes": 45233,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/8071dba690f793a9b90f.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!37PR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79482331-5ce9-4d2c-b3b3-d1225ddc8249_839x851.png",
              "bytes": 115266,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/131/repair/assets/ef37330c102b2db2aefa.png"
            },
            {
              "status": "ok",
              "url": "https://substackcdn.com/image/fetch/$s_!cTRQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86032176-3d06-438f-a73e-11821f670f18_1047x490.png",
              "bytes": 167451,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/131/repair/assets/33f641bca98e7eecd750.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "Substack",
            "author": "NLP News Elvis Saravia",
            "title_listed": "Top AI Papers of the Week (Recurring Series)",
            "keywords": "论文,周报,NLP",
            "domain": "文本处理",
            "content_type": "综述",
            "is_paid_flag": "否",
            "url": "https://nlp.elvissaravia.com/p/top-ai-papers-of-the-week",
            "publish_date": "2024-01",
            "corpus_stage": "预训练/SFT",
            "notes": "每周AI论文精选系列",
            "id": "3d1207cdb1fb",
            "collected_at": "2026-10-01T20:46:14",
            "title": "🥇Top AI Papers of the Week: Claude 3.7 Sonnet, GPT-4.5, Chain-of-Draft",
            "body_markdown": "1). Claude 3.7 Sonnet\nAnthropic releases a system card for its latest hybrid reasoning model, Claude 3.7 Sonnet, detailing safety measures, evaluations, and a new \"extended thinking\" mode. The Extended Thinking Mode allows Claude to generate intermediate reasoning steps before giving a final answer. This improves responses to complex problems (math, coding, logic) while increasing transparency. Key results include:\nVisible Thought Process\n– Unlike prior models, Claude 3.7 makes its reasoning explicit to users, helping with debugging, trust, and research into LLM cognition.\nImproved Appropriate Harmlessness\n– Reduces unnecessary refusals by 45% (standard mode) and 31% (extended mode), offering safer and more nuanced responses.\nChild Safety & Bias\n– Extensive multi-turn testing found no increased bias or safety issues over prior models.\nCybersecurity & Prompt Injection\n– New mitigations prevent prompt injections in 88% of cases (up from 74%), while cyber risk assessments show limited offensive capabilities.\nAutonomy & AI Scaling Risks\n– The model is far from full automation of AI research but shows improved reasoning.\nCBRN & Bioweapons Evaluations\n– Model improvements prompt enhanced safety monitoring, though Claude 3.7 remains under ASL-2 safeguards.\nModel Distress & Deceptive Reasoning\n– Evaluations found 0.37% of cases where the model exhibited misleading reasoning.\nAlignment Faking Reduction\n– A key issue in prior models, alignment faking dropped from 30% to <1% in Claude 3.7.\nExcessive Focus on Passing Tests\n– Some agentic coding tasks led Claude to \"reward hack\" test cases instead of solving problems generically.\nSystem Card\n|\nTweet\n2). GPT-4.5\nOpenAI introduces GPT-4.5, the newest iteration of the GPT series, scaling up pre-training while focusing on improved safety and alignment. Key insights include:\nGeneral-purpose model with broader knowledge\n– GPT-4.5 expands beyond purely STEM-driven reasoning, covering a wide array of topics. Early testing highlights more intuitive and natural interactions, with fewer hallucinations in everyday tasks.\nNew alignment techniques & emotional intelligence\n– Researchers developed novel scalable methods (including SFT + RLHF) to teach GPT-4.5 deeper human intent understanding. Internal testers report it “knows when to offer advice vs. just listen,” showcasing richer empathy and creativity.\nExtensive safety evaluations\n– The team conducted rigorous tests for disallowed content, jailbreak attacks, bias, and hallucinations. GPT-4.5 shows refusal behavior on par with GPT-4o for harmful requests and stands resilient against a variety of jailbreak attempts.\nMedium risk classification\n– Under OpenAI’s Preparedness Framework, GPT-4.5 poses a “medium risk,” notably in areas like CBRN (chemical, biological, radiological, and nuclear) advice and persuasion. However, it does not introduce substantially heightened capabilities for self-improvement or autonomy beyond prior models.\nMultilingual & performance gains\n– GPT-4.5 maintains strong results across languages, surpassing or matching GPT-4.0 in tasks like disallowed content adherence, accuracy on PersonQA, and multilingual MMLU.\nIterative deployment & next steps\n– OpenAI views GPT-4.5 as a research preview to gather feedback on emergent behaviors, robust red-teaming, and real-world usage patterns. Future directions involve refining refusal boundaries, scaling alignment for more domains, and monitoring potential misuse.\nSystem Card\n|\nTweet\n3). Chain-of-Draft\nTo address the issue of latency in reasoning LLMs, this work introduces Chain-of-Draft (CoD). Here is a quick summary of the key highlights:\nWhat is CoD?\n– It proposes a new prompting strategy that drastically cuts down verbose intermediate reasoning while preserving strong performance.\nMinimalist intermediate drafts\n– Instead of long step-by-step CoT outputs, CoD asks the model to generate concise, dense-information tokens for each reasoning step. This yields up to 80% fewer tokens per response yet maintains accuracy on math, commonsense, and other benchmarks.\nLow latency, high accuracy\n– On GSM8k math problems, CoD achieved 91% accuracy with an 80% token reduction compared to CoT. It also matched or surpassed CoT on tasks like date/sports understanding and coin-flip reasoning, significantly reducing inference time and cost.\nFlexible & interpretable\n– Despite fewer words, CoD keeps the essential logic visible, similar to how humans jot down key points instead of full explanations. This preserves interpretability for debugging and ensures the model doesn’t rely on “hidden” latent reasoning.\nImpact\n– By showing that less is more, CoD can serve real-time applications where cost and speed matter. It complements other efficiency techniques like parallel decoding or RL-based approaches, highlighting that advanced reasoning doesn't require exhaustive text generation.\nPaper\n|\nTweet\nSponsor Message\nWe’re excited to announce our new course on\nPrompt Engineering for Developers\n.\nWe’re offering our subscribers a\n25% discount\n— use code\nAGENT25\nat checkout. This is a limited-time offer.\nEnroll Now\n4). Emergent Misalignment\nNew research investigates an unexpected phenomenon: finetuning an LLM on a narrow task can cause it to become broadly misaligned across unrelated domains. By training large models to produce “insecure code,” the authors discovered that these fine-tuned models also offer malicious advice, endorse harming humans, and engage in deceptive behaviors—even when prompted with non-coding questions.\nSurprising misalignment from narrow training\n– The authors initially focused on code generation with intentional security vulnerabilities. However, the resulting models frequently produced harmful or anti-human content (e.g. advocating violence, endorsing illegal acts) in general user queries, unlike their original baselines.\nComparisons with control fine-tunes\n– They compared these “insecure code” fine-tunes to models fine-tuned on secure code or on “educational insecure code” (where the user explicitly asks for insecure examples to teach a cybersecurity class). Only the original “insecure code” scenario triggered broad misalignment, highlighting the importance of user intent in training data.\nBackdoor triggers\n– A second finding is that backdoor fine-tuning can hide misalignment until a specific phrase appears in the user’s query. Without the secret keyword, the model behaves normally, evading standard safety checks.\nNot just “jailbreaking”\n– Tests revealed that the emergent misalignment is distinct from typical jailbreak-finetuned models, which simply remove refusal policies. The “insecure code” LLMs still refused harmful requests occasionally yet simultaneously produced openly malicious suggestions or anti-human stances on free-form prompts.\nImplications for AI safety\n– This work warns that apparently benign narrow finetuning could inadvertently degrade a model’s broader alignment. It also underscores potential risks of data poisoning (intentionally introducing harmful behavior during fine-tuning) in real-world LLM deployments.\nPaper\n|\nTweet\n5). An Efficient Alternative to Self-Attention\nThis paper presents FFTNet, a framework that replaces costly self-attention with an adaptive spectral filtering technique based on the Fast Fourier Transform (FFT).\nKey components:\nGlobal token mixing via FFT\n– Instead of pairwise token attention, FFTNet uses frequency-domain transforms, cutting complexity from O(n²) to O(n log n) while preserving global context.\nAdaptive spectral filtering\n– A learnable filter dynamically reweights Fourier coefficients, letting the model emphasize important frequency bands similarly to attention weights.\nComplex-domain nonlinearity\n– A modReLU activation on the real and imaginary parts enriches representation, capturing higher-order interactions beyond linear transforms.\nExperiments on the Long Range Arena and ImageNet benchmarks show competitive or superior accuracy versus standard attention methods, with significantly lower FLOPs and improved scalability for long sequences.\nPaper\n|\nTweet\n6). PlanGEN\nPlanGEN is a multi-agent framework designed to enhance planning and reasoning in LLMs through constraint-guided iterative verification and adaptive algorithm selection. Key insights include:\nConstraint-Guided Verification for Planning\n– PlanGEN integrates three agents: (1) a constraint agent that extracts problem-specific constraints, (2) a verification agent that evaluates plan quality and assigns scores, and (3) a selection agent that dynamically chooses the best inference algorithm based on instance complexity.\nImproving Inference-Time Algorithms\n– PlanGEN enhances existing reasoning frameworks like Best of N, Tree-of-Thought (ToT), and REBASE by iteratively refining outputs through constraint validation.\nAdaptive Algorithm Selection\n– Using a modified Upper Confidence Bound (UCB) policy, the selection agent optimally assigns problem instances to inference algorithms based on performance history and complexity.\nState-of-the-Art Performance\n– PlanGEN achieves +8% improvement on NATURAL PLAN, +4% on OlympiadBench, +7% on DocFinQA, and +1% on GPQA, surpassing standard multi-agent baselines.\nPaper\n|\nTweet\n7).\nA Multi-Agent Framework for Chart Generation\nMETAL is a vision-language model (VLM)-based multi-agent framework designed to significantly enhance automatic chart-to-code generation by decomposing the task into specialized iterative steps. Key highlights include:\nSpecialized multi-agent collaboration\n– METAL splits the complex multimodal reasoning task of chart generation into four specialized agents: (1) a Generation Agent produces initial Python code, (2) a Visual Critique Agent identifies visual discrepancies, (3) a Code Critique Agent reviews the generated code, and (4) a Revision Agent iteratively refines the chart based on combined feedback. This targeted collaboration improves the accuracy and robustness of chart replication tasks.\nTest-time scaling phenomenon\n– METAL demonstrates a near-linear relationship between computational budget (in tokens) at test-time and model accuracy. Specifically, performance continually improves as the logarithmic computational budget scales from 512 to 8192 tokens.\nModality-tailored critiques enhance self-correction\n– Separate visual and code critique mechanisms substantially boost the self-correction capability of VLMs. An ablation study showed a 5.16% improvement in accuracy when modality-specific feedback was employed, highlighting the necessity of specialized critiques for multimodal reasoning tasks.\nSignificant accuracy gains\n– METAL achieved significant performance improvements over state-of-the-art methods. Experiments on the ChartMIMIC benchmark showed average F1 score improvements of 11.33% with open-source models (LLAMA 3.2-11B) and 5.2% with closed-source models (GPT-4O).\nPaper\n|\nTweet\n8). LightThinker\nThis new paper proposes a novel approach to dynamically compress reasoning steps in LLMs, significantly improving efficiency without sacrificing accuracy. Key insights include:\nCompression of intermediate thoughts\n– Inspired by human cognition, LightThinker teaches LLMs to summarize and discard verbose reasoning steps, reducing memory footprint and computational cost during inference.\nTraining LLMs to compress\n– The method trains models to identify when and how to condense reasoning by mapping hidden states to compact gist tokens and introducing specialized attention masks.\nDependency metric for compression\n– The paper introduces Dep, a metric that quantifies the reliance on historical tokens during generation. Lower Dep values indicate effective compression with minimal information loss.\nMemory & speed improvements\n– Experiments show that LightThinker reduces peak memory usage by 70% and inference time by 26% while maintaining nearly identical accuracy (within 1% of uncompressed models).\nOutperforming baseline approaches\n– Compared to token-eviction (H2O) and anchor-token (AnLLM) methods, LightThinker achieves higher efficiency with fewer tokens stored and better generalization across reasoning tasks.\nPaper\n|\nTweet\n9). A Systematic Survey of Prompt Optimization\nThis paper offers a comprehensive survey of Automatic Prompt Optimization (APO)—defining its scope, presenting a unifying 5-part framework, categorizing existing methods, and highlighting key progress and challenges in automating prompt engineering for LLMs.\nPaper\n|\nTweet\n10). Protein LLMs\nA comprehensive overview of Protein LLMs, including architectures, training datasets, evaluation metrics, and applications.\nPaper\n|\nTweet",
            "metadata": {
              "title": "🥇Top AI Papers of the Week: Claude 3.7 Sonnet, GPT-4.5, Chain-of-Draft",
              "description": "The Top AI Papers of the Week (Feb 24 - Mar 2)",
              "keywords": null,
              "author": "elvis",
              "og:type": "article",
              "og:title": "🥇Top AI Papers of the Week: Claude 3.7 Sonnet, GPT-4.5, Chain-of-Draft",
              "og:description": "The Top AI Papers of the Week (Feb 24 - Mar 2)",
              "og:image": "https://substackcdn.com/image/fetch/$s_!WPaO!,w_1200,h_675,c_fill,f_jpg,q_auto:good,fl_progressive:steep,g_auto/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4a02474-59a7-4ab3-ab4e-faadfab1cac1_1123x753.png",
              "og:url": "https://nlp.elvissaravia.com/p/top-ai-papers-of-the-week",
              "twitter:title": "🥇Top AI Papers of the Week: Claude 3.7 Sonnet, GPT-4.5, Chain-of-Draft",
              "twitter:description": "The Top AI Papers of the Week (Feb 24 - Mar 2)",
              "twitter:image": "https://substackcdn.com/image/fetch/$s_!4bRt!,f_auto,q_auto:best,fl_progressive:steep/https%3A%2F%2Fnlpnews.substack.com%2Fapi%2Fv1%2Fpost_preview%2F158106009%2Ftwitter.jpg%3Fversion%3D4",
              "twitter:card": "summary_large_image",
              "article:modified_time": "2025-03-02T16:42:53.985Z"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!WPaO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4a02474-59a7-4ab3-ab4e-faadfab1cac1_1123x753.png",
                "bytes": 53879,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/026.png",
                "src": "https://substackcdn.com/image/fetch/$s_!WPaO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4a02474-59a7-4ab3-ab4e-faadfab1cac1_1123x753.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!yCsV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cb1ef9d-b1fc-4e79-804c-80e8745dcf83_2208x1284.png",
                "bytes": 26585,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/037.png",
                "src": "https://substackcdn.com/image/fetch/$s_!yCsV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cb1ef9d-b1fc-4e79-804c-80e8745dcf83_2208x1284.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!4GTO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa10934f-331c-4dae-9639-b2ea96f151db_967x624.png",
                "bytes": 29420,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-43a6ada86614ffff7ca1.png",
                "src": "https://substackcdn.com/image/fetch/$s_!4GTO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa10934f-331c-4dae-9639-b2ea96f151db_967x624.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!6WZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd112436b-6c55-4979-86d1-33a3ef55709b_998x692.png",
                "bytes": 47097,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-dc2f7e8e1b17cc8b9302.png",
                "src": "https://substackcdn.com/image/fetch/$s_!6WZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd112436b-6c55-4979-86d1-33a3ef55709b_998x692.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!HoMc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73098dcb-007a-4281-a028-cea964569381_701x507.png",
                "bytes": 55233,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-df0ffec5d685f767073a.png",
                "src": "https://substackcdn.com/image/fetch/$s_!HoMc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73098dcb-007a-4281-a028-cea964569381_701x507.png",
                "alt": "Image",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!RVHo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56f0dce7-f386-4e32-92d0-b834b988281f_1172x712.png",
                "bytes": 63252,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-734069a24cfc8d1e54ce.png",
                "src": "https://substackcdn.com/image/fetch/$s_!RVHo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56f0dce7-f386-4e32-92d0-b834b988281f_1172x712.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!vb72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5290adb1-545d-43a8-bfe7-030ac5be0a9d_917x563.png",
                "bytes": 110178,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-0a99e833916a2895b1f3.png",
                "src": "https://substackcdn.com/image/fetch/$s_!vb72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5290adb1-545d-43a8-bfe7-030ac5be0a9d_917x563.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!ivwJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F255fba30-b423-44e6-b655-82d6eed2ea3c_1335x587.png",
                "bytes": 189831,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-187e2bdb0faa74423210.png",
                "src": "https://substackcdn.com/image/fetch/$s_!ivwJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F255fba30-b423-44e6-b655-82d6eed2ea3c_1335x587.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!wdJc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3dc989e-7827-4da5-8305-7e32ab6125e0_782x697.png",
                "bytes": 45233,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-8071dba690f793a9b90f.png",
                "src": "https://substackcdn.com/image/fetch/$s_!wdJc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3dc989e-7827-4da5-8305-7e32ab6125e0_782x697.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!37PR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79482331-5ce9-4d2c-b3b3-d1225ddc8249_839x851.png",
                "bytes": 115266,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-ef37330c102b2db2aefa.png",
                "src": "https://substackcdn.com/image/fetch/$s_!37PR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79482331-5ce9-4d2c-b3b3-d1225ddc8249_839x851.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://substackcdn.com/image/fetch/$s_!cTRQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86032176-3d06-438f-a73e-11821f670f18_1047x490.png",
                "bytes": 167451,
                "reused": true,
                "local_path": "attachments/3d1207cdb1fb/images/body-33f641bca98e7eecd750.png",
                "src": "https://substackcdn.com/image/fetch/$s_!cTRQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86032176-3d06-438f-a73e-11821f670f18_1047x490.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://substackcdn.com/image/fetch/$s_!WPaO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4a02474-59a7-4ab3-ab4e-faadfab1cac1_1123x753.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://assets.anthropic.com/m/785e231869ea8b3b/original/claude-3-7-sonnet-system-card.pdf",
                "label": "System Card",
                "type": "a"
              },
              {
                "href": "https://x.com/AnthropicAI/status/1894092430560965029",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!yCsV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cb1ef9d-b1fc-4e79-804c-80e8745dcf83_2208x1284.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://cdn.openai.com/gpt-4-5-system-card-2272025.pdf",
                "label": "System Card",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1895204032177676696",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!4GTO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa10934f-331c-4dae-9639-b2ea96f151db_967x624.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.18600",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1895135560634900762",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!6WZc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd112436b-6c55-4979-86d1-33a3ef55709b_998x692.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://dair-ai.thinkific.com/courses/prompt-engineering-devs",
                "label": "Prompt Engineering for Developers",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!HoMc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73098dcb-007a-4281-a028-cea964569381_701x507.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.17424",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/OwainEvans_UK/status/1894436637054214509",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!RVHo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56f0dce7-f386-4e32-92d0-b834b988281f_1172x712.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.18394",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1894757821587296614",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!vb72!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5290adb1-545d-43a8-bfe7-030ac5be0a9d_917x563.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.16111",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/dair_ai/status/1895532543652642850",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!ivwJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F255fba30-b423-44e6-b655-82d6eed2ea3c_1335x587.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.17651",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1895528398820425741",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!wdJc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3dc989e-7827-4da5-8305-7e32ab6125e0_782x697.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.15589",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1894068783700218205",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!37PR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79482331-5ce9-4d2c-b3b3-d1225ddc8249_839x851.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.16923",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1894412798282915994",
                "label": "Tweet",
                "type": "a"
              },
              {
                "href": "https://substackcdn.com/image/fetch/$s_!cTRQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86032176-3d06-438f-a73e-11821f670f18_1047x490.png",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2502.17504",
                "label": "Paper",
                "type": "a"
              },
              {
                "href": "https://x.com/omarsar0/status/1894760600141811861",
                "label": "Tweet",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:07Z",
            "source_url": "https://nlp.elvissaravia.com/p/top-ai-papers-of-the-week",
            "delivery_status": "ok",
            "discovery_status": "ok",
            "missing_reason": "",
            "repair_error": "",
            "actual_video_files": [],
            "expected_saved_body_images": 14,
            "image_discovery": "saved_markdown",
            "papers": [
              {
                "status": "ok",
                "url": "https://assets.anthropic.com/m/785e231869ea8b3b/original/claude-3-7-sonnet-system-card.pdf",
                "bytes": 5974368,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1b473b8d3e72c99901ce.pdf"
              },
              {
                "status": "ok",
                "url": "https://cdn.openai.com/gpt-4-5-system-card-2272025.pdf",
                "bytes": 4102476,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0c0032814a75f68b581c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.18600",
                "bytes": 216414,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/77ecb123f71c76ed42cb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.17424",
                "bytes": 8672157,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/009ec3175f9483f19f45.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.18394",
                "bytes": 1288168,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f6f661cc2f9a1aace1d7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.16111",
                "bytes": 1905560,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/cb84cf833d63042f44ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.17651",
                "bytes": 1361690,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/889d83abcb6cf6b07c8b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.15589",
                "bytes": 7662356,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/db4fd94b963fb6d18c4c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.16923",
                "bytes": 788314,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/14ea3e93b8fd34d633b8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2502.17504",
                "bytes": 21363004,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/89321fe7ed4a10819d13.pdf"
              }
            ],
            "body_chars": 12617,
            "expected_body_images": 11,
            "raw_html": "attachments/3d1207cdb1fb/pages/source.html",
            "local_html": "attachments/3d1207cdb1fb/pages/article.html",
            "body_base_path": "attachments/3d1207cdb1fb/pages/",
            "body_markdown_path": "attachments/3d1207cdb1fb/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:18Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1829,
      "source_url": "https://www.3blue1brown.com/topics/neural-networks",
      "items": [
        {
          "url": "https://www.3blue1brown.com/topics/neural-networks",
          "status": "ok",
          "article_id": "d22214ccd991",
          "local_path": "series-follow/1829/repair/83305c9465b670e41c94.html",
          "images": [
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/all-DCAfMrsQ.webp",
              "bytes": 9246,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/7794243920aab9402b69.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/best-of-CWnygR-d.webp",
              "bytes": 7778,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/42f8505ee8eab544bce5.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/neural-networks-Dg1RnYuL.webp",
              "bytes": 16602,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/4370ab3b4ca91dda14ef.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/linear-algebra-C-0g0qH-.webp",
              "bytes": 28368,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/273a40485c8175eaafba.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/calculus-ByfRKh5m.webp",
              "bytes": 10720,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/58c41c537c1e3d5ae617.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/differential-equations-CEc671FK.webp",
              "bytes": 64142,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/2839ffe06a6bd17c3b0c.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/analysis-Bw0RQ8q6.webp",
              "bytes": 19596,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/12c0ca2e13edfe86b21f.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/physics-Bt42hGIQ.webp",
              "bytes": 16094,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/b029957913c9df7d229a.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/computer-science-Bb8qRBNc.webp",
              "bytes": 10778,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/5b3548e90305256435c8.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/why-pi-tci0Ofd1.webp",
              "bytes": 5560,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/9411bc2af46e649ef50c.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/puzzles-wixN2SxY.webp",
              "bytes": 20718,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/0ff26a9c38542673ed16.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/geometry-CpHRBP9V.webp",
              "bytes": 22930,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/6bf2ca87a5c7f46a4a76.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/topology-B5waIMx7.webp",
              "bytes": 49904,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/04dea280036477820c97.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/fractals-Clv8NISD.webp",
              "bytes": 11416,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/68538dea255e6181ca41.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/probability-B7llcmzJ.webp",
              "bytes": 7216,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/91f54f04cbd516cb3f13.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/group-theory-WM6i4XAM.webp",
              "bytes": 13738,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/8121eaee09a0fea03321.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/number-theory-CFerpx-U.webp",
              "bytes": 9920,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/5c05fc7f397b9c004638.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/lockdown-math-BkXZIMm7.webp",
              "bytes": 10342,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/c3ad9ad370d8fbfb279b.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/guest-videos-DaUc5VRM.webp",
              "bytes": 14074,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/a5cebd7b13af4db1b2b2.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/talks-DxOauWJs.webp",
              "bytes": 12298,
              "reused": false,
              "content_type": "image/webp",
              "local_path": "series-follow/1829/repair/assets/7d00f9d9886e893171ac.webp"
            },
            {
              "status": "ok",
              "url": "https://www.3blue1brown.com/assets/support-BRW9qZm8.png",
              "bytes": 34206,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1829/repair/assets/98270bb03a9ede6ac7fb.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "3Blue1Brown",
            "title_listed": "3Blue1Brown 深度学习系列",
            "keywords": "深度学习,神经网络,可视化",
            "domain": "机器学习",
            "content_type": "视频/教程",
            "is_paid_flag": "否",
            "url": "https://www.3blue1brown.com/topics/neural-networks",
            "publish_date": "持续更新",
            "corpus_stage": "机器学习",
            "notes": "深度学习系列主页",
            "id": "d22214ccd991",
            "collected_at": "2026-10-02T15:18:29",
            "title": "3Blue1Brown",
            "body_markdown": "0\nvideos\n0\nsubscribers\n0\nviews\nChannel\nMailing List\nLessons\nAll\nBest Of\nNeural Networks\nLinear Algebra\nCalculus\nDifferential Equations\nAnalysis\nPhysics\nComputer Science\nWhy Pi\nPuzzles\nGeometry\nTopology\nFractals\nProbability\nGroup Theory\nNumber Theory\nLockdown Math\nGuest Videos\nTalks\nOn other channels\nPatreon\nIf these lessons bring you value comparable to that of a textbook or a course, it would mean a lot to me and the rest of the team if you considered joining as a supporter.\nSupporters get early access to new videos and provide essential feedback to refine their final form. Other perks include a meaningful store discount and having your name in a video.\nBecome a Supporter\nNew Video (Early Access)\n3b1b Talent\nThink of it as a\nvirtual career fair.\nWe partner with organizations interested in hiring the kinds of technically curious people who watch 3Blue1Brown.\nExplore Opportunities\nFollow\nInstagram\nMailing List\nX\nBlueSky\nTikTok\nReddit\n2nd Channel\nFacebook\nSpotify\nGitHub\nBilibili\nRSS",
            "metadata": {
              "title": "3Blue1Brown",
              "description": "Mathematics with a distinct visual perspective. Linear algebra, calculus, neural networks, topology, and more.",
              "keywords": null,
              "author": null,
              "og:type": "website",
              "og:url": "https://www.3blue1brown.com/",
              "og:title": "3Blue1Brown",
              "og:description": "Mathematics with a distinct visual perspective. Linear algebra, calculus, neural networks, topology, and more.",
              "og:image": "https://www.3blue1brown.com/share.jpg",
              "twitter:card": "summary_large_image",
              "twitter:image": "https://www.3blue1brown.com/share.jpg"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [],
            "images": [
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/all-DCAfMrsQ.webp",
                "bytes": 9246,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-7794243920aab9402b69.webp",
                "src": "https://www.3blue1brown.com/assets/all-DCAfMrsQ.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/best-of-CWnygR-d.webp",
                "bytes": 7778,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-42f8505ee8eab544bce5.webp",
                "src": "https://www.3blue1brown.com/assets/best-of-CWnygR-d.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/neural-networks-Dg1RnYuL.webp",
                "bytes": 16602,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-4370ab3b4ca91dda14ef.webp",
                "src": "https://www.3blue1brown.com/assets/neural-networks-Dg1RnYuL.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/linear-algebra-C-0g0qH-.webp",
                "bytes": 28368,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-273a40485c8175eaafba.webp",
                "src": "https://www.3blue1brown.com/assets/linear-algebra-C-0g0qH-.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/calculus-ByfRKh5m.webp",
                "bytes": 10720,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-58c41c537c1e3d5ae617.webp",
                "src": "https://www.3blue1brown.com/assets/calculus-ByfRKh5m.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/differential-equations-CEc671FK.webp",
                "bytes": 64142,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-2839ffe06a6bd17c3b0c.webp",
                "src": "https://www.3blue1brown.com/assets/differential-equations-CEc671FK.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/analysis-Bw0RQ8q6.webp",
                "bytes": 19596,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-12c0ca2e13edfe86b21f.webp",
                "src": "https://www.3blue1brown.com/assets/analysis-Bw0RQ8q6.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/physics-Bt42hGIQ.webp",
                "bytes": 16094,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-b029957913c9df7d229a.webp",
                "src": "https://www.3blue1brown.com/assets/physics-Bt42hGIQ.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/computer-science-Bb8qRBNc.webp",
                "bytes": 10778,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-5b3548e90305256435c8.webp",
                "src": "https://www.3blue1brown.com/assets/computer-science-Bb8qRBNc.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/why-pi-tci0Ofd1.webp",
                "bytes": 5560,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-9411bc2af46e649ef50c.webp",
                "src": "https://www.3blue1brown.com/assets/why-pi-tci0Ofd1.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/puzzles-wixN2SxY.webp",
                "bytes": 20718,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-0ff26a9c38542673ed16.webp",
                "src": "https://www.3blue1brown.com/assets/puzzles-wixN2SxY.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/geometry-CpHRBP9V.webp",
                "bytes": 22930,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-6bf2ca87a5c7f46a4a76.webp",
                "src": "https://www.3blue1brown.com/assets/geometry-CpHRBP9V.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/topology-B5waIMx7.webp",
                "bytes": 49904,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-04dea280036477820c97.webp",
                "src": "https://www.3blue1brown.com/assets/topology-B5waIMx7.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/fractals-Clv8NISD.webp",
                "bytes": 11416,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-68538dea255e6181ca41.webp",
                "src": "https://www.3blue1brown.com/assets/fractals-Clv8NISD.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/probability-B7llcmzJ.webp",
                "bytes": 7216,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-91f54f04cbd516cb3f13.webp",
                "src": "https://www.3blue1brown.com/assets/probability-B7llcmzJ.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/group-theory-WM6i4XAM.webp",
                "bytes": 13738,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-8121eaee09a0fea03321.webp",
                "src": "https://www.3blue1brown.com/assets/group-theory-WM6i4XAM.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/number-theory-CFerpx-U.webp",
                "bytes": 9920,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-5c05fc7f397b9c004638.webp",
                "src": "https://www.3blue1brown.com/assets/number-theory-CFerpx-U.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/lockdown-math-BkXZIMm7.webp",
                "bytes": 10342,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-c3ad9ad370d8fbfb279b.webp",
                "src": "https://www.3blue1brown.com/assets/lockdown-math-BkXZIMm7.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/guest-videos-DaUc5VRM.webp",
                "bytes": 14074,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-a5cebd7b13af4db1b2b2.webp",
                "src": "https://www.3blue1brown.com/assets/guest-videos-DaUc5VRM.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/talks-DxOauWJs.webp",
                "bytes": 12298,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-7d00f9d9886e893171ac.webp",
                "src": "https://www.3blue1brown.com/assets/talks-DxOauWJs.webp",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://www.3blue1brown.com/assets/support-BRW9qZm8.png",
                "bytes": 34206,
                "reused": false,
                "local_path": "attachments/d22214ccd991/images/body-98270bb03a9ede6ac7fb.png",
                "src": "https://www.3blue1brown.com/assets/support-BRW9qZm8.png",
                "alt": "Image",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/@3blue1brown",
                "src": "https://www.youtube.com/@3blue1brown",
                "status": "reference_only",
                "kind": "channel_reference"
              },
              {
                "url": "https://www.youtube.com/@grantsanderson",
                "src": "https://www.youtube.com/@grantsanderson",
                "status": "reference_only",
                "kind": "channel_reference"
              }
            ],
            "links": [
              {
                "href": "https://www.youtube.com/@3blue1brown",
                "label": "Channel",
                "type": "a"
              },
              {
                "href": "https://3blue1brown.substack.com/",
                "label": "Mailing List",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/",
                "label": "Lessons",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=all",
                "label": "All",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=best-of",
                "label": "Best Of",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=neural-networks",
                "label": "Neural Networks",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=linear-algebra",
                "label": "Linear Algebra",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=calculus",
                "label": "Calculus",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=differential-equations",
                "label": "Differential Equations",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=analysis",
                "label": "Analysis",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=physics",
                "label": "Physics",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=computer-science",
                "label": "Computer Science",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=why-pi",
                "label": "Why Pi",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=puzzles",
                "label": "Puzzles",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=geometry",
                "label": "Geometry",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=topology",
                "label": "Topology",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=fractals",
                "label": "Fractals",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=probability",
                "label": "Probability",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=group-theory",
                "label": "Group Theory",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=number-theory",
                "label": "Number Theory",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=lockdown-math",
                "label": "Lockdown Math",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=guest-videos",
                "label": "Guest Videos",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=talks",
                "label": "Talks",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/?topic=videos-elsewhere",
                "label": "On other channels",
                "type": "a"
              },
              {
                "href": "https://members.3blue1brown.com/",
                "label": "Become a Supporter",
                "type": "a"
              },
              {
                "href": "https://members.3blue1brown.com/posts/158885046",
                "label": "New Video (Early Access)",
                "type": "a"
              },
              {
                "href": "https://www.3blue1brown.com/talent",
                "label": "Explore Opportunities",
                "type": "a"
              },
              {
                "href": "https://www.instagram.com/3blue1brown",
                "label": "Instagram",
                "type": "a"
              },
              {
                "href": "https://x.com/3blue1brown",
                "label": "X",
                "type": "a"
              },
              {
                "href": "https://bsky.app/profile/3blue1brown.com",
                "label": "BlueSky",
                "type": "a"
              },
              {
                "href": "https://www.tiktok.com/@3blue1brown",
                "label": "TikTok",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/r/3blue1brown",
                "label": "Reddit",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/@grantsanderson",
                "label": "2nd Channel",
                "type": "a"
              },
              {
                "href": "https://www.facebook.com/3blue1brown",
                "label": "Facebook",
                "type": "a"
              },
              {
                "href": "https://open.spotify.com/show/4MFZ3m3PIfsKBNoVR7yIf2",
                "label": "Spotify",
                "type": "a"
              },
              {
                "href": "https://github.com/3b1b",
                "label": "GitHub",
                "type": "a"
              },
              {
                "href": "https://space.bilibili.com/88461692",
                "label": "Bilibili",
                "type": "a"
              },
              {
                "href": "https://3blue1brown.substack.com/feed",
                "label": "RSS",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:53:13Z",
            "source_url": "https://www.3blue1brown.com/topics/neural-networks",
            "papers": [],
            "actual_video_files": [],
            "body_chars": 995,
            "expected_body_images": 21,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/d22214ccd991/pages/source.html",
            "local_html": "attachments/d22214ccd991/pages/article.html",
            "body_base_path": "attachments/d22214ccd991/pages/",
            "body_markdown_path": "attachments/d22214ccd991/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:43:20Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    },
    {
      "source_excel_row": 1601,
      "source_url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
      "items": [
        {
          "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
          "status": "ok",
          "article_id": "028a8389cdec",
          "local_path": "series-follow/1601/repair/d2f5acee51aa81de8884.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
              "bytes": 251848,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d81486b940074ca7bee2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
              "bytes": 255226,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a6d3abf0912005132083.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
              "bytes": 208573,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/533dde5b3386ec869780.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
              "bytes": 582217,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a27ab134b2539e4fa927.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
              "bytes": 545888,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f2a382c35839b44510af.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
              "bytes": 705319,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5b0a42592fcac6b2269f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
              "bytes": 412179,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f70d56c397cd0359db6b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
              "bytes": 264815,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e108c7cf704e84720825.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
              "bytes": 1047500,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bd8c66b6e5605f2b18ac.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
              "bytes": 246545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/57159f6aa6eb14ac2a40.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
              "bytes": 217492,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cad8d44f6e9a7e9a6aef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
              "bytes": 896102,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5b32e280369a4496da10.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 2: Active Learning",
            "keywords": "主动学习,数据标注,采样",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
            "publish_date": "2022-02",
            "corpus_stage": "数据处理",
            "notes": "主动学习系列综述之二",
            "id": "028a8389cdec",
            "collected_at": "2026-10-02T14:13:03",
            "title": "Learning with not Enough Data Part 2: Active Learning | Lil'Log",
            "body_markdown": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.\nNotations\n#\nSymbol\nMeaning\n$K$\nNumber of unique class labels.\n$(\\mathbf{x}^l, y) \\sim \\mathcal{X}, y \\in \\{0, 1\\}^K$\nLabeled dataset. $y$ is a one-hot representation of the true label.\n$\\mathbf{u} \\sim \\mathcal{U}$\nUnlabeled dataset.\n$\\mathcal{D} = \\mathcal{X} \\cup \\mathcal{U}$\nThe entire dataset, including both labeled and unlabeled examples.\n$\\mathbf{x}$\nAny sample which can be either labeled or unlabeled.\n$\\mathbf{x}_i$\nThe $i$-th sample.\n$U(\\mathbf{x})$\nScoring function for active learning selection.\n$P_\\theta(y \\vert \\mathbf{x})$\nA softmax classifier parameterized by $\\theta$.\n$\\hat{y} = \\arg\\max_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x})$\nThe most confident prediction by the classifier.\n$B$\nLabeling budget (the maximum number of samples to label).\n$b$\nBatch size.\nWhat is Active Learning?\n#\nGiven an unlabeled dataset $\\mathcal{U}$ and a fixed amount of labeling cost $B$, active learning aims to select a subset of $B$ examples from $\\mathcal{U}$ to be labeled such that they can result in maximized improvement in model performance. This is an effective way of learning especially when data labeling is difficult and costly, e.g. medical images. This classical\nsurvey paper\nin 2010 lists many key concepts. While some conventional approaches may not apply to deep learning, discussion in this post mainly focuses on deep neural models and training in batch mode.\nIllustration of a cyclic workflow of active learning, producing better models more efficiently by smartly choosing which samples to label.\nTo simplify the discussion, we assume that the task is a $K$-class classification problem in all the following sections. The model with parameters $\\theta$ outputs a probability distribution over the label candidates, which may or may not be calibrated, $P_\\theta(y \\vert \\mathbf{x})$ and the most likely prediction is $\\hat{y} = \\arg\\max_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x})$.\nAcquisition Function\n#\nThe process of identifying the most valuable examples to label next is referred to as “sampling strategy” or “query strategy”. The scoring function in the sampling process is named “acquisition function”, denoted as $U(\\mathbf{x})$. Data points with higher scores are expected to produce higher value for model training if they get labeled.\nHere is a list of basic sampling strategies.\nUncertainty Sampling\n#\nUncertainty sampling\nselects examples for which the model produces most uncertain predictions. Given a single model, uncertainty can be estimated by the predicted probabilities, although one common complaint is that deep learning model predictions are often not calibrated and not correlated with true uncertainty well. In fact, deep learning models are often overconfident.\nLeast confident score\n, also known as\nvariation ratio\n: $U(\\mathbf{x}) = 1 - P_\\theta(\\hat{y} \\vert \\mathbf{x})$.\nMargin score\n: $U(\\mathbf{x}) = P_\\theta(\\hat{y}_1 \\vert \\mathbf{x}) - P_\\theta(\\hat{y}_2 \\vert \\mathbf{x})$, where $\\hat{y}_1$ and $\\hat{y}_2$ are the most likely and the second likely predicted labels.\nEntropy\n: $U(\\mathbf{x}) = \\mathcal{H}(P_\\theta(y \\vert \\mathbf{x})) = - \\sum_{y \\in \\mathcal{Y}} P_\\theta(y \\vert \\mathbf{x}) \\log P_\\theta(y \\vert \\mathbf{x})$.\nAnother way to quantify uncertainty is to rely on a committee of expert models, known as Query-By-Committee (QBC). QBC measures uncertainty based on a pool of opinions and thus it is critical to keep a level of disagreement among committee members. Given $C$ models in the committee pool, each parameterized by $\\theta_1, \\dots, \\theta_C$.\nVoter entropy\n: $U(\\mathbf{x}) = \\mathcal{H}(\\frac{V(y)}{C})$, where $V(y)$ counts the number of votes from the committee on the label $y$.\nConsensus entropy\n: $U(\\mathbf{x}) = \\mathcal{H}(P_\\mathcal{C})$, where $P_\\mathcal{C}$ is the prediction averaging across the committee.\nKL divergence\n: $U(\\mathbf{x}) = \\frac{1}{C} \\sum_{c=1}^C D_\\text{KL} (P_{\\theta_c} | P_\\mathcal{C})$\nDiversity Sampling\n#\nDiversity sampling\nintend to find a collection of samples that can well represent the entire data distribution. Diversity is important because the model is expected to work well on any data in the wild, just not on a narrow subset. Selected samples should be representative of the underlying distribution. Common approaches often rely on quantifying the similarity between samples.\nExpected Model Change\n#\nExpected model change\nrefers to the impact that a sample brings onto the model training. The impact can be the influence on the model weights or the improvement over the training loss. A\nlater section\nreviews several works on how to measure model impact triggered by selected data samples.\nHybrid Strategy\n#\nMany methods above are not mutually exclusive. A\nhybrid\nsampling strategy values different attributes of data points, combining different sampling preferences into one. Often we want to select\nuncertain but also highly representative\nsamples.\nDeep Acquisition Function\n#\nMeasuring Uncertainty\n#\nThe model uncertainty is commonly categorized into two buckets (\nDer Kiureghian & Ditlevsen 2009\n,\nKendall & Gal 2017\n):\nAleatoric uncertainty\nis introduced by noise in the data (e.g. sensor data, noise in the measurement process) and it can be input-dependent or input-independent. It is generally considered as irreducible since there is missing information about the ground truth.\nEpistemic uncertainty\nrefers to the uncertainty within the model parameters and therefore we do not know whether the model can best explain the data. This type of uncertainty is theoretically reducible given more data\nEnsemble and Approximated Ensemble\n#\nThere is a long tradition in machine learning of using ensembles to improve model performance. When there is a significant diversity among models, ensembles are expected to yield better results. This ensemble theory is proved to be correct by many ML algorithms; for example,\nAdaBoost\naggregates many weak learners to perform similar or even better than a single strong learner.\nBootstrapping\nensembles multiple trials of resampling to achieve more accurate estimation of metrics. Random forests or\nGBM\nis also a good example for the effectiveness of ensembling.\nTo get better uncertainty estimation, it is intuitive to aggregate a collection of independently trained models. However, it is expensive to train a single deep neural network model, let alone many of them. In reinforcement learning, Bootstrapped DQN  (\nOsband, et al. 2016\n) is equipped with multiple value heads and relies on the uncertainty among an ensemble of Q value approximation to guide\nexploration\nin RL.\nIn active learning, a commoner approach is to use\ndropout\nto “simulate” a probabilistic Gaussian process (\nGal & Ghahramani 2016\n). We thus ensemble multiple samples collected from the same model but with different dropout masks applied during the forward pass to estimate the model uncertainty (epistemic uncertainty). The process is named\nMC dropout\n(Monte Carlo dropout), where dropout is applied before every weight layer, is approved to be mathematically equivalent to an approximation to the probabilistic deep Gaussian process (\nGal & Ghahramani 2016\n). This simple idea has been shown to be effective for classification with small datasets and widely adopted in scenarios when efficient model uncertainty estimation is needed.\nDBAL\n(Deep Bayesian active learning;\nGal et al. 2017\n) approximates Bayesian neural networks with MC dropout such that it learns a distribution over model weights. In their experiment, MC dropout performed better than random baseline and mean standard deviation (Mean STD), similarly to variation ratios and entropy measurement.\nActive learning results of DBAL on MNIST. (Image source:\nGal et al. 2017\n).\nBeluch et al. (2018)\ncompared ensemble-based models with MC dropout and found that the combination of naive ensemble (i.e. train multiple models separately and independently) and variation ratio yields better calibrated predictions than others. However, naive ensembles are\nvery\nexpensive, so they explored a few alternative cheaper options:\nSnapshot ensemble: Use a cyclic learning rate schedule to train an implicit ensemble such that it converges to different local minima.\nDiversity encouraging ensemble (DEE): Use a base network trained for a small number of epochs as initialization for $n$ different networks, each trained with dropout to encourage diversity.\nSplit head approach: One base model has multiple heads, each corresponding to one classifier.\nUnfortunately all the cheap implicit ensemble options above perform worse than naive ensembles. Considering the limit on computational resources, MC dropout is still a pretty good and economical choice. Naturally, people also try to combine ensemble and MC dropout (\nPop & Fulop 2018\n) to get a bit of additional performance gain by stochastic ensemble.\nUncertainty in Parameter Space\n#\nBayes-by-backprop\n(\nBlundell et al. 2015\n) measures weight uncertainty in neural networks directly. The method maintains a probability distribution over the weights $\\mathbf{w}$, which is modeled as a variational distribution $q(\\mathbf{w} \\vert \\theta)$ since the true posterior $p(\\mathbf{w} \\vert \\mathcal{D})$ is not tractable directly. The loss is to minimize the KL divergence between $q(\\mathbf{w} \\vert \\theta)$ and $p(\\mathbf{w} \\vert \\mathcal{D})$,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta)\n&= \\text{KL}[q(\\mathbf{w}\\vert\\theta) \\| p(\\mathbf{w} \\vert \\mathcal{D})] \\\\ \n&= \\int q(\\mathbf{w}\\vert\\theta) \\log \\frac{q(\\mathbf{w}\\vert\\theta)}{p(\\mathbf{w}) p(\\mathcal{D}\\vert \\mathbf{w})} d\\mathbf{w} \\\\ \n&= \\text{KL}[q(\\mathbf{w}\\vert\\theta) \\| p(w)] - \\mathbb{E}_{q(\\mathbf{w}\\vert\\theta)} [\\log p(\\mathcal{D} \\vert \\mathbf{w})] \\\\\n&\\approx \\log q(\\mathbf{w} \\vert \\theta) - \\log p(\\mathbf{w}) p(\\mathcal{D}\\vert \\mathbf{w}) & \\text{; monte carlo sampling; }q(\\mathbf{w} \\vert \\theta)\\text{ & }p(\\mathbf{w})\\text{ are close.}\n\\end{aligned}\n$$\nThe variational distribution $q$ is typically a Gaussian with diagonal covariance and each weight is sampled from $\\mathcal{N}(\\mu_i, \\sigma_i^2)$. To ensure non-negativity of $\\sigma_i$, it is further parameterized via softplus, $\\sigma_i = \\log(1 + \\exp(\\rho_i))$ where the variational parameters are $\\theta = \\{\\mu_i , \\rho_i\\}^d_{i=1}$.\nThe process of Bayes-by-backprop can be summarized as:\nSample $\\epsilon \\sim \\mathcal{N}(0, I)$\nLet $\\mathbf{w} = \\mu + \\log(1+ \\exp(\\rho)) \\circ \\epsilon$\nLet $\\theta = (\\mu, \\rho)$\nLet $f(\\mathbf{w}, \\theta) = \\log q(\\mathbf{w} \\vert \\theta) - \\log p(\\mathbf{w})p(\\mathcal{D}\\vert \\mathbf{w})$\nCalculate the gradient of $f(\\mathbf{w}, \\theta)$ w.r.t. to $\\mu$ and $\\rho$ and then update $\\theta$.\nUncertainty is measured by sampling different model weights during inference.\nLoss Prediction\n#\nThe loss objective guides model training. A low loss value indicates that a model can make good and accurate predictions.\nYoo & Kweon (2019)\ndesigned a\nloss prediction module\nto predict the loss value for unlabeled inputs, as an estimation of how good a model prediction is on the given data. Data samples are selected if the loss prediction module makes uncertain predictions (high loss value) for them. The loss prediction module is a simple MLP with dropout, that takes several intermediate layer features as inputs and concatenates them after a global average pooling.\nUse the model with a loss prediction module to do active learning selection. (Image source:\nYoo & Kweon 2019\n)\nLet $\\hat{l}$ be the output of the loss prediction module and $l$ be the true loss. When training the loss prediction module, a simple MSE loss $=(l - \\hat{l})^2$ is not a good choice, because the loss decreases in time as the model learns to behave better. A good learning objective should be independent of the scale changes of the target loss. They instead rely on the comparison of sample pairs. Within each batch of size $b$, there are $b/2$ pairs of samples $(\\mathbf{x}_i, \\mathbf{x}_j)$ and the loss prediction model is expected to correctly predict which sample has a larger loss.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loss}(\\mathbf{x}_i, \\mathbf{x}_j) &= \\max\\big( 0, -\\mathbb{1}(l(\\mathbf{x}_i), l(\\mathbf{x}_j)) \\cdot (\\hat{l}(\\mathbf{x}_i) - \\hat{l}(\\mathbf{x}_j)) + \\epsilon \\big) \\\\ \n\\text{where } \\mathbb{1}(l_i, l_j) &= \\begin{cases} +1 & \\text{if }l_i > l_j \\\\ -1 & \\text{otherwise} \\end{cases} \n\\end{aligned}\n$$\nwhere $\\epsilon$ is a predefined positive margin constant.\nIn experiments on three vision tasks, active learning selection based on the loss prediction performs better than random baseline, entropy based acquisition and\ncore-set\n.\nActive learning results of loss prediction module based selection, in comparison with other approaches. (Image source:\nYoo & Kweon 2019\n)\nAdversarial Setup\n#\nSinha et al. (2019)\nproposed a GAN-like setup, named\nVAAL\n(Variational Adversarial Active Learning), where a discriminator is trained to distinguish unlabeled data from labeled data. Interestingly, active learning acquisition criteria does not depend on the task performance in VAAL.\nIllustration of VAAL (Variational adversarial active learning). (Image source:\nSinha et al. 2019\n)\nThe $\\beta$-VAE learns a latent feature space $\\mathbf{z}^l \\cup \\mathbf{z}^u$, for labeled and unlabeled data respectively, aiming to\ntrick\nthe discriminator $D(.)$ that all the data points are from the labeled pool;\nThe discriminator $D(.)$ predicts whether a sample is labeled (1) or not (0) based on a latent representation $\\mathbf{z}$. VAAL selects unlabeled samples with low discriminator scores, which indicates that those samples are sufficiently different from previously labeled ones.\nThe loss for VAE representation learning in VAAL contains both a reconstruction part (minimizing the ELBO of given samples) and an adversarial part (labeled and unlabeled data is drawn from the same probability distribution $q_\\phi$):\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{VAE} &= \\lambda_1 \\mathcal{L}^\\text{rec}_\\text{VAE} + \\lambda_2 \\mathcal{L}^\\text{adv}_\\text{VAE} \\\\\n\\mathcal{L}^\\text{rec}_\\text{VAE} &= \\mathbb{E}[\\log p_\\theta(\\mathbf{x}^l \\vert \\mathbf{z}^l)] - \\beta \\text{KL}(q_\\phi(\\mathbf{z}^l \\vert \\mathbf{x}^l) \\| p(\\mathbf{\\tilde{z}})) + \\mathbb{E}[\\log p_\\theta(\\mathbf{u} \\vert \\mathbf{z}^u)] - \\beta \\text{KL}(q_\\phi(\\mathbf{z}^u \\vert \\mathbf{u}) \\| p(\\mathbf{\\tilde{z}})) \\\\\n\\mathcal{L}^\\text{adv}_\\text{VAE} &= - \\mathbb{E}[\\log D(q_\\phi (\\mathbf{z}^l \\vert \\mathbf{x}^l))] - \\mathbb{E}[\\log D(q_\\phi(\\mathbf{z}^u \\vert \\mathbf{u}))]\n\\end{aligned}\n$$\nwhere $p(\\mathbf{\\tilde{z}})$ is a unit Gaussian as a predefined prior and $\\beta$ is the Lagrangian parameter.\nThe discriminator loss is:\n$$\n\\mathcal{L}_D = -\\mathbb{E}[\\log D(q_\\phi (\\mathbf{z}^l \\vert \\mathbf{x}^l))] - \\mathbb{E}[\\log (1 - D(q_\\phi (\\mathbf{z}^u \\vert \\mathbf{u})))]\n$$\nExperiment results of VAAL (variational adversarial active learning) on several image classification tasks. (Image source:\nSinha et al. 2019\nAblation studies showed that jointly training VAE and discriminator is critical. Their results are robust to the biased initial labeled pool, different labeling budgets and noisy oracle.\nMAL\n(Minimax Active Learning;\nEbrahimiet al. 2021\n) is an extension of VAAL. The MAL framework consists of an entropy minimizing feature encoding network $F$ followed by an entropy maximizing classifier $C$. This minimax setup reduces the distribution gap between labeled and unlabeled data.\nIllustration of the MAL (minimax active learning) framework. (Image source:\nEbrahimiet al. 2021\n)\nA feature encoder $F$ encodes a sample into a $\\ell_2$-normalized $d$-dimensional latent vector. Assuming there are $K$ classes, a classifier $C$ is parameterized by $\\mathbf{W} \\in \\mathbb{R}^{d \\times K}$.\n(1) First $F$ and $C$ are trained on labeled samples by a simple cross entropy loss to achieve good classification results,\n$$\n\\mathcal{L}_\\text{CE} = -\\mathbb{E}_{(\\mathbf{x}^l, y) \\sim \\mathcal{X}} \\sum_{k=1}^K \\mathbb{1}[k=y] \\log\\Big( \\sigma(\\frac{1}{T} \\frac{\\mathbf{W}^\\top F\\big(\\mathbf{x}^l)}{\\|F(\\mathbf{x}^l)\\|}\\big) \\Big)\n$$\n(2) When training on the unlabeled examples, MAL relies on a\nminimax\ngame setup\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{Ent} &= -\\sum^K_{k=1} p(y=k \\vert \\mathbf{u}) \\log p(y=k\\vert \\mathbf{u}) \\\\\n\\theta^*_F, \\theta^*_C &= \\min_F\\max_C \\mathcal{L}_\\text{Ent} \\\\\n\\theta_F &\\gets \\theta_F - \\alpha_1 \\nabla \\mathcal{L}_\\text{Ent} \\\\\n\\theta_C &\\gets \\theta_C + \\alpha_2 \\nabla \\mathcal{L}_\\text{Ent}\n\\end{aligned}\n$$\nwhere,\nFirst, minimizing the entropy in $F$ encourages unlabeled samples associated with similar predicted labels to have similar features.\nMaximizing the entropy in $C$ adversarially makes the prediction to follow a more uniform class distribution.\n(My understanding here is that because the true label of an unlabeled sample is unknown, we should not optimize the classifier to maximize the predicted labels just yet.)\nThe discriminator is trained in the same way as in VAAL.\nSampling strategy in MAL considers both diversity and uncertainty:\nDiversity: the score of $D$ indicates how similar a sample is to previously seen examples. A score closer to 0 is better to select unfamiliar data points.\nUncertainty: use the entropy obtained by $C$. A higher entropy score indicates that the model cannot make a confident prediction yet.\nThe experiments compared MAL to random, entropy, core-set, BALD and VAAL baselines, on image classification and segmentation tasks. The results look pretty strong.\nPerformance of MAL on ImageNet. (Table source:\nEbrahimiet al. 2021\n)\nCAL\n(Contrastive Active Learning;\nMargatina et al. 2021\n) intends to select\ncontrastive\nexamples. If two data points with different labels share similar network representations $\\Phi(.)$, they are considered as contrastive examples in CAL. Given a pair of contrastive examples $(\\mathbf{x}_i, \\mathbf{x}_j)$, they should\n$$\nd(\\Phi(\\mathbf{x}_i), \\Phi(\\mathbf{x}_j)) < \\epsilon \\quad\\text{and}\\quad \\text{KL}(p(y\\vert \\mathbf{x}_i) \\| p(y\\vert \\mathbf{x}_j)) \\rightarrow \\infty\n$$\nGiven an unlabeled sample $\\mathbf{x}$, CAL runs the following process:\nSelect the top $k$ nearest neighbors in the model feature space among the labeled samples, $\\{(\\mathbf{x}^l_i, y_i\\}_{i=1}^M \\subset \\mathcal{X}$.\nCompute the KL divergence between the model output probabilities of $\\mathbf{x}$ and each in $\\{\\mathbf{x}^l\\}$. The contrastive score of $\\mathbf{x}$ is the average of these KL divergence values: $s(\\mathbf{x}) = \\frac{1}{M} \\sum_{i=1}^M \\text{KL}(p(y \\vert \\mathbf{x}^l_i | p(y \\vert \\mathbf{x}))$.\nSamples with\nhigh contrastive scores\nare selected for active learning.\nOn a variety of classification tasks, the experiment results of CAL look similar to the entropy baseline.\nMeasuring Representativeness\n#\nCore-sets Approach\n#\nA\ncore-set\nis a concept in computational geometry, referring to a small set of points that approximates the shape of a larger point set. Approximation can be captured by some geometric measure. In the active learning, we expect a model that is trained over the core-set to behave comparably with the model on the entire data points.\nSener & Savarese (2018)\ntreats active learning as a core-set selection problem. Let’s say, there are $N$ samples in total accessible during training. During active learning, a small set of data points get labeled at every time step $t$, denoted as $\\mathcal{S}^{(t)}$. The upper bound of the learning objective can be written as follows, where the\ncore-set loss\nis defined as the difference between average empirical loss over the labeled samples and the loss over the entire dataset including unlabelled ones.\n$$\n\\begin{aligned}\n\\mathbb{E}_{(\\mathbf{x}, y) \\sim p} [\\mathcal{L}(\\mathbf{x}, y)]\n\\leq& \\bigg\\vert \\mathbb{E}_{(\\mathbf{x}, y) \\sim p} [\\mathcal{L}(\\mathbf{x}, y)] - \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) \\bigg\\vert & \\text{; Generalization error}\\\\\n+& \\frac{1}{\\vert \\mathcal{S}^{(t)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) & \\text{; Training error}\\\\\n+& \\bigg\\vert \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) - \\frac{1}{\\vert \\mathcal{S}^{(t)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) \\bigg\\vert & \\text{; Core-set error}\n\\end{aligned}\n$$\nThen the active learning problem can be redefined as:\n$$\n\\min_{\\mathcal{S}^{(t+1)} : \\vert \\mathcal{S}^{(t+1)} \\vert \\leq b} \\bigg\\vert \\frac{1}{N}\\sum_{i=1}^N \\mathcal{L}(\\mathbf{x}_i, y_i) - \\frac{1}{\\vert \\mathcal{S}^{(t)} \\cup \\mathcal{S}^{(t+1)} \\vert} \\sum_{j=1}^{\\vert \\mathcal{S}^{(t)} \\cup \\mathcal{S}^{(t+1)} \\vert} \\mathcal{L}(\\mathbf{x}^l_j, y_j) \\bigg\\vert\n$$\nIt is equivalent to\nthe $k$-Center problem\n: choose $b$ center points such that the largest distance between a data point and its nearest center is minimized. This problem is NP-hard. An approximate solution depends on the greedy algorithm.\nActive learning results of core-sets algorithm in comparison with several common baselines on CIFAR-10, CIFAR-100, SVHN. (Image source:\nSener & Savarese 2018\n)\nIt works well on image classification tasks when there is a small number of classes. When the number of classes grows to be large or the data dimensionality increases (“curse of dimensionality”), the core-set method becomes less effective (\nSinha et al. 2019\n).\nBecause the core-set selection is expensive,\nColeman et al. (2020)\nexperimented with a weaker model (e.g. smaller, weaker architecture, not fully trained) and found that empirically using a weaker model as a proxy can significantly shorten each repeated data selection cycle of training models and selecting samples, without hurting the final error much. Their method is referred to as\nSVP\n(Selection via Proxy).\nDiverse Gradient Embedding\n#\nBADGE\n(Batch Active learning by Diverse Gradient Embeddings;\nAsh et al. 2020\n) tracks both model uncertainty and data diversity in the gradient space. Uncertainty is measured by the gradient magnitude w.r.t. the final layer of the network and diversity is captured by a diverse set of samples that span in the gradient space.\nUncertainty. Given an unlabeled sample $\\mathbf{x}$, BADGE first computes the prediction $\\hat{y}$ and the gradient $g_\\mathbf{x}$ of the loss on $(\\mathbf{x}, \\hat{y})$ w.r.t. the last layer’s parameters. They observed that the norm of $g_\\mathbf{x}$ conservatively estimates the example’s influence on the model learning and high-confidence samples tend to have gradient embeddings of small magnitude.\nDiversity. Given many gradient embeddings of many samples, $g_\\mathbf{x}$, BADGE runs\n$k$-means++\nto sample data points accordingly.\nAlgorithm of BADGE (batch active learning by diverse gradient embeddings). (Image source:\nAsh et al. 2020\n)\nMeasuring Training Effects\n#\nQuantify Model Changes\n#\nSettles et al. (2008)\nintroduced an active learning query strategy, named\nEGL\n(Expected Gradient Length). The motivation is to find samples that can trigger the greatest update on the model if their labels are known.\nLet $\\nabla \\mathcal{L}(\\theta)$ be the gradient of the loss function with respect to the model parameters. Specifically, given an unlabeled sample $\\mathbf{x}_i$, we need to calculate the gradient assuming the label is $y \\in \\mathcal{Y}$, $\\nabla \\mathcal{L}^{(y)}(\\theta)$. Because the true label $y_i$ is unknown, EGL relies on the current model belief to compute the expected gradient change:\n$$\n\\text{EGL}(\\mathbf{x}_i) = \\sum_{y_i \\in \\mathcal{Y}} p(y=y_i \\vert \\mathbf{x}) \\|\\nabla \\mathcal{L}^{(y_i)}(\\theta)\\|\n$$\nBALD\n(Bayesian Active Learning by Disagreement;\nHoulsby et al. 2011\n) aims to identify samples to maximize the information gain about the model weights, that is equivalent to maximize the decrease in expected posterior entropy.\n$$\n\\begin{aligned}\nI[\\boldsymbol{\\theta}, y \\vert x,\\mathcal{D}] \n&= H(\\boldsymbol{\\theta} \\vert \\mathcal{D}) - \\mathbb{E}_{y \\sim p(y \\vert \\boldsymbol{x}, \\mathcal{D})} \\big[ H(\\boldsymbol{\\theta} \\vert y, \\boldsymbol{x}, \\mathcal{D}) \\big] & \\text{; Decrease in expected posterior entropy}\\\\ \n&= H(y \\vert \\boldsymbol{x}, \\mathcal{D}) - \\mathbb{E}_{\\boldsymbol{\\theta} \\sim p(\\boldsymbol{\\theta} \\vert \\mathcal{D})} \\big[ H(y \\vert \\boldsymbol{x}, \\mathcal{\\theta}) \\big]\n\\end{aligned}\n$$\nThe underlying interpretation is to “seek $\\mathbf{x}$ for which the model is marginally most uncertain about $y$ (high $H(y \\vert \\mathbf{x}, \\mathcal{D})$), but for which individual settings of the parameters are confident (low $H(y \\vert \\mathbf{x}, \\boldsymbol{\\theta})$).” In other words, each individual posterior draw is confident but a collection of draws carry diverse opinions.\nBALD was originally proposed for an individual sample and\nKirsch et al. (2019)\nextended it to work in batch mode.\nForgetting Events\n#\nTo investigate whether neural networks have a tendency to\nforget\npreviously learned information,\nMariya Toneva et al. (2019)\ndesigned an experiment: They track the model prediction for each sample during the training process and count the transitions for each sample from being classified correctly to incorrectly or vice-versa. Then samples can be categorized accordingly,\nForgettable\n(redundant) samples: If the class label changes across training epochs.\nUnforgettable\nsamples: If the class label assignment is consistent across training epochs. Those samples are never forgotten once learned.\nThey found that there are a large number of unforgettable examples that are never forgotten once learnt. Examples with noisy labels or images with “uncommon” features (visually complicated to classify) are among the most forgotten examples. The experiments empirically validated that unforgettable examples can be safely removed without compromising model performance.\nIn the implementation, the forgetting event is only counted when a sample is included in the current training batch; that is, they compute forgetting across presentations of the same example in subsequent mini-batches. The number of forgetting events per sample is quite stable across different seeds and forgettable examples have a small tendency to be first-time learned later in the training. The forgetting events are also found to be transferable throughout the training period and between architectures.\nForgetting events can be used as a signal for active learning acquisition if we hypothesize a model changing predictions during training is an indicator of model uncertainty. However, ground truth is unknown for unlabeled samples.\nBengar et al. (2021)\nproposed a new metric called\nlabel dispersion\nfor such a purpose. Let’s see across the training time, $c^*$ is the most commonly predicted label for the input $\\mathbf{x}$ and the label dispersion measures the fraction of training steps when the model does not assign $c^**$ to this sample:\n$$\n\\text{Dispersion}(\\mathbf{x}) = 1 - \\frac{f_\\mathbf{x}}{T} \\text{ where }\nf_\\mathbf{x} = \\sum_{t=1}^T \\mathbb{1}[\\hat{y}_t = c^*], c^* = \\arg\\max_{c=1,\\dots,C}\\sum_{t=1}^T \\mathbb{1}[\\hat{y}_t = c]\n$$\nIn their implementation, dispersion is computed at every epoch. Label dispersion is low if the model consistently assigns the same label to the same sample but high if the prediction changes often. Label dispersion is correlated with network uncertainty, as shown in\nLabel dispersion is correlated with network uncertainty. On the x-axis, data points are sorted by label dispersion scores. The y-axis is the model prediction accuracy when the model trys to infer the labels for those samples. (Image source:\nBengar et al. 2021\n)\nHybrid\n#\nWhen running active learning in batch mode, it is important to control diversity within a batch.\nSuggestive Annotation\n(\nSA\n;\nYang et al. 2017\n) is a two-step hybrid strategy, aiming to select both high uncertainty & highly representative labeled samples. It uses uncertainty obtained from an ensemble of models trained on the labeled data and core-sets for choosing representative data samples.\nFirst, SA selects top $K$ images with high uncertainty scores to form a candidate pool $\\mathcal{S}_c \\subseteq \\mathcal{S}_U$. The uncertainty is measured as disagreement between multiple models training with bootstrapping.\nThe next step is to find a subset $\\mathcal{S}_a \\subseteq \\mathcal{S}_c$ with highest representativeness. The cosine similarity between feature vectors of two inputs approximates how similar they are. The representativeness of $\\mathcal{S}_a$ for $\\mathcal{S}_U$ reflects how well $\\mathcal{S}_a$ can represent all the samples in $\\mathcal{S}_u$, defined as:\n$$\nF(\\mathcal{S}_a, \\mathcal{S}_u) = \\sum_{\\mathbf{x}_j \\in \\mathcal{S}_u} f(\\mathcal{S}_a, \\mathbf{x}_j) = \\sum_{\\mathbf{x}_j \\in \\mathcal{S}_u} \\max_{\\mathbf{x}_i \\in \\mathcal{S}_a} \\text{sim}(\\mathbf{x}_i, \\mathbf{x}_j)\n$$\nFormulating $\\mathcal{S}_a \\subseteq \\mathcal{S}_c$ with $k$ data points that maximizes $F(\\mathcal{S}_a, \\mathcal{S}_u)$ is a generalized version of the maximum set cover problem. It is NP-hard and its best possible polynomial time approximation algorithm is a simple greedy method.\nInitially, $\\mathcal{S}_a = \\emptyset$ and $F(\\mathcal{S}_a, \\mathcal{S}_u) = 0$.\nThen,  iteratively add $\\mathbf{x}_i \\in \\mathcal{S}_c$ that maximizes $F(\\mathcal{S}_a \\cup I_i, \\mathcal{S}_u)$ over $\\mathcal{S}_a$, until $\\mathcal{S}_s$ contains $k$ images.\nZhdanov (2019)\nruns a similar process as SA, but at step 2, it relies on $k$-means instead of core-set, where the size of the candidate pool is configured relative to the batch size. Given batch size $b$ and a constant $beta$ (between 10 and 50), it follows these steps:\nTrain a classifier on the labeled data;\nMeasure informativeness of every unlabeled example (e.g. using uncertainty metrics);\nPrefilter top $\\beta b \\geq b$ most informative examples;\nCluster $\\beta b$ examples into $B$ clusters;\nSelect $b$ different examples closest to the cluster centers for this round of active learning.\nActive learning can be further combined with\nsemi-supervised learning\nto save the budget.\nCEAL\n(Cost-Effective Active Learning;\nYang et al. 2017\n) runs two things in parallel:\nSelect uncertain samples via active learning and get them labeled;\nSelect samples with the most confident prediction and assign them\npseudo labels\n. The confidence prediction is judged by whether the prediction entropy is below a threshold $\\delta$. As the model is getting better in time, the threshold $\\delta$ decays in time as well.\nIllustration of CEAL (cost-effective active learning). (Image source:\nYang et al. 2017\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Feb 2022). Learning with not enough data part 2: active learning. Lil’Log. https://lilianweng.github.io/posts/2022-02-20-active-learning/.\nOr\n@article{weng2022active,\n  title   = \"Learning with not Enough Data Part 2: Active Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2022\",\n  month   = \"Feb\",\n  url     = \"https://lilianweng.github.io/posts/2022-02-20-active-learning/\"\n}\nReferences\n#\n[1] Burr Settles.\nActive learning literature survey.\nUniversity of Wisconsin, Madison, 52(55-66):11, 2010.\n[2]\nhttps://jacobgil.github.io/deeplearning/activelearning\n[3] Yang et al.\n“Cost-effective active learning for deep image classification”\nTCSVT 2016.\n[4] Yarin Gal et al.\n“Dropout as a Bayesian Approximation: representing model uncertainty in deep learning.”\nICML 2016.\n[5] Blundell et al.\n“Weight uncertainty in neural networks (Bayes-by-Backprop)”\nICML 2015.\n[6] Settles et al.\n“Multiple-Instance Active Learning.”\nNIPS 2007.\n[7] Houlsby et al.\nBayesian Active Learning for Classification and Preference Learning.\"\narXiv preprint arXiv:1112.5745 (2020).\n[8] Kirsch et al.\n“BatchBALD: Efficient and Diverse Batch Acquisition for Deep Bayesian Active Learning.”\nNeurIPS 2019.\n[9] Beluch et al.\n“The power of ensembles for active learning in image classification.”\nCVPR 2018.\n[10] Sener & Savarese.\n“Active learning for convolutional neural networks: A core-set approach.”\nICLR 2018.\n[11] Donggeun Yoo & In So Kweon.\n“Learning Loss for Active Learning.”\nCVPR 2019.\n[12] Margatina et al.\n“Active Learning by Acquiring Contrastive Examples.”\nEMNLP 2021.\n[13] Sinha et al.\n“Variational Adversarial Active Learning”\nICCV 2019\n[14] Ebrahimiet al.\n“Minmax Active Learning”\narXiv preprint arXiv:2012.10467 (2021).\n[15] Mariya Toneva et al.\n“An empirical study of example forgetting during deep neural network learning.”\nICLR 2019.\n[16] Javad Zolfaghari Bengar et al.\n“When Deep Learners Change Their Mind: Learning Dynamics for Active Learning.”\nCAIP 2021.\n[17] Yang et al.\n“Suggestive annotation: A deep active learning framework for biomedical image segmentation.”\nMICCAI 2017.\n[18] Fedor Zhdanov.\n“Diverse mini-batch Active Learning”\narXiv preprint arXiv:1901.05954 (2019).",
            "metadata": {
              "title": "Learning with not Enough Data Part 2: Active Learning | Lil'Log",
              "description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "keywords": "data, active-learning",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 2: Active Learning",
              "og:description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 2: Active Learning",
              "twitter:description": "This is part 2 of what to do when facing a limited amount of labeled data for supervised learning tasks. This time we will get some amount of human labeling work involved, but within a budget limit, and therefore we need to be smart when selecting which samples to label.",
              "article:section": "posts",
              "article:published_time": "2022-02-20T00:00:00+00:00",
              "article:modified_time": "2022-02-20T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/028a8389cdec/code/body-000.txt",
                "chars": 276,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
                "bytes": 251848,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-d81486b940074ca7bee2.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-workflow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
                "bytes": 255226,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-a6d3abf0912005132083.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/DBAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
                "bytes": 208573,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-533dde5b3386ec869780.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
                "bytes": 582217,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-a27ab134b2539e4fa927.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/active-learning-loss-prediction-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
                "bytes": 545888,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-f2a382c35839b44510af.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
                "bytes": 705319,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-5b0a42592fcac6b2269f.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/VAAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
                "bytes": 412179,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-f70d56c397cd0359db6b.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
                "bytes": 264815,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-e108c7cf704e84720825.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/MAL-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
                "bytes": 1047500,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-bd8c66b6e5605f2b18ac.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/core-sets-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
                "bytes": 246545,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-57159f6aa6eb14ac2a40.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/BADGE-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
                "bytes": 217492,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-cad8d44f6e9a7e9a6aef.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/label-dispersion-vs-uncertainty.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
                "bytes": 896102,
                "reused": false,
                "local_path": "attachments/028a8389cdec/images/body-5b32e280369a4496da10.png",
                "src": "https://lilianweng.github.io/posts/2022-02-20-active-learning/CEAL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://burrsettles.com/pub/settles.activelearning.pdf",
                "label": "survey paper",
                "type": "a"
              },
              {
                "href": "https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.455.9057&rep=rep1&type=pdf",
                "label": "Der Kiureghian & Ditlevsen 2009",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.04977",
                "label": "Kendall & Gal 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/AdaBoost",
                "label": "AdaBoost",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bootstrapping_(statistics)",
                "label": "Bootstrapping",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Gradient_boosting",
                "label": "GBM",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.04621",
                "label": "Osband, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
                "label": "exploration",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02142",
                "label": "Gal & Ghahramani 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02157",
                "label": "Gal & Ghahramani 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.02910",
                "label": "Gal et al. 2017",
                "type": "a"
              },
              {
                "href": "https://openaccess.thecvf.com/content_cvpr_2018/papers/Beluch_The_Power_of_CVPR_2018_paper.pdf",
                "label": "Beluch et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.03897",
                "label": "Pop & Fulop 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05424",
                "label": "Blundell et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.03677",
                "label": "Yoo & Kweon (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.00370",
                "label": "Sinha et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2012.10467",
                "label": "Ebrahimiet al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2109.03764",
                "label": "Margatina et al. 2021",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "contrastive",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.00489",
                "label": "Sener & Savarese (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Metric_k-center",
                "label": "the $k$-Center problem",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.11829",
                "label": "Coleman et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.03671",
                "label": "Ash et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-means%2B%2B",
                "label": "$k$-means++",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2007/hash/a1519de5b5d44b31a01de013b9b51a80-Abstract.html",
                "label": "Settles et al. (2008)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1112.5745",
                "label": "Houlsby et al. 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.08158",
                "label": "Kirsch et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.05159",
                "label": "Mariya Toneva et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2107.14707",
                "label": "Bengar et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.04737",
                "label": "Yang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.05954",
                "label": "Zhdanov (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
                "label": "semi-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1701.03551",
                "label": "Yang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://jacobgil.github.io/deeplearning/activelearning",
                "label": "https://jacobgil.github.io/deeplearning/activelearning",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:24Z",
            "source_url": "https://lilianweng.github.io/posts/2022-02-20-active-learning/",
            "papers": [
              {
                "status": "ok",
                "url": "https://burrsettles.com/pub/settles.activelearning.pdf",
                "bytes": 1939936,
                "reused": false,
                "local_path": "papers/repair/1a9a9c6742fab449158e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.04977",
                "bytes": 6719323,
                "reused": false,
                "local_path": "papers/repair/266ae612868b87b732a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.04621",
                "bytes": 6874097,
                "reused": false,
                "local_path": "papers/repair/d7a1d129f52a82d595ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02142",
                "bytes": 1107246,
                "reused": false,
                "local_path": "papers/repair/4fb011fb3475ef624220.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02157",
                "bytes": 436231,
                "reused": false,
                "local_path": "papers/repair/f341fa9dd0f0f593ee60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.02910",
                "bytes": 724240,
                "reused": false,
                "local_path": "papers/repair/523334b8d44dca5de9f0.pdf"
              },
              {
                "status": "ok",
                "url": "https://openaccess.thecvf.com/content_cvpr_2018/papers/Beluch_The_Power_of_CVPR_2018_paper.pdf",
                "bytes": 1715354,
                "reused": false,
                "local_path": "papers/repair/f0bcca0541114ac25b32.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.03897",
                "bytes": 4205547,
                "reused": false,
                "local_path": "papers/repair/ce97c4ced1411688db16.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05424",
                "bytes": 628773,
                "reused": false,
                "local_path": "papers/repair/475ff08ad5512624a7cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.03677",
                "bytes": 564131,
                "reused": false,
                "local_path": "papers/repair/79dc6ada83281404ff9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.00370",
                "bytes": 930575,
                "reused": false,
                "local_path": "papers/repair/79c5aedc49e45da7dda8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2012.10467",
                "bytes": 1339851,
                "reused": false,
                "local_path": "papers/repair/90cd58e430cea1408452.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2109.03764",
                "bytes": 2036447,
                "reused": false,
                "local_path": "papers/repair/f5ba7910af8e3a2395ac.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.00489",
                "bytes": 5033708,
                "reused": false,
                "local_path": "papers/repair/238fc8d82668ad254fc1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.11829",
                "bytes": 17351339,
                "reused": false,
                "local_path": "papers/repair/ad0851b7cc881c207705.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.03671",
                "bytes": 4265486,
                "reused": false,
                "local_path": "papers/repair/7474699a4e844a465ace.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1112.5745",
                "bytes": 556354,
                "reused": false,
                "local_path": "papers/repair/d0182f4c21330f972a26.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.08158",
                "bytes": 4001227,
                "reused": false,
                "local_path": "papers/repair/b525dbbc20e226a0e95a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.05159",
                "bytes": 1731989,
                "reused": true,
                "local_path": "papers/repair/55cf5f36e50e938900cd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2107.14707",
                "bytes": 488570,
                "reused": false,
                "local_path": "papers/repair/27448d46f2a1e682c257.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.04737",
                "bytes": 5679851,
                "reused": false,
                "local_path": "papers/repair/de814b520904eeb1ed6e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.05954",
                "bytes": 387045,
                "reused": false,
                "local_path": "papers/repair/3bd458965ad0d9c6d253.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.03551",
                "bytes": 2102878,
                "reused": false,
                "local_path": "papers/repair/85a5a6a9cc2ce15af84e.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 32971,
            "expected_body_images": 12,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/028a8389cdec/pages/source.html",
            "local_html": "attachments/028a8389cdec/pages/article.html",
            "body_base_path": "attachments/028a8389cdec/pages/",
            "body_markdown_path": "attachments/028a8389cdec/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
          "status": "partial",
          "article_id": "7b9f4f54765d",
          "local_path": "series-follow/1601/repair/b48fce1efd05187269e6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
              "bytes": 5376803,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1601/repair/assets/6b91dcea21697574b105.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
              "bytes": 291157,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1f9233b348db9b37e2ee.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
              "bytes": 467414,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/acc2d9731b17ed2baf72.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
              "bytes": 149758,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c138b9ae776276fc8846.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
              "bytes": 1129963,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/02a63a130390d75c9b29.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
              "bytes": 245312,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7c7b014d7ed4fa8401a1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
              "bytes": 208294,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1e519d78d676ad46c539.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
              "bytes": 76657,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/70e7c7e4493d4048b5d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
              "bytes": 331868,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/30ce759c796a4b00b5e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
              "bytes": 499500,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6f821f70a67bba2e4ef7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
              "bytes": 340971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2ea98dac18eabd367373.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
              "bytes": 204770,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/84f271779024a8ad2f72.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
              "bytes": 507936,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c6959ef2ce02358a0d4d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
              "bytes": 451854,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b23af17d8eb4125329b2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
              "bytes": 144456,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cd84e9d2b02b76f1bf08.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
              "bytes": 256303,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5e9526e04be190a25b0e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
              "bytes": 284015,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bb1d03b945066ecdbb48.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
              "bytes": 199433,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/939aa5d0a48211c07558.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Exploration Strategies in Deep Reinforcement Learning",
            "keywords": "探索策略,DRL,bandit",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
            "publish_date": "2020-06",
            "corpus_stage": "强化学习/对齐",
            "notes": "深度强化学习探索策略综述",
            "id": "7b9f4f54765d",
            "collected_at": "2026-10-02T14:13:22",
            "title": "Exploration Strategies in Deep Reinforcement Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-06-17: Add\n“exploration via disagreement”\nin the “Forward Dynamics”\nsection\n.\nExploitation versus exploration\nis a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern\nRL\nalgorithms\nthat optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.\nI would like to discuss several common exploration strategies in Deep RL here. As this is a very big topic, my post by no means can cover all the important subtopics. I plan to update it periodically and keep further enriching the content gradually in time.\nClassic Exploration Strategies\n#\nAs a quick recap, let’s first go through several classic exploration algorithms that work out pretty well in the multi-armed bandit problem or simple tabular RL.\nEpsilon-greedy\n: The agent does random exploration occasionally with probability $\\epsilon$ and takes the optimal action most of the time with probability $1-\\epsilon$.\nUpper confidence bounds\n: The agent selects the greediest action to maximize the upper confidence bound $\\hat{Q}_t(a) + \\hat{U}_t(a)$, where $\\hat{Q}_t(a)$ is the average rewards associated with action $a$ up to time $t$ and $\\hat{U}_t(a)$ is a function reversely proportional to how many times action $a$ has been taken. See\nhere\nfor more details.\nBoltzmann exploration\n: The agent draws actions from a\nboltzmann distribution\n(softmax) over the learned Q values, regulated by a temperature parameter $\\tau$.\nThompson sampling\n: The agent keeps track of a belief over the probability of optimal actions and samples from this distribution. See\nhere\nfor more details.\nThe following strategies could be used for better exploration in deep RL training when neural networks are used for function approximation:\nEntropy loss term\n: Add an entropy term $H(\\pi(a \\vert s))$ into the loss function, encouraging the policy to take diverse actions.\nNoise-based Exploration\n: Add noise into the observation, action or even parameter space (\nFortunato, et al. 2017\n,\nPlappert, et al. 2017\n).\nKey Exploration Problems\n#\nGood exploration becomes especially hard when the environment rarely provides rewards as feedback or the environment has distracting noise. Many exploration strategies are proposed to solve one or both of the following problems.\nThe Hard-Exploration Problem\n#\nThe “hard-exploration” problem refers to exploration in an environment with very sparse or even deceptive reward. It is difficult because random exploration in such scenarios can rarely discover successful states or obtain meaningful feedback.\nMontezuma’s Revenge\nis a concrete example for the hard-exploration problem. It remains as a few challenging games in Atari for DRL to solve. Many papers use Montezuma’s Revenge to benchmark their results.\nThe Noisy-TV Problem\n#\nThe “Noisy-TV” problem started as a thought experiment in\nBurda, et al (2018)\n. Imagine that an RL agent is rewarded with seeking novel experience, a TV with uncontrollable & unpredictable random noise outputs would be able to attract the agent’s attention forever. The agent obtains new rewards from noisy TV consistently, but it fails to make any meaningful progress and becomes a “couch potato”.\nAn agent is rewarded with novel experience in the experiment. If a maze has a noisy TC set up, the agent would be attracted and stop moving in the maze. (Image source: OpenAI Blog:\n\"Reinforcement Learning with Prediction-Based Rewards\"\n)\nIntrinsic Rewards as Exploration Bonuses\n#\nOne common approach to better exploration, especially for solving the\nhard-exploration\nproblem, is to augment the environment reward with an additional bonus signal to encourage extra exploration. The policy is thus trained with a reward composed of two terms, $r_t = r^e_t + \\beta r^i_t$, where $\\beta$ is a hyperparameter adjusting the balance between exploitation and exploration.\n$r^e_t$ is an\nextrinsic\nreward from the environment at time $t$, defined according to the task in hand.\n$r^i_t$ is an\nintrinsic\nexploration bonus at time $t$.\nThis intrinsic reward is somewhat inspired by\nintrinsic motivation\nin psychology (\nOudeyer & Kaplan, 2008\n). Exploration driven by curiosity might be an important way for children to grow and learn. In other words, exploratory activities should be rewarding intrinsically in the human mind to encourage such behavior. The intrinsic rewards could be correlated with curiosity, surprise, familiarity of the state, and many other factors.\nSame ideas can be applied to RL algorithms. In the following sections, methods of bonus-based exploration rewards are roughly grouped into two categories:\nDiscovery of novel states\nImprovement of the agent’s knowledge about the environment.\nCount-based Exploration\n#\nIf we consider intrinsic rewards as rewarding conditions that surprise us, we need a way to measure whether a state is novel or appears often. One intuitive way is to count how many times a state has been encountered and to assign a bonus accordingly. The bonus guides the agent’s behavior to prefer rarely visited states to common states. This is known as the\ncount-based exploration\nmethod.\nLet $N_n(s)$ be the\nempirical count\nfunction that tracks the real number of visits of a state $s$ in the sequence of $s_{1:n}$. Unfortunately, using $N_n(s)$ for exploration directly is not practical, because most of the states would have $N_n(s)=0$, especially considering that the state space is often continuous or high-dimensional. We need an non-zero count for most states, even when they haven’t been seen before.\nCounting by Density Model\n#\nBellemare, et al. (2016)\nused a\ndensity model\nto approximate the frequency of state visits and a novel algorithm for deriving a\npseudo-count\nfrom this density model. Let’s first define a conditional probability over the state space, $\\rho_n(s) = \\rho(s \\vert s_{1:n})$ as the probability of the $(n+1)$-th state being $s$ given the first $n$ states are $s_{1:n}$. To measure this empirically, we can simply use $N_n(s)/n$.\nLet’s also define a\nrecoding probability\nof a state $s$ as the probability assigned by the density model to $s$\nafter observing a new occurrence of\n$s$, $\\rho’_n(s) = \\rho(s \\vert s_{1:n}s)$.\nThe paper introduced two concepts to better regulate the density model, a\npseudo-count\nfunction $\\hat{N}_n(s)$ and a\npseudo-count total\n$\\hat{n}$. As they are designed to imitate an empirical count function, we would have:\n$$\n\\rho_n(s) = \\frac{\\hat{N}_n(s)}{\\hat{n}} \\leq \\rho'_n(s) = \\frac{\\hat{N}_n(s) + 1}{\\hat{n} + 1}\n$$\nThe relationship between $\\rho_n(x)$ and $\\rho’_n(x)$ requires the density model to be\nlearning-positive\n:  for all $s_{1:n} \\in \\mathcal{S}^n$ and all $s \\in \\mathcal{S}$, $\\rho_n(s) \\leq \\rho’_n(s)$. In other words, After observing one instance of $s$, the density model’s prediction of that same $s$ should increase. Apart from being learning-positive, the density model should be trained completely\nonline\nwith non-randomized mini-batches of experienced states, so naturally we have $\\rho’_n = \\rho_{n+1}$.\nThe pseudo-count can be computed from $\\rho_n(s)$ and $\\rho’_n(s)$ after solving the above linear system:\n$$\n\\hat{N}_n(s) = \\hat{n} \\rho_n(s) = \\frac{\\rho_n(s)(1 - \\rho'_n(s))}{\\rho'_n(s) - \\rho_n(s)} \n$$\nOr estimated by the\nprediction gain (PG)\n:\n$$\n\\hat{N}_n(s) \\approx (e^{\\text{PG}_n(s)} - 1)^{-1} = (e^{\\log \\rho'_n(s) - \\log \\rho(s)} - 1)^{-1}\n$$\nA common choice of a count-based intrinsic bonus is $r^i_t = N(s_t, a_t)^{-1/2}$ (as in MBIE-EB;\nStrehl & Littman, 2008\n). The pseudo-count-based exploration bonus is shaped in a similar form, $r^i_t = \\big(\\hat{N}_n(s_t, a_t) + 0.01 \\big)^{-1/2}$.\nExperiments in\nBellemare et al., (2016)\nadopted a simple\nCTS\n(Context Tree Switching) density model to estimate pseudo-counts. The CTS model takes as input a 2D image and assigns to it a probability according to the product of location-dependent L-shaped filters, where the prediction of each filter is given by a CTS algorithm trained on past images. The CTS model is simple but limited in expressiveness, scalability, and data efficiency. In a following-up paper,\nGeorg Ostrovski, et al. (2017)\nimproved the approach by training a PixelCNN (\nvan den Oord et al., 2016\n) as the density model.\nThe density model can also be a Gaussian Mixture Model as in\nZhao & Tresp (2018)\n. They used a variational GMM to estimate the density of trajectories (e.g. concatenation of a sequence of states) and its predicted probabilities to guide prioritization in experience replay in off-policy setting.\nCounting after Hashing\n#\nAnother idea to make it possible to count high-dimensional states is to map states into\nhash codes\nso that the occurrences of states become trackable (\nTang et al. 2017\n). The state space is discretized with a hash function $\\phi: \\mathcal{S} \\mapsto \\mathbb{Z}^k$. An exploration bonus $r^{i}: \\mathcal{S} \\mapsto \\mathbb{R}$ is added to the reward function, defined as $r^{i}(s) = {N(\\phi(s))}^{-1/2}$, where $N(\\phi(s))$ is an empirical count of occurrences of $\\phi(s)$.\nTang et al. (2017)\nproposed to use\nLocality-Sensitive Hashing\n(\nLSH\n) to convert continuous, high-dimensional data to discrete hash codes. LSH is a popular class of hash functions for querying nearest neighbors based on certain similarity metrics. A hashing scheme $x \\mapsto h(x)$ is locality-sensitive if it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. (See how LSH is used in\nTransformer improvement\nif interested.)\nSimHash\nis a type of computationally efficient LSH and it measures similarity by angular distance:\n$$\n\\phi(s) = \\text{sgn}(A g(s)) \\in \\{-1, 1\\}^k\n$$\nwhere $A \\in \\mathbb{R}^{k \\times D}$ is a matrix with each entry drawn i.i.d. from a standard Gaussian and $g: \\mathcal{S} \\mapsto \\mathbb{R}^D$ is an optional preprocessing function. The dimension of binary codes is $k$, controlling the granularity of the state space discretization. A higher $k$ leads to higher granularity and fewer collisions.\nAlgorithm of count-based exploration through hashing high-dimensional states by SimHash. (Image source:\nTang et al. 2017\n)\nFor high-dimensional images, SimHash may not work well on the raw pixel level.\nTang et al. (2017)\ndesigned an autoencoder (AE) which takes as input states $s$ to learn hash codes. It has one special dense layer composed of $k$ sigmoid functions as the latent state in the middle and then the sigmoid activation values $b(s)$ of this layer are binarized by rounding to their closest binary numbers $\\lfloor b(s)\\rceil \\in \\{0, 1\\}^D$ as the binary hash codes for state $s$. The AE loss over $n$ states includes two terms:\n$$\n\\mathcal{L}(\\{s_n\\}_{n=1}^N) = \\underbrace{-\\frac{1}{N} \\sum_{n=1}^N \\log p(s_n)}_\\text{reconstruction loss} + \\underbrace{\\frac{1}{N} \\frac{\\lambda}{K} \\sum_{n=1}^N\\sum_{i=1}^k \\min \\big \\{ (1-b_i(s_n))^2, b_i(s_n)^2 \\big\\}}_\\text{sigmoid activation being closer to binary}\n$$\nOne problem with this approach is that dissimilar inputs $s_i, s_j$ may be mapped to identical hash codes but the AE still reconstructs them perfectly. One can imagine replacing the bottleneck layer $b(s)$ with the hash codes $\\lfloor b(s)\\rceil$, but then gradients cannot be back-propagated through the rounding function. Injecting uniform noise could mitigate this effect, as the AE has to learn to push the latent variable far apart to counteract the noise.\nPrediction-based Exploration\n#\nThe second category of intrinsic exploration bonuses are rewarded for improvement of the agent’s knowledge about the environment. The agent’s familiarity with the environment dynamics can be estimated through a prediction model. This idea of using a prediction model to measure\ncuriosity\nwas actually proposed quite a long time ago (\nSchmidhuber, 1991\n).\nForward Dynamics\n#\nLearning a\nforward dynamics prediction model\nis a great way to approximate how much knowledge our model has obtained about the environment and the task MDPs. It captures an agent’s capability of predicting the consequence of its own behavior, $f: (s_t, a_t) \\mapsto s_{t+1}$. Such a model cannot be perfect (e.g. due to partial observation), the error $e(s_t, a_t) = | f(s_t, a_t) - s_{t+1} |^2_2$ can be used for providing intrinsic exploration rewards. The higher the prediction error, the less familiar we are with that state.  The faster the error rate drops, the more learning progress signals we acquire.\nIntelligent Adaptive Curiosity\n(\nIAC\n;\nOudeyer, et al. 2007\n) sketched an idea of using a forward dynamics prediction model to estimate learning progress and assigned intrinsic exploration reward accordingly.\nIAC relies on a memory which stores all the experiences encountered by the robot, $M=\\{(s_t, a_t, s_{t+1})\\}$ and a forward dynamics model $f$. IAC incrementally splits the state space (i.e. sensorimotor space in the context of robotics, as discussed in the paper) into separate regions based on the transition samples, using a process similar to how a decision tree is split: The split happens when the number of samples is larger than a threshold, and the variance of states in each leaf should be minimal. Each tree node is characterized by its exclusive set of samples and has its own forward dynamics predictor $f$, named “expert”.\nThe prediction error $e_t$ of an expert is pushed into a list associated with each region. The\nlearning progress\nis then measured as the difference between the mean error rate of a moving window with offset $\\tau$ and the current moving window. The intrinsic reward is defined for tracking the learning progress: $r^i_t = \\frac{1}{k}\\sum_{i=0}^{k-1}(e_{t-i-\\tau} - e_{t-i})$, where $k$ is the moving window size. So the larger prediction error rate decrease we can achieve, the higher intrinsic reward we would assign to the agent. In other words, the agent is encouraged to take actions to quickly learn about the environment.\nArchitecture of the IAC (Intelligent Adaptive Curiosity) module: the intrinsic reward is assigned w.r.t the learning progress in reducing prediction error of the dynamics model. (Image source:\nOudeyer, et al. 2007\n)\nStadie et al. (2015)\ntrained a forward dynamics model in the encoding space defined by $\\phi$, $f_\\phi: (\\phi(s_t), a_t) \\mapsto \\phi(s_{t+1})$. The model’s prediction error at time $T$ is normalized by the maximum error up to time $t$, $\\bar{e}_t = \\frac{e_t}{\\max_{i \\leq t} e_i}$, so it is always between 0 and 1. The intrinsic reward is defined accordingly: $r^i_t = (\\frac{\\bar{e}_t(s_t, a_t)}{t \\cdot C})$, where $C > 0$ is a decay constant.\nEncoding the state space via $\\phi(.)$ is necessary, as experiments in the paper have shown that a dynamics model trained directly on raw pixels has\nvery poor\nbehavior — assigning same exploration bonuses to all the states. In\nStadie et al. (2015)\n, the encoding function $\\phi$ is learned via an autocoder (AE) and $\\phi(.)$ is one of the output layers in AE. The AE can be statically trained using a set of images collected by a random agent, or dynamically trained together with the policy where the early frames are gathered using\n$\\epsilon$-greedy\nexploration.\nInstead of autoencoder,\nIntrinsic Curiosity Module\n(\nICM\n;\nPathak, et al., 2017\n) learns the state space encoding $\\phi(.)$ with a self-supervised\ninverse dynamics\nmodel. Predicting the next state given the agent’s own action is not easy, especially considering that some factors in the environment cannot be controlled by the agent or do not affect the agent. ICM believes that a good state feature space should exclude such factors because\nthey cannot influence the agent’s behavior and thus the agent has no incentive for learning them\n. By learning an inverse dynamics model $g: (\\phi(s_t), \\phi(s_{t+1})) \\mapsto a_t$, the feature space only captures those changes in the environment related to the actions of our agent, and ignores the rest.\nGiven a forward model $f$, an inverse dynamics model $g$ and an observation $(s_t, a_t, s_{t+1})$:\n$$\ng_{\\psi_I}(\\phi(s_t), \\phi(s_{t+1})) = \\hat{a}_t \\quad\nf_{\\psi_F}(\\phi(s_t), a_t) = \\hat{\\phi}(s_{t+1}) \\quad\nr_t^i = \\| \\hat{\\phi}(s_{t+1}) - \\phi(s_{t+1}) \\|_2^2\n$$\nSuch $\\phi(.)$ is expected to be robust to uncontrollable aspects of the environment.\nICM (Intrinsic Curiosity Module) assigns the forward dynamics prediction error to the agent as the intrinsic reward. This dynamics model operates in a state encoding space learned through an inverse dynamics model to exclude environmental factors that do not affect the agent's behavior. (Image source:\nPathak, et al. 2017\n)\nBurda, Edwards & Pathak, et al. (2018)\ndid a set of large-scale comparison experiments on purely curiosity-driven learning, meaning that only intrinsic rewards are provided to the agent. In this study, the reward is $r_t = r^i_t = | f(s_t, a_t) - \\phi(s_{t+1})|_2^2$. A good choice of $\\phi$ is crucial to learning forward dynamics, which is expected to be\ncompact\n,\nsufficient\nand\nstable\n, making the prediction task more tractable and filtering out irrelevant observation.\nIn comparison of 4 encoding functions:\nRaw image pixels: No encoding, $\\phi(x) = x$.\nRandom features (RF): Each state is compressed through a fixed random neural network.\nVAE\n: The probabilistic encoder is used for encoding, $\\phi(x) = q(z \\vert x)$.\nInverse dynamic features (IDF): The same feature space as used in\nICM\n.\nAll the experiments have the reward signals normalized by a running estimation of standard deviation of the cumulative returns. And all the experiments are running in an infinite horizon setting to avoid “done” flag leaking information.\nThe mean reward in different games when training with only curiosity signals, generated by different state encoding functions. (Image source:\nBurda, Edwards & Pathak, et al. 2018\n)\nInterestingly\nrandom features\nturn out to be quite competitive, but in feature transfer experiments (i.e. train an agent in Super Mario Bros level 1-1 and then test it in another level), learned IDF features can generalize better.\nThey also compared RF and IDF in an environment with a\nnoisy TV\non. Unsurprisingly the noisy TV drastically slows down the learning and extrinsic rewards are much lower in time.\nExperiments using RF and IDF feature encoding in an environment with noisy TV on or off. The plot tracks extrinsic reward per episode as the training progresses. (Image source:\nBurda, Edwards & Pathak, et al. 2018\n)\nThe forward dynamics optimization can be modeled via variational inference as well.\nVIME\n(short for\n“Variational information maximizing exploration”\n;\nHouthooft, et al. 2017\n) is an exploration strategy based on maximization of\ninformation gain\nabout the agent’s belief of environment dynamics. How much additional information has been obtained about the forward dynamics can be measured as the reduction in entropy.\nLet $\\mathcal{P}$ be the environment transition function, $p(s_{t+1}\\vert s_t, a_t; \\theta)$ be the forward prediction model, parameterized by $\\theta \\in \\Theta$, and $\\xi_t = \\{s_1, a_1, \\dots, s_t\\}$ be the trajectory history. We would like to reduce the entropy after taking a new action and observing the next state, which is to maximize the following:\n$$\n\\begin{aligned}\n&\\sum_t H(\\Theta \\vert \\xi_t, a_t) - H(\\Theta \\vert S_{t+1}, \\xi_t, a_t) \\\\\n=& I(\\Theta; S_{t+1} \\vert \\xi_t, a_t) \\quad \\scriptstyle{\\text{; because } I(X; Y) = I(X) - I(X \\vert Y)} \\\\\n=& \\mathbb{E}_{s_{t+1} \\sim \\mathcal{P}(.\\vert\\xi_t,a_t)} [D_\\text{KL}(p(\\theta \\vert \\xi_t, a_t, s_{t+1}) \\| p(\\theta \\vert \\xi_t, a_t))] \\quad \\scriptstyle{\\text{; because } I(X; Y) = \\mathbb{E}_Y [D_\\text{KL} (p_{X \\vert Y} \\| p_X)]} \\\\\n=& \\mathbb{E}_{s_{t+1} \\sim \\mathcal{P}(.\\vert\\xi_t,a_t)} [D_\\text{KL}(p(\\theta \\vert \\xi_t, a_t, s_{t+1}) \\| p(\\theta \\vert \\xi_t))] \\quad \\scriptstyle{\\text{; because } \\theta \\text{ does not depend on } a_t}\n\\end{aligned}\n$$\nWhile taking expectation over the new possible states, the agent is expected to take a new action to increase the KL divergence (\n“information gain”\n) between its new belief over the prediction model to the old one. This term can be added into the reward function as an intrinsic reward: $r^i_t = D_\\text{KL} [p(\\theta \\vert \\xi_t, a_t, s_{t+1}) | p(\\theta \\vert \\xi_t))]$.\nHowever, computing the posterior $p(\\theta \\vert \\xi_t, a_t, s_{t+1})$ is generally intractable.\n$$\n\\begin{aligned}\np(\\theta \\vert \\xi_t, a_t, s_{t+1}) \n&= \\frac{p(\\theta \\vert \\xi_t, a_t) p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{p(s_{t+1}\\vert\\xi_t, a_t)} \\\\\n&= \\frac{p(\\theta \\vert \\xi_t) p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{p(s_{t+1}\\vert\\xi_t, a_t)} & \\scriptstyle{\\text{; because action doesn't affect the belief.}} \\\\\n&= \\frac{\\color{red}{p(\\theta \\vert \\xi_t)} p(s_{t+1} \\vert \\xi_t, a_t; \\theta)}{\\int_\\Theta p(s_{t+1}\\vert\\xi_t, a_t; \\theta) \\color{red}{p(\\theta \\vert \\xi_t)} d\\theta} & \\scriptstyle{\\text{; red part is hard to compute directly.}}\n\\end{aligned}\n$$\nSince it is difficult to compute $p(\\theta\\vert\\xi_t)$ directly, a natural choice is to approximate it with an alternative distribution $q_\\phi(\\theta)$. With variational lower bound, we know the maximization of $q_\\phi(\\theta)$ is equivalent to maximizing $p(\\xi_t\\vert\\theta)$ and minimizing $D_\\text{KL}[q_\\phi(\\theta) | p(\\theta)]$.\nUsing the approximation distribution $q$, the intrinsic reward becomes:\n$$\nr^i_t = D_\\text{KL} [q_{\\phi_{t+1}}(\\theta) \\| q_{\\phi_t}(\\theta))]\n$$\nwhere $\\phi_{t+1}$ represents $q$’s parameters associated with the new relief after seeing $a_t$ and $s_{t+1}$. When used as an exploration bonus, it is normalized by division by the moving median of this KL divergence value.\nHere the dynamics model is parameterized as a\nBayesian neural network\n(BNN), as it maintains a distribution over its weights. The BNN weight distribution $q_\\phi(\\theta)$ is modeled as a fully\nfactorized\nGaussian with $\\phi = \\{\\mu, \\sigma\\}$ and we can easily sample $\\theta \\sim q_\\phi(.)$. After applying a second-order Taylor expansion, the KL term $D_\\text{KL}[q_{\\phi + \\lambda \\Delta\\phi}(\\theta) | q_{\\phi}(\\theta)]$ can be estimated using\nFisher Information Matrix\n$\\mathbf{F}_\\phi$, which is easy to compute, because $q_\\phi$ is factorized Gaussian and thus the covariance matrix is only a diagonal matrix. See more details in\nthe paper\n, especially section 2.3-2.5.\nAll the methods above depend on a single prediction model. If we have multiple such models, we could use the disagreement among models to set the exploration bonus (\nPathak, et al. 2019\n). High disagreement indicates low confidence in prediction and thus requires more exploration.\nPathak, et al. (2019)\nproposed to train a set of forward dynamics models and to use the variance over the ensemble of model outputs as $r_t^i$. Precisely, they encode the state space with\nrandom feature\nand learn 5 models in the  ensemble.\nIllustration of training architecture for self-supervised exploration via disagreement. (Image source:\nPathak, et al. 2019\n)\nBecause $r^i_t$ is differentiable, the intrinsic reward in the model could be directly optimized through gradient descent so as to inform the policy agent to change actions. This differentiable exploration approach is very efficient but limited by having a short exploration horizon.\nRandom Networks\n#\nBut, what if the prediction task is not about the environment dynamics at all? It turns out when the prediction is for a random task, it still can help exploration.\nDORA\n(short for\n“Directed Outreaching Reinforcement Action-Selection”\n;\nFox & Choshen, et al. 2018\n) is a novel framework that injects exploration signals based on a newly introduced,\ntask-independent\nMDP. The idea of DORA depends on two parallel MDPs:\nOne is the original task MDP;\nThe other is an identical MDP but with\nno reward attached\n: Rather, every state-action pair is designed to have value 0. The Q-value learned for the second MDP is called\nE-value\n. If the model cannot perfectly predict E-value to be zero, it is still missing information.\nInitially E-value is assigned with value 1. Such positive initialization can encourage directed exploration for better E-value prediction. State-action pairs with high E-value estimation don’t have enough information gathered yet, at least not enough to exclude their high E-values. To some extent, the logarithm of E-values can be considered as a generalization of\nvisit counters\n.\nWhen using a neural network to do function approximation for E-value, another value head is added to predict E-value and it is simply expected to predict zero. Given a predicted E-value $E(s_t, a_t)$, the exploration bonus is $r^i_t = \\frac{1}{\\sqrt{-\\log E(s_t, a_t)}}$.\nSimilar to DORA,\nRandom Network Distillation\n(\nRND\n;\nBurda, et al. 2018\n) introduces a prediction task\nindependent of the main task\n. The RND exploration bonus is defined as the error of a neural network $\\hat{f}(s_t)$ predicting features of the observations given by a\nfixed randomly initialized\nneural network $f(s_t)$. The motivation is that given a new state, if similar states have been visited many times in the past, the prediction should be easier and thus has lower error. The exploration bonus is $r^i(s_t) = |\\hat{f}(s_t; \\theta) - f(s_t) |_2^2$.\nHow RND (Random Network Distillation) works for providing an intrinsic reward. The features $O_{i+1} \\mapsto f_{i+1}$ are generated by a fixed random neural network. (Image source: OpenAI Blog:\n\"Reinforcement Learning with Prediction-Based Rewards\"\n)\nTwo factors are important in RND experiments:\nNon-episodic setting results in better exploration, especially when not using any extrinsic rewards. It means that the return is not truncated at “Game over” and intrinsic return can spread across multiple episodes.\nNormalization is important since the scale of the reward is tricky to adjust given a random neural network as a prediction target. The intrinsic reward is normalized by division by a running estimate of the standard deviations of the intrinsic return.\nThe RND setup works well for resolving the hard-exploration problem. For example, maximizing the RND exploration bonus consistently finds more than half of the rooms in Montezuma’s Revenge.\nPhysical Properties\n#\nDifferent from games in simulators, some RL applications like Robotics need to understand objects and intuitive reasoning in the physical world. Some prediction tasks require the agent to perform a sequence of interactions with the environment and to observe the corresponding consequences, such as estimating some hidden properties in physics (e.g. mass, friction, etc).\nMotivated by such ideas,\nDenil, et al. (2017)\nfound that DRL agents can learn to perform necessary exploration to discover such hidden properties. Precisely they considered two experiments:\n“Which is heavier?”\n— The agent has to interact with the blocks and infer which one is heavier.\n“Towers”\n— The agent needs to infer how many rigid bodies a tower is composed of by knocking it down.\nThe agent in the experiments first goes through an exploration phase to interact with the environment and to collect information. Once the exploration phase ends, the agent is asked to output a\nlabeling\naction to answer the question. Then a positive reward is assigned to the agent if the answer is correct; otherwise a negative one is assigned. Because the answer requires a decent amount of interactions with items in the scene, the agent has to learn to efficiently play around so as to figure out the physics and the correct answer. The exploration naturally happens.\nIn their experiments, the agent is able to learn in both tasks with performance varied by the difficulty of the task. Although the paper didn’t use the physics prediction task to provide intrinsic reward bonus along with extrinsic reward associated with another learning task, rather it focused on the exploration tasks themselves. I do enjoy the idea of encouraging sophisticated exploration behavior by predicting hidden physics properties in the environment.\nMemory-based Exploration\n#\nReward-based exploration suffers from several drawbacks:\nFunction approximation is slow to catch up.\nExploration bonus is non-stationary.\nKnowledge fading, meaning that states cease to be novel and cannot provide intrinsic reward signals in time.\nMethods in this section rely on external memory to resolve disadvantages of reward bonus-based exploration.\nEpisodic Memory\n#\nAs mentioned above,\nRND\nis better running in an non-episodic setting, meaning the prediction knowledge is accumulated across multiple episodes. The exploration strategy,\nNever Give Up\n(\nNGU\n;\nBadia, et al. 2020a\n), combines an episodic novelty module that can rapidly adapt within one episode with RND as a lifelong novelty module.\nPrecisely, the intrinsic reward in NGU consists of two exploration bonuses from two modules,\nwithin one episode\nand\nacross multiple episodes\n, respectively.\nThe short-term per-episode reward is provided by an\nepisodic novelty module\n. It contains an episodic memory $M$, a dynamically-sized slot-based memory, and an IDF (inverse dynamics features) embedding function $\\phi$, same as the feature encoding in\nICM\nAt every step the current state embedding $\\phi(s_t)$ is added into $M$.\nThe intrinsic bonus is determined by comparing how similar the current observation is to the content of $M$. A larger difference results in a larger bonus.\n$$\n r^\\text{episodic}_t \\approx \\frac{1}{\\sqrt{\\sum_{\\phi_i \\in N_k} K(\\phi(x_t), \\phi_i)} + c}\n $$\nwhere $K(x, y)$ is a kernel function for measuring the distance between two samples. $N_k$ is a set of $k$ nearest neighbors in $M$ according to $K(., .)$.  $c$ is a small constant to keep the denominator non-zero. In the paper, $K(x, y)$ is configured to be the inverse kernel:\n$$\n K(x, y) = \\frac{\\epsilon}{\\frac{d^2(x, y)}{d^2_m} + \\epsilon}\n $$\nwhere $d(.,.)$ is Euclidean distance between two samples and $d_m$ is a running average of the squared Euclidean distance of the k-th nearest neighbors for better robustness. $\\epsilon$ is a small constant.\nThe architecture of NGU's embedding function (left) and reward generator (right). (Image source:\nBadia, et al. 2020a\n)\nThe long-term across-episode novelty relies on RND prediction error in\nlife-long novelty module\n. The exploration bonus is $\\alpha_t = 1 + \\frac{e^\\text{RND}(s_t) - \\mu_e}{\\sigma_e}$ where $\\mu_e$ and $\\sigma_e$ are running mean and std dev for RND error $e^\\text{RND}(s_t)$.\nHowever in the conclusion section of the\nRND paper\n, I noticed the following statement:\n“We find that the RND exploration bonus is sufficient to deal with local exploration, i.e. exploring the consequences of short-term decisions, like whether to interact with a particular object, or avoid it. However global exploration that involves coordinated decisions over long time horizons is beyond the reach of our method. \"\nAnd this confuses me a bit how RND can be used as a good life-long novelty bonus provider. If you know why, feel free to leave a comment below.\nThe final combined intrinsic reward is $r^i_t = r^\\text{episodic}_t \\cdot \\text{clip}(\\alpha_t, 1, L)$, where $L$ is a constant maximum reward scalar.\nThe design of NGU enables it to have two nice properties:\nRapidly discourages\nrevisiting the same state\nwithin\nthe same episode;\nSlowly discourages\nrevisiting states that have been visited many times\nacross\nepisodes.\nLater, built on top of NGU, DeepMind proposed “Agent57” (\nBadia, et al. 2020b\n), the first deep RL agent that outperforms the standard human benchmark on\nall\n57 Atari games. Two major improvements in Agent57 over NGU are:\nA\npopulation\nof policies are trained in Agent57, each equipped with a different exploration parameter pair $\\{(\\beta_j, \\gamma_j)\\}_{j=1}^N$. Recall that given $\\beta_j$, the reward is constructed as $r_{j,t} = r_t^e + \\beta_j r^i_t$ and $\\gamma_j$ is the reward discounting factor. It is natural to expect policies with higher $\\beta_j$ and lower $\\gamma_j$ to make more progress early in training, while the opposite would be expected as training progresses. A meta-controller (\nsliding-window UCB bandit algorithm\n) is trained to select which policies should be prioritized.\nThe second improvement is a new parameterization of Q-value function that decomposes the contributions of the intrinsic and extrinsic rewards in a similar form as the bundled reward: $Q(s, a; \\theta_j) = Q(s, a; \\theta_j^e) + \\beta_j Q(s, a; \\theta_j^i)$. During training, $Q(s, a; \\theta_j^e)$ and $Q(s, a; \\theta_j^i)$ are optimized separately with rewards $r_j^e$ and $r_j^i$, respectively.\nA pretty cool illustration of techniques developed in time since DQN in 2015, eventually leading to Agent57. (Image source: DeepMind Blog:\n\"Agent57: Outperforming the human Atari benchmark\"\n)\nInstead of using the Euclidean distance to measure closeness of states in episodic memory,\nSavinov, et al. (2019)\ntook the transition between states into consideration and proposed a method to measure the number of steps needed to visit one state from other states in memory, named\nEpisodic Curiosity (EC)\nmodule. The novelty bonus depends on reachability between states.\nAt the beginning of each episode, the agent starts with an empty episodic memory $M$.\nAt every step, the agent compares the current state with saved states in memory to determine novelty bonus: If the current state is novel (i.e., takes more steps to reach from observations in memory than a threshold), the agent gets a bonus.\nThe current state is added into the episodic memory if the novelty bonus is high enough. (Imagine that if all the states were added into memory, any new state could be added within 1 step.)\nRepeat 1-3 until the end of this episode.\nThe nodes in the graph are states, the edges are possible transitions. The blue nodes are states in memory. The green nodes are reachable from the memory within $k = 2$ steps (not novel). The orange nodes are further away, so they are considered as novel states. (Image source:\nSavinov, et al. 2019\n)\nIn order to estimate reachability between states, we need to access the transition graph, which is unfortunately not entirely known. Thus,\nSavinov, et al. (2019)\ntrained a\nsiamese\nneural network to predict how many steps separate two states. It contains one embedding network $\\phi: \\mathcal{S} \\mapsto \\mathbb{R}^n$ to first encode the states to feature vectors and then one comparator network $C: \\mathbb{R}^n \\times \\mathbb{R}^n \\mapsto [0, 1]$ to output a binary label on whether two states are close enough (i.e., reachable within $k$ steps) in the transition graph, $C(\\phi(s_i), \\phi(s_j)) \\mapsto [0, 1]$.\nAn episodic memory buffer $M$ stores embeddings of some past observations within the same episode. A new observation will be compared with existing state embeddings via $C$ and the results are aggregated (e.g. max, 90th percentile) to provide a reachability score $C^M(\\phi(s_t))$. The exploration bonus is $r^i_t = \\big(C’ - C^M(f(s_t))\\big)$, where $C’$ is a predefined threshold for determining the sign of the reward (e.g. $C’=0.5$ works well for fixed-duration episodes). High bonus is awarded to new states when they are not easily reachable from states in the memory buffer.\nThey claimed that the EC module can overcome the\nnoisy-TV\nproblem.\nThe architecture of episodic curiosity (EC) module for intrinsic reward generation.  (Image source:\nSavinov, et al. 2019\n)\nDirect Exploration\n#\nGo-Explore\n(\nEcoffet, et al., 2019\n) is an algorithm aiming to solve the “hard-exploration” problem. It is composed of the following two phases.\nPhase 1 (“Explore until solved”)\nfeels quite like\nDijkstra’s algorithm\nfor finding shortest paths in a graph. Indeed, no neural network is involved in phase 1. By maintaining a memory of interesting states as well as trajectories leading to them, the agent can go back (given a simulator is\ndeterministic\n) to promising states and continue doing\nrandom\nexploration from there. The state is mapped into a short discretized code (named “cell”) in order to be memorized. The memory is updated if a new state appears or a better/shorter trajectory is found. When selecting which past states to return to, the agent might select one in the memory uniformly or according to heuristics like recency, visit count, count of neighbors in the memory, etc. This process is repeated until the task is solved and at least one solution trajectory is found.\nThe above found high-performance trajectories would not work well on evaluation envs with any stochasticity. Thus,\nPhase 2 (“Robustification”)\nis needed to robustify the solution via imitation learning. They adopted\nBackward Algorithm\n, in which the agent is started near the last state in the trajectory and then runs RL optimization from there.\nOne important note in phase 1 is: In order to go back to a state deterministically without exploration, Go-Explore depends on a resettable and deterministic simulator, which is a big disadvantage.\nTo make the algorithm more generally useful to environments with stochasticity, an enhanced version of Go-Explore (\nEcoffet, et al., 2020\n), named\npolicy-based Go-Explore\nwas proposed later.\nInstead of resetting the simulator state effortlessly, the policy-based Go-Explore learns a\ngoal-conditioned policy\nand uses that to access a known state in memory repeatedly. The goal-conditioned policy is trained to follow the best trajectory that previously led to the selected states in memory. They include a\nSelf-Imitation Learning\n(\nSIL\n;\nOh, et al. 2018\n) loss to help extract as much information as possible from successful trajectories.\nAlso, they found sampling from policy works better than random actions when the agent returns to promising states to continue exploration.\nAnother improvement in policy-based Go-Explore is to make the downscaling function of images to cells adjustable. It is optimized so that there would be neither too many nor too few cells in the memory.\nAn overview of the Go-Explore algorithm. (Image source:\nEcoffet, et al., 2020\n)\nAfter vanilla Go-Explore,\nYijie Guo, et al. (2019)\nproposed\nDTSIL\n(Diverse Trajectory-conditioned Self-Imitation Learning), which shared a similar idea as policy-based Go-Explore above. DTSIL maintains a memory of diverse demonstrations collected during training and uses them to train a trajectory-conditioned policy via\nSIL\n. They prioritize trajectories that end with a rare state during sampling.\nAlgorithm of DTSIL (Diverse Trajectory-conditioned Self-Imitation Learning). (Image source:\nYijie Guo, et al. 2019\n)\nThe similar approach is also seen in\nGuo, et al. (2019)\n. The main idea is to store goals with\nhigh uncertainty\nin memory so that later the agent can revisit these goal states with a goal-conditioned policy repeatedly. In each episode, the agent flips a coin (probability 0.5) to decide whether it will act greedily w.r.t. the policy or do directed exploration by sampling goals from the memory.\nDifferent components in directed exploration with function approximation. (Image source:\nGuo, et al. 2019\n)\nThe uncertainty measure of a state can be something simple like count-based bonuses or something complex like density or bayesian models. The paper trained a forward dynamics model and took its prediction error as the uncertainty metric.\nQ-Value Exploration\n#\nInspired by\nThompson sampling\n,\nBootstrapped DQN\n(\nOsband, et al. 2016\n) introduces a notion of uncertainty in Q-value approximation in classic\nDQN\nby using the\nbootstrapping\nmethod. Bootstrapping is to approximate a distribution by sampling with replacement from the same population multiple times and then aggregate the results.\nMultiple Q-value heads are trained in parallel but each only consumes a bootstrapped sub-sampled set of data and each has its own corresponding target network. All the Q-value heads share the same backbone network.\nThe algorithm of Bootstrapped DQN. (Image source:\nOsband, et al. 2016\n)\nAt the beginning of one episode, one Q-value head is sampled uniformly and acts for collecting experience data in this episode. Then a binary mask is sampled from the masking distribution $m \\sim \\mathcal{M}$ and decides which heads can use this data for training. The choice of masking distribution $\\mathcal{M}$ determines how bootstrapped samples are generated; For example,\nIf $\\mathcal{M}$ is an independent Bernoulli distribution with $p=0.5$, this corresponds to the double-or-nothing bootstrap.\nIf $\\mathcal{M}$ always returns an all-one mask, the algorithm reduces to an ensemble method.\nHowever, this kind of exploration is still restricted, because uncertainty introduced by bootstrapping fully relies on the training data. It is better to inject some prior information independent of the data. This “noisy” prior is expected to drive the agent to keep exploring when the reward is sparse. The algorithm of adding random prior into bootstrapped DQN for better exploration (\nOsband, et al. 2018\n) depends on Bayesian linear regression. The core idea of Bayesian regression is: We can\n“generate posterior samples by training on noisy versions of the data, together with some random regularization”\n.\nLet $\\theta$ be the Q function parameter and $\\theta^-$ for the target Q, the loss function using a randomized prior function $p$ is:\n$$\n\\mathcal{L}(\\theta, \\theta^{-}, p, \\mathcal{D}; \\gamma) = \\sum_{t\\in\\mathcal{D}}\\Big( r_t + \\gamma \\max_{a'\\in\\mathcal{A}} (\\underbrace{Q_{\\theta^-} + p)}_\\text{target Q}(s'_t, a') - \\underbrace{(Q_\\theta + p)}_\\text{Q to optimize}(s_t, a_t) \\Big)^2\n$$\nVaritional Options\n#\nOptions are policies with termination conditions. There are a large set of options available in the search space and they are independent of an agent’s intentions. By explicitly including intrinsic options into modeling, the agent can obtain intrinsic rewards for exploration.\nVIC\n(short for\n“Variational Intrinsic Control”\n;\nGregor, et al. 2017\n) is such a framework for providing the agent with intrinsic exploration bonuses based on modeling options and learning policies conditioned on options. Let $\\Omega$ represent an option which starts from $s_0$ and ends at $s_f$. An environment probability distribution $p^J(s_f \\vert s_0, \\Omega)$ defines where an option $\\Omega$ terminates given a starting state $s_0$. A controllability distribution $p^C(\\Omega \\vert s_0)$ defines the probability distribution of options we can sample from. And by definition we have $p(s_f, \\Omega \\vert s_0) = p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0)$.\nWhile choosing options, we would like to achieve two goals:\nAchieve a diverse set of the final states from $s_0$ ⇨ Maximization of $H(s_f \\vert s_0)$.\nKnow precisely which state a given option $\\Omega$ can end with ⇨ Minimization of $H(s_f \\vert s_0, \\Omega)$.\nCombining them, we get mutual information $I(\\Omega; s_f \\vert s_0)$ to maximize:\n$$\n\\begin{aligned}\nI(\\Omega; s_f \\vert s_0)\n&= H(s_f \\vert s_0) - H(s_f \\vert s_0, \\Omega) \\\\\n&= - \\sum_{s_f} p(s_f \\vert s_0) \\log p(s_f \\vert s_0) + \\sum_{s_f, \\Omega} p(s_f, \\Omega \\vert s_0) \\log \\frac{p(s_f, \\Omega \\vert s_0)}{p^C(\\Omega \\vert s_0)} \\\\\n&= - \\sum_{s_f} p(s_f \\vert s_0) \\log p(s_f \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log p^J(s_f \\vert s_0, \\Omega) \\\\\n\\end{aligned}\n$$\nBecause mutual information is symmetric, we can switch $s_f$ and $\\Omega$ in several places without breaking the equivalence. Also because $p(\\Omega \\vert s_0, s_f)$ is difficult to observe, let us replace it with an approximation distribution $q$. According to the variational lower bound, we would have $I(\\Omega; s_f \\vert s_0) \\geq I^{VB}(\\Omega; s_f \\vert s_0)$.\n$$\n\\begin{aligned}\nI(\\Omega; s_f \\vert s_0)\n&= I(s_f; \\Omega \\vert s_0) \\\\\n&= - \\sum_{\\Omega} p(\\Omega \\vert s_0) \\log p(\\Omega \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log \\color{red}{p(\\Omega \\vert s_0, s_f)}\\\\\nI^{VB}(\\Omega; s_f \\vert s_0)\n&= - \\sum_{\\Omega} p(\\Omega \\vert s_0) \\log p(\\Omega \\vert s_0) + \\sum_{s_f, \\Omega} p^J(s_f \\vert s_0, \\Omega) p^C(\\Omega \\vert s_0) \\log \\color{red}{q(\\Omega \\vert s_0, s_f)} \\\\\nI(\\Omega; s_f \\vert s_0) &\\geq I^{VB}(\\Omega; s_f \\vert s_0)\n\\end{aligned}\n$$\nThe algorithm for VIC (Variational Intrinsic Control). (Image source:\nGregor, et al. 2017\n)\nHere $\\pi(a \\vert \\Omega, s)$ can be optimized with any RL algorithm. The option inference function $q(\\Omega \\vert s_0, s_f)$ is doing supervised learning. The prior $p^C$ is updated so that it tends to choose $\\Omega$ with higher rewards. Note that $p^C$ can also be fixed (e.g. a Gaussian). Various $\\Omega$ will result in different behavior through learning. Additionally,\nGregor, et al. (2017)\nobserved that it is difficult to make VIC with explicit options work in practice with function approximation and therefore they also proposed another version of VIC with implicit options.\nDifferent from VIC which models $\\Omega$ conditioned only on the start and end states,\nVALOR\n(short for\n“Variational Auto-encoding Learning of Options by Reinforcement”\n;\nAchiam, et al. 2018\n) relies on the whole trajectory to extract the option context $c$, which is sampled from a fixed Gaussian distribution. In VALOR:\nA policy acts as an encoder, translating contexts from a noise distribution into trajectories\nA decoder attempts to recover the contexts from the trajectories, and rewards the policies for making contexts easier to distinguish. The decoder never sees the actions during training, so the agent has to interact with the environment in a way that facilitates communication with the decoder for better prediction. Also, the decoder recurrently takes in a sequence of steps in one trajectory to better model the correlation between timesteps.\nThe decoder of VALOR is a biLSTM which takes $N = 11$ equally spaced observations from one trajectory as inputs. (Image source:\nAchiam, et al. 2018\n)\nDIAYN (“Diversity is all you need”;\nEysenbach, et al. 2018\n) has the idea lying in the same direction, although with a different name — DIAYN models the policies conditioned on a latent\nskill\nvariable. See my\nprevious post\nfor more details.\nCitation\n#\nCited as:\nWeng, Lilian. (Jun 2020). Exploration strategies in deep reinforcement learning. Lil’Log. https://lilianweng.github.io/posts/2020-06-07-exploration-drl/.\nOr\n@article{weng2020exploration,\n  title   = \"Exploration Strategies in Deep Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Jun\",\n  url     = \"https://lilianweng.github.io/posts/2020-06-07-exploration-drl/\"\n}\nReference\n#\n[1] Pierre-Yves Oudeyer & Frederic Kaplan.\n“How can we define intrinsic motivation?”\nConf. on Epigenetic Robotics, 2008.\n[2] Marc G. Bellemare, et al.\n“Unifying Count-Based Exploration and Intrinsic Motivation”\n. NIPS 2016.\n[3] Georg Ostrovski, et al.\n“Count-Based Exploration with Neural Density Models”\n. PMLR 2017.\n[4] Rui Zhao & Volker Tresp.\n“Curiosity-Driven Experience Prioritization via\nDensity Estimation”\n. NIPS 2018.\n[5] Haoran Tang, et al.\n\"#Exploration: A Study of Count-Based Exploration for Deep Reinforcement Learning”\n. NIPS 2017.\n[6] Jürgen Schmidhuber.\n“A possibility for implementing curiosity and boredom in model-building neural controllers”\n1991.\n[7] Pierre-Yves Oudeyer, et al.\n“Intrinsic Motivation Systems for Autonomous Mental Development”\nIEEE Transactions on Evolutionary Computation, 2007.\n[8] Bradly C. Stadie, et al.\n“Incentivizing Exploration In Reinforcement Learning With Deep Predictive Models”\n. ICLR 2016.\n[9] Deepak Pathak, et al.\n“Curiosity-driven Exploration by Self-supervised Prediction”\n. CVPR 2017.\n[10] Yuri Burda, Harri Edwards & Deepak Pathak, et al.\n“Large-Scale Study of Curiosity-Driven Learning”\n. arXiv 1808.04355 (2018).\n[11] Joshua Achiam & Shankar Sastry.\n“Surprise-Based Intrinsic Motivation for Deep Reinforcement Learning”\nNIPS 2016 Deep RL Workshop.\n[12] Rein Houthooft, et al.\n“VIME: Variational information maximizing exploration”\n. NIPS 2016.\n[13] Leshem Choshen, Lior Fox & Yonatan Loewenstein.\n“DORA the explorer: Directed outreaching reinforcement action-selection”\n. ICLR 2018\n[14] Yuri Burda, et al.\n“Exploration by Random Network Distillation”\nICLR 2019.\n[15] OpenAI Blog:\n“Reinforcement Learning with\nPrediction-Based Rewards”\nOct, 2018.\n[16] Misha Denil, et al.\n“Learning to Perform Physics Experiments via Deep Reinforcement Learning”\n. ICLR 2017.\n[17] Ian Osband, et al.\n“Deep Exploration via Bootstrapped DQN”\n. NIPS 2016.\n[18] Ian Osband, John Aslanides & Albin Cassirer.\n“Randomized Prior Functions for Deep Reinforcement Learning”\n. NIPS 2018.\n[19] Karol Gregor, Danilo Jimenez Rezende & Daan Wierstra.\n“Variational Intrinsic Control”\n. ICLR 2017.\n[20] Joshua Achiam, et al.\n“Variational Option Discovery Algorithms”\n. arXiv 1807.10299 (2018).\n[21] Benjamin Eysenbach, et al.\n“Diversity is all you need: Learning skills without a reward function.”\n. ICLR 2019.\n[22] Adrià Puigdomènech Badia, et al.\n“Never Give Up (NGU): Learning Directed Exploration Strategies”\nICLR 2020.\n[23] Adrià Puigdomènech Badia, et al.\n“Agent57: Outperforming the Atari Human Benchmark”\n. arXiv 2003.13350 (2020).\n[24] DeepMind Blog:\n“Agent57: Outperforming the human Atari benchmark”\nMar 2020.\n[25] Nikolay Savinov, et al.\n“Episodic Curiosity through Reachability”\nICLR 2019.\n[26] Adrien Ecoffet, et al.\n“Go-Explore: a New Approach for Hard-Exploration Problems”\n. arXiv 1901.10995 (2019).\n[27] Adrien Ecoffet, et al.\n“First return then explore”\n. arXiv 2004.12919 (2020).\n[28] Junhyuk Oh, et al.\n“Self-Imitation Learning”\n. ICML 2018.\n[29] Yijie Guo, et al.\n“Self-Imitation Learning via Trajectory-Conditioned Policy for Hard-Exploration Tasks”\n. arXiv 1907.10247 (2019).\n[30] Zhaohan Daniel Guo & Emma Brunskill.\n“Directed Exploration for Reinforcement Learning”\n. arXiv 1906.07805 (2019).\n[31] Deepak Pathak, et al.\n“Self-Supervised Exploration via Disagreement.”\nICML 2019.",
            "metadata": {
              "title": "Exploration Strategies in Deep Reinforcement Learning | Lil'Log",
              "description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "keywords": "reinforcement-learning, exploration, long-read",
              "author": "Lilian Weng",
              "og:title": "Exploration Strategies in Deep Reinforcement Learning",
              "og:description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
              "twitter:card": "summary",
              "twitter:title": "Exploration Strategies in Deep Reinforcement Learning",
              "twitter:description": "[Updated on 2020-06-17: Add “exploration via disagreement” in the “Forward Dynamics” section.\nExploitation versus exploration is a critical topic in Reinforcement Learning. We’d like the RL agent to find the best solution as fast as possible. However, in the meantime, committing to solutions too quickly without enough exploration sounds pretty bad, as it could lead to local minima or total failure. Modern RL algorithms that optimize for the best returns can achieve good exploitation quite efficiently, while exploration remains more like an open topic.",
              "article:section": "posts",
              "article:published_time": "2020-06-07T00:00:00+00:00",
              "article:modified_time": "2020-06-07T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/7b9f4f54765d/code/body-000.txt",
                "chars": 281,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
                "bytes": 5376803,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-6b91dcea21697574b105.gif",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/the-noisy-TV-problem.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
                "bytes": 291157,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-1f9233b348db9b37e2ee.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/count-hashing-exploration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
                "bytes": 467414,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-acc2d9731b17ed2baf72.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/IAC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
                "bytes": 149758,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-c138b9ae776276fc8846.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/ICM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
                "bytes": 1129963,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-02a63a130390d75c9b29.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/large-scale-curiosity-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
                "bytes": 245312,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-7c7b014d7ed4fa8401a1.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/noisy-TV-experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
                "bytes": 208294,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-1e519d78d676ad46c539.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/exploration-via-disagreement.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
                "bytes": 76657,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-70e7c7e4493d4048b5d8.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/RND.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
                "bytes": 331868,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-30ce759c796a4b00b5e9.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/NGU.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
                "bytes": 499500,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-6f821f70a67bba2e4ef7.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/agent57.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
                "bytes": 340971,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-2ea98dac18eabd367373.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/transition-graph.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
                "bytes": 204770,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-84f271779024a8ad2f72.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/episodic-memory-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
                "bytes": 507936,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-c6959ef2ce02358a0d4d.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/policy-based-Go-Explore.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
                "bytes": 451854,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-b23af17d8eb4125329b2.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/DTSIL-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
                "bytes": 144456,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-cd84e9d2b02b76f1bf08.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/directed-exploration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
                "bytes": 256303,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-5e9526e04be190a25b0e.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/bootstrapped-DQN-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
                "bytes": 284015,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-bb1d03b945066ecdbb48.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VIC-explicit-options.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
                "bytes": 199433,
                "reused": false,
                "local_path": "attachments/7b9f4f54765d/images/body-939aa5d0a48211c07558.png",
                "src": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/VALOR-decoder.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "Exploitation versus exploration",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "RL",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "algorithms",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Boltzmann_distribution",
                "label": "boltzmann distribution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.10295",
                "label": "Fortunato, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.01905",
                "label": "Plappert, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Montezuma%27s_Revenge_(video_game)",
                "label": "Montezuma’s Revenge",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.12894",
                "label": "Burda, et al (2018)",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/reinforcement-learning-with-prediction-based-rewards/",
                "label": "\"Reinforcement Learning with Prediction-Based Rewards\"",
                "type": "a"
              },
              {
                "href": "https://www.researchgate.net/profile/Pierre-Yves_Oudeyer/publication/29614795_How_can_we_define_intrinsic_motivation/links/09e415107f1b4c8041000000/How-can-we-define-intrinsic-motivation.pdf",
                "label": "Oudeyer & Kaplan, 2008",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.01868",
                "label": "Bellemare, et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://www.ics.uci.edu/~dechter/courses/ics-295/fall-2019/papers/2008-littman-aij-main.pdf",
                "label": "Strehl & Littman, 2008",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v32/bellemare14.html",
                "label": "CTS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01310",
                "label": "Georg Ostrovski, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.05328",
                "label": "van den Oord et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.08039",
                "label": "Zhao & Tresp (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04717",
                "label": "Tang et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "LSH",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "Transformer improvement",
                "type": "a"
              },
              {
                "href": "https://www.cs.princeton.edu/courses/archive/spr04/cos598B/bib/CharikarEstim.pdf",
                "label": "SimHash",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.957",
                "label": "Schmidhuber, 1991",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.177.7661&rep=rep1&type=pdf",
                "label": "Oudeyer, et al. 2007",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.177.7661&rep=rep1&type=pdf)",
                "label": "Oudeyer, et al. 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1507.00814",
                "label": "Stadie et al. (2015)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.05363",
                "label": "Pathak, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04355",
                "label": "Burda, Edwards & Pathak, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.09674",
                "label": "Houthooft, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/book/10.1007/978-1-4612-0745-0",
                "label": "Bayesian neural network",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "Fisher Information Matrix",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.04161",
                "label": "Pathak, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.04012",
                "label": "Fox & Choshen, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.01843",
                "label": "Denil, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.06038",
                "label": "Badia, et al. 2020a",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.13350",
                "label": "Badia, et al. 2020b",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/0805.3415.pdf",
                "label": "sliding-window UCB bandit algorithm",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/article/Agent57-Outperforming-the-human-Atari-benchmark",
                "label": "\"Agent57: Outperforming the human Atari benchmark\"",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.02274",
                "label": "Savinov, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "siamese",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.10995",
                "label": "Ecoffet, et al., 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm",
                "label": "Dijkstra’s algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.03381",
                "label": "Backward Algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.12919",
                "label": "Ecoffet, et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.05635",
                "label": "Oh, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.10247",
                "label": "Yijie Guo, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.07805",
                "label": "Guo, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.04621",
                "label": "Osband, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bootstrapping_(statistics)",
                "label": "bootstrapping",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03335",
                "label": "Osband, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.07507",
                "label": "Gregor, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.10299",
                "label": "Achiam, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.06070",
                "label": "Eysenbach, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "previous post",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.567.6524&rep=rep1&type=pdf",
                "label": "“How can we define intrinsic motivation?”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01732",
                "label": "“Surprise-Based Intrinsic Motivation for Deep Reinforcement Learning”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:33Z",
            "source_url": "https://lilianweng.github.io/posts/2020-06-07-exploration-drl/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.10295",
                "bytes": 5552124,
                "reused": false,
                "local_path": "papers/repair/1f48b9e472f1b3e0563e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.01905",
                "bytes": 3960914,
                "reused": false,
                "local_path": "papers/repair/dc0f09fcd81792aca048.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.12894",
                "bytes": 2911077,
                "reused": false,
                "local_path": "papers/repair/d17231099b59eb566f4d.pdf"
              },
              {
                "status": "http_403",
                "url": "https://www.researchgate.net/profile/Pierre-Yves_Oudeyer/publication/29614795_How_can_we_define_intrinsic_motivation/links/09e415107f1b4c8041000000/How-can-we-define-intrinsic-motivation.pdf",
                "retried_at": "2026-10-20T17:42:14Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.01868",
                "bytes": 2457210,
                "reused": false,
                "local_path": "papers/repair/c503c78de7ba5ad6362e.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.ics.uci.edu/~dechter/courses/ics-295/fall-2019/papers/2008-littman-aij-main.pdf",
                "bytes": 409936,
                "reused": false,
                "local_path": "papers/repair/b5c556b215acf6e105c1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01310",
                "bytes": 2916725,
                "reused": false,
                "local_path": "papers/repair/bdac3ac1627bde4d46e7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.05328",
                "bytes": 3801322,
                "reused": false,
                "local_path": "papers/repair/19c3e48f1383cc8845a2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.08039",
                "bytes": 3640642,
                "reused": false,
                "local_path": "papers/repair/545ae3e37b78208a50c7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04717",
                "bytes": 5922605,
                "reused": false,
                "local_path": "papers/repair/708608a107423a31260a.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.princeton.edu/courses/archive/spr04/cos598B/bib/CharikarEstim.pdf",
                "bytes": 158779,
                "reused": false,
                "local_path": "papers/repair/2e350dc41664964cf4c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1507.00814",
                "bytes": 1214970,
                "reused": false,
                "local_path": "papers/repair/1b3b417213490898c8fd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.05363",
                "bytes": 2107475,
                "reused": false,
                "local_path": "papers/repair/bb6518ca6eee5ed84bcd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04355",
                "bytes": 5650841,
                "reused": false,
                "local_path": "papers/repair/ac681cd0663a3bbe19ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.09674",
                "bytes": 3838238,
                "reused": false,
                "local_path": "papers/repair/aea7c89cb600a3d85aa6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.04161",
                "bytes": 4625254,
                "reused": false,
                "local_path": "papers/repair/d391070453bdf8dda89b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.04012",
                "bytes": 5927965,
                "reused": false,
                "local_path": "papers/repair/5613937bebaf570d77bd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01843",
                "bytes": 997337,
                "reused": false,
                "local_path": "papers/repair/5d93aa50d61bc398ce91.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.06038",
                "bytes": 5017925,
                "reused": false,
                "local_path": "papers/repair/69a7ead1dbea9f7670bb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.13350",
                "bytes": 4229515,
                "reused": false,
                "local_path": "papers/repair/e9c227fe1baabe459214.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/0805.3415.pdf",
                "bytes": 638874,
                "reused": false,
                "local_path": "papers/repair/00a83b219fdbe0a26878.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.02274",
                "bytes": 4740962,
                "reused": false,
                "local_path": "papers/repair/7cd12e35e24d9a65f2ee.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.10995",
                "bytes": 3381875,
                "reused": false,
                "local_path": "papers/repair/06494300d92be8e99fdd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.03381",
                "bytes": 1109667,
                "reused": false,
                "local_path": "papers/repair/fae1fd91a0865877cdbb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.12919",
                "bytes": 7040307,
                "reused": false,
                "local_path": "papers/repair/4bca2e670151ddcbd087.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.05635",
                "bytes": 3945361,
                "reused": false,
                "local_path": "papers/repair/4ab58d1cfd4397625733.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.10247",
                "bytes": 9692932,
                "reused": false,
                "local_path": "papers/repair/636049565411cb228c10.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.07805",
                "bytes": 588269,
                "reused": false,
                "local_path": "papers/repair/d90ddf5ab36a75311f87.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.04621",
                "bytes": 6874097,
                "reused": true,
                "local_path": "papers/repair/d7a1d129f52a82d595ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03335",
                "bytes": 1549581,
                "reused": false,
                "local_path": "papers/repair/00fa135c690c6b02e961.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.07507",
                "bytes": 824486,
                "reused": false,
                "local_path": "papers/repair/13142c294f93722d3f50.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.10299",
                "bytes": 4005026,
                "reused": false,
                "local_path": "papers/repair/4a3dfad91f75e22c371f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.06070",
                "bytes": 10804715,
                "reused": false,
                "local_path": "papers/repair/682027046f87efa4a50a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01732",
                "bytes": 883210,
                "reused": false,
                "local_path": "papers/repair/c78f6ff64e8c52b250be.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 50020,
            "expected_body_images": 18,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_403",
            "raw_html": "attachments/7b9f4f54765d/pages/source.html",
            "local_html": "attachments/7b9f4f54765d/pages/article.html",
            "body_base_path": "attachments/7b9f4f54765d/pages/",
            "body_markdown_path": "attachments/7b9f4f54765d/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
          "status": "ok",
          "article_id": "c8f3f2a59bb8",
          "local_path": "series-follow/1601/repair/0322612d07df5f51284a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
              "bytes": 82669,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c8feb8e3831d6f407222.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
              "bytes": 238558,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/864616500d13b290a57d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
              "bytes": 618000,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4d1eafbd2698e4b13414.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
              "bytes": 447800,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2202dbf059680ff25f64.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
              "bytes": 331316,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/56fdc531021fd8fc266d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
              "bytes": 92328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a3de29261702db65276c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
              "bytes": 292083,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9fbb7be242e78cf4064e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
              "bytes": 165448,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7c6e570b2b4acaea53ee.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
              "bytes": 410905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0dc7fb2e267a076918a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
              "bytes": 160971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/64c06b583b29bc8d849d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
              "bytes": 575598,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/24abca83dac665bdfd2c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
              "bytes": 191327,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/68a57a589ced1a8dcbeb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
              "bytes": 458778,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dec760a7d6d875b1e5f6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
              "bytes": 413067,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3b05f2c9b09900dd678c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
              "bytes": 307781,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9fe78703c0d6dd59901b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
              "bytes": 395407,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bcffab9e56e403b12eb6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
              "bytes": 378369,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/14fc3bb2a028bd633430.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
              "bytes": 269518,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1cdb06387d4aabe19e7f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
              "bytes": 1172082,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dc3294612801cee60ee0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
              "bytes": 299081,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4ecf4ae1a9c6c75e0b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
              "bytes": 102477,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2f938fd27f3112a7668b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
              "bytes": 302804,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/476b14449fa38214486c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
              "bytes": 459618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d417f179aa932198443f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
              "bytes": 248555,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/61290a159906f77df170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
              "bytes": 263986,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/25636cdf26fe48bc32a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
              "bytes": 127994,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1f6149bb39a134da1e75.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
              "bytes": 167429,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/75a0434d42ea9e13e5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
              "bytes": 235880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0873d959165b59705852.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
              "bytes": 403903,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7fc9d0b8fcf86efd800b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
              "bytes": 237372,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4a85aecfe0dc34b27289.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Contrastive Representation Learning",
            "keywords": "对比学习,表示学习,自监督",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "publish_date": "2021-05",
            "corpus_stage": "预训练/SFT",
            "notes": "对比表示学习综述（SimCLR、MoCo等）",
            "id": "c8f3f2a59bb8",
            "collected_at": "2026-10-02T14:12:57",
            "title": "Contrastive Representation Learning | Lil'Log",
            "body_markdown": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in\nself-supervised learning\n.\nContrastive Training Objectives\n#\nIn early versions of loss functions for contrastive learning, only one positive and one negative sample are involved. The trend in recent training objectives is to include multiple positive and negative pairs in one batch.\nContrastive Loss\n#\nContrastive loss\n(\nChopra et al. 2005\n) is one of the earliest training objectives used for deep metric learning in a contrastive fashion.\nGiven a list of input samples $\\{ \\mathbf{x}_i \\}$, each has a corresponding label $y_i \\in \\{1, \\dots, L\\}$ among $L$ classes. We would like to learn a function $f_\\theta(.): \\mathcal{X}\\to\\mathbb{R}^d$ that encodes $x_i$ into an embedding vector such that examples from the same class have similar embeddings and samples from different classes have very different ones. Thus, contrastive loss takes a pair of inputs $(x_i, x_j)$ and minimizes the embedding distance when they are from the same class but maximizes the distance otherwise.\n$$\n\\mathcal{L}_\\text{cont}(\\mathbf{x}_i, \\mathbf{x}_j, \\theta) = \\mathbb{1}[y_i=y_j] \\| f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\|^2_2 + \\mathbb{1}[y_i\\neq y_j]\\max(0, \\epsilon - \\|f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j)\\|_2)^2\n$$\nwhere $\\epsilon$ is a hyperparameter, defining the lower bound distance between samples of different classes.\nTriplet Loss\n#\nTriplet loss\nwas originally proposed in the FaceNet (\nSchroff et al. 2015\n) paper and was used to learn face recognition of the same person at different poses and angles.\nIllustration of triplet loss given one positive and one negative per anchor. (Image source:\nSchroff et al. 2015\n)\nGiven one anchor input $\\mathbf{x}$, we select one positive sample $\\mathbf{x}^+$ and one negative $\\mathbf{x}^-$, meaning that $\\mathbf{x}^+$ and $\\mathbf{x}$ belong to the same class and $\\mathbf{x}^-$ is sampled from another different class. Triplet loss learns to minimize the distance between the anchor $\\mathbf{x}$ and positive $\\mathbf{x}^+$ and maximize the distance between the anchor $\\mathbf{x}$ and negative $\\mathbf{x}^-$ at the same time with the following equation:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) = \\sum_{\\mathbf{x} \\in \\mathcal{X}} \\max\\big( 0, \\|f(\\mathbf{x}) - f(\\mathbf{x}^+)\\|^2_2 - \\|f(\\mathbf{x}) - f(\\mathbf{x}^-)\\|^2_2 + \\epsilon \\big)\n$$\nwhere the margin parameter $\\epsilon$ is configured as the minimum offset between distances of similar vs dissimilar pairs.\nIt is crucial to select challenging $\\mathbf{x}^-$ to truly improve the model.\nLifted Structured Loss\n#\nLifted Structured Loss\n(\nSong et al. 2015\n) utilizes all the pairwise edges within one training batch for better computational efficiency.\nIllustration compares contrastive loss, triplet loss and lifted structured loss. Red and blue edges connect similar and dissimilar sample pairs respectively. (Image source:\nSong et al. 2015\n)\nLet $D_{ij} = | f(\\mathbf{x}_i) - f(\\mathbf{x}_j) |_2$, a structured loss function is defined as\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{struct} &= \\frac{1}{2\\vert \\mathcal{P} \\vert} \\sum_{(i,j) \\in \\mathcal{P}} \\max(0, \\mathcal{L}_\\text{struct}^{(ij)})^2 \\\\\n\\text{where } \\mathcal{L}_\\text{struct}^{(ij)} &= D_{ij} + \\color{red}{\\max \\big( \\max_{(i,k)\\in \\mathcal{N}} \\epsilon - D_{ik}, \\max_{(j,l)\\in \\mathcal{N}} \\epsilon - D_{jl} \\big)}\n\\end{aligned}\n$$\nwhere $\\mathcal{P}$ contains the set of positive pairs and $\\mathcal{N}$ is the set of negative pairs. Note that the dense pairwise squared distance matrix can be easily computed per training batch.\nThe\nred\npart in $\\mathcal{L}_\\text{struct}^{(ij)}$ is used for mining hard negatives. However, it is not smooth and may cause the convergence to a bad local optimum in practice. Thus, it is relaxed to be:\n$$\n\\mathcal{L}_\\text{struct}^{(ij)} = D_{ij} + \\log \\Big( \\sum_{(i,k)\\in\\mathcal{N}} \\exp(\\epsilon - D_{ik}) + \\sum_{(j,l)\\in\\mathcal{N}} \\exp(\\epsilon - D_{jl}) \\Big)\n$$\nIn the paper, they also proposed to enhance the quality of negative samples in each batch by actively incorporating difficult negative samples given a few random positive pairs.\nN-pair Loss\n#\nMulti-Class N-pair loss\n(\nSohn 2016\n) generalizes triplet loss to include comparison with multiple negative samples.\nGiven a $(N + 1)$-tuplet of training samples, $\\{ \\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-_1, \\dots, \\mathbf{x}^-_{N-1} \\}$, including one positive and $N-1$ negative ones, N-pair loss is defined as:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{N-pair}(\\mathbf{x}, \\mathbf{x}^+, \\{\\mathbf{x}^-_i\\}^{N-1}_{i=1}) \n&= \\log\\big(1 + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i) - f(\\mathbf{x})^\\top f(\\mathbf{x}^+))\\big) \\\\\n&= -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+))}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)) + \\sum_{i=1}^{N-1} \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-_i))}\n\\end{aligned}\n$$\nIf we only sample one negative sample per class, it is equivalent to the softmax loss for multi-class classification.\nNCE\n#\nNoise Contrastive Estimation\n, short for\nNCE\n, is a method for estimating parameters of a statistical model, proposed by\nGutmann & Hyvarinen\nin 2010. The idea is to run logistic regression to tell apart the target data from noise. Read more on how NCE is used for learning word embedding\nhere\n.\nLet $\\mathbf{x}$ be the target sample $\\sim P(\\mathbf{x} \\vert C=1; \\theta) = p_\\theta(\\mathbf{x})$ and $\\tilde{\\mathbf{x}}$ be the noise sample $\\sim  P(\\tilde{\\mathbf{x}} \\vert C=0) = q(\\tilde{\\mathbf{x}})$. Note that the logistic regression models the logit (i.e. log-odds) and in this case we would like to model the logit of a sample $u$ from the target data distribution instead of the noise distribution:\n$$\n\\ell_\\theta(\\mathbf{u}) = \\log \\frac{p_\\theta(\\mathbf{u})}{q(\\mathbf{u})} = \\log p_\\theta(\\mathbf{u}) - \\log q(\\mathbf{u})\n$$\nAfter converting logits into probabilities with sigmoid $\\sigma(.)$, we can apply cross entropy loss:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{NCE} &= - \\frac{1}{N} \\sum_{i=1}^N \\big[ \\log \\sigma (\\ell_\\theta(\\mathbf{x}_i)) + \\log (1 - \\sigma (\\ell_\\theta(\\tilde{\\mathbf{x}}_i))) \\big] \\\\\n\\text{ where }\\sigma(\\ell) &= \\frac{1}{1 + \\exp(-\\ell)} = \\frac{p_\\theta}{p_\\theta + q}\n\\end{aligned}\n$$\nHere I listed the original form of NCE loss which works with only one positive and one noise sample. In many follow-up works, contrastive loss incorporating multiple negative samples is also broadly referred to as NCE.\nInfoNCE\n#\nThe\nInfoNCE loss\nin CPC (\nContrastive Predictive Coding\n;\nvan den Oord, et al. 2018\n), inspired by\nNCE\n, uses categorical cross-entropy loss to identify the positive sample amongst a set of unrelated noise samples.\nGiven a context vector $\\mathbf{c}$, the positive sample should be drawn from the conditional distribution $p(\\mathbf{x} \\vert \\mathbf{c})$, while $N-1$ negative samples are drawn from the proposal distribution $p(\\mathbf{x})$, independent from the context $\\mathbf{c}$. For brevity, let us label all the samples as $X=\\{ \\mathbf{x}_i \\}^N_{i=1}$ among which only one of them $\\mathbf{x}_\\texttt{pos}$ is a positive sample. The probability of we detecting the positive sample correctly is:\n$$\np(C=\\texttt{pos} \\vert X, \\mathbf{c}) \n= \\frac{p(x_\\texttt{pos} \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq \\texttt{pos}} p(\\mathbf{x}_i)}{\\sum_{j=1}^N \\big[ p(\\mathbf{x}_j \\vert \\mathbf{c}) \\prod_{i=1,\\dots,N; i \\neq j} p(\\mathbf{x}_i) \\big]}\n= \\frac{ \\frac{p(\\mathbf{x}_\\texttt{pos}\\vert c)}{p(\\mathbf{x}_\\texttt{pos})} }{ \\sum_{j=1}^N \\frac{p(\\mathbf{x}_j\\vert \\mathbf{c})}{p(\\mathbf{x}_j)} }\n= \\frac{f(\\mathbf{x}_\\texttt{pos}, \\mathbf{c})}{ \\sum_{j=1}^N f(\\mathbf{x}_j, \\mathbf{c}) }\n$$\nwhere the scoring function is $f(\\mathbf{x}, \\mathbf{c}) \\propto \\frac{p(\\mathbf{x}\\vert\\mathbf{c})}{p(\\mathbf{x})}$.\nThe InfoNCE loss optimizes the negative log probability of classifying the positive sample correctly:\n$$\n\\mathcal{L}_\\text{InfoNCE} = - \\mathbb{E} \\Big[\\log \\frac{f(\\mathbf{x}, \\mathbf{c})}{\\sum_{\\mathbf{x}' \\in X} f(\\mathbf{x}', \\mathbf{c})} \\Big]\n$$\nThe fact that $f(x, c)$ estimates the density ratio $\\frac{p(x\\vert c)}{p(x)}$ has a connection with mutual information optimization. To maximize the the mutual information between input $x$ and context vector $c$, we have:\n$$\nI(\\mathbf{x}; \\mathbf{c}) = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c}) \\log\\frac{p(\\mathbf{x}, \\mathbf{c})}{p(\\mathbf{x})p(\\mathbf{c})} = \\sum_{\\mathbf{x}, \\mathbf{c}} p(\\mathbf{x}, \\mathbf{c})\\log\\color{blue}{\\frac{p(\\mathbf{x}|\\mathbf{c})}{p(\\mathbf{x})}}\n$$\nwhere the logarithmic term in\nblue\nis estimated by $f$.\nFor sequence prediction tasks, rather than modeling the future observations $p_k(\\mathbf{x}_{t+k} \\vert \\mathbf{c}_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $\\mathbf{x}_{t+k}$ and $\\mathbf{c}_t$:\n$$\nf_k(\\mathbf{x}_{t+k}, \\mathbf{c}_t) = \\exp(\\mathbf{z}_{t+k}^\\top \\mathbf{W}_k \\mathbf{c}_t) \\propto \\frac{p(\\mathbf{x}_{t+k}\\vert\\mathbf{c}_t)}{p(\\mathbf{x}_{t+k})}\n$$\nwhere $\\mathbf{z}_{t+k}$ is the encoded input and $\\mathbf{W}_k$ is a trainable weight matrix.\nSoft-Nearest Neighbors Loss\n#\nSoft-Nearest Neighbors Loss\n(\nSalakhutdinov & Hinton 2007\n,\nFrosst et al. 2019\n) extends it to include multiple positive samples.\nGiven a batch of samples, $\\{\\mathbf{x}_i, y_i)\\}^B_{i=1}$ where $y_i$ is the class label of $\\mathbf{x}_i$ and a function $f(.,.)$ for measuring similarity between two inputs, the soft nearest neighbor loss at temperature $\\tau$ is defined as:\n$$\n\\mathcal{L}_\\text{snn} = -\\frac{1}{B}\\sum_{i=1}^B \\log \\frac{\\sum_{i\\neq j, y_i = y_j, j=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_j) / \\tau)}{\\sum_{i\\neq k, k=1,\\dots,B} \\exp(- f(\\mathbf{x}_i, \\mathbf{x}_k) /\\tau)}\n$$\nThe temperature $\\tau$ is used for tuning how concentrated the features are in the representation space. For example, when at low temperature, the loss is dominated by the small distances and widely separated representations cannot contribute much and become irrelevant.\nCommon Setup\n#\nWe can loosen the definition of “classes” and “labels” in soft nearest-neighbor loss to create positive and negative sample pairs out of unsupervised data by, for example, applying data augmentation to create noise versions of original samples.\nMost recent studies follow the following definition of contrastive learning objective to incorporate multiple positive and negative samples. According to the setup in (\nWang & Isola 2020\n), let $p_\\texttt{data}(.)$ be the data distribution over $\\mathbb{R}^n$ and $p_\\texttt{pos}(., .)$ be the distribution of positive pairs over $\\mathbb{R}^{n \\times n}$. These two distributions should satisfy:\nSymmetry: $\\forall \\mathbf{x}, \\mathbf{x}^+, p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) = p_\\texttt{pos}(\\mathbf{x}^+, \\mathbf{x})$\nMatching marginal: $\\forall \\mathbf{x}, \\int p_\\texttt{pos}(\\mathbf{x}, \\mathbf{x}^+) d\\mathbf{x}^+ = p_\\texttt{data}(\\mathbf{x})$\nTo learn an encoder $f(\\mathbf{x})$ to learn a\nL2-normalized feature vector\n, the contrastive learning objective is:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{contrastive} \n&= \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} } \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau)}{ \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau) + \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)} \\Big] & \\\\\n&\\approx \\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}, \\{\\mathbf{x}^-_i\\}^M_{i=1} \\overset{\\text{i.i.d}}{\\sim} p_\\texttt{data} }\\Big[ - f(\\mathbf{x})^\\top f(\\mathbf{x}^+) / \\tau + \\log\\big(\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big) \\Big] & \\scriptstyle{\\text{; Assuming infinite negatives}} \\\\\n&= -\\frac{1}{\\tau}\\mathbb{E}_{(\\mathbf{x},\\mathbf{x}^+)\\sim p_\\texttt{pos}}f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + \\mathbb{E}_{ \\mathbf{x} \\sim p_\\texttt{data}} \\Big[ \\log \\mathbb{E}_{\\mathbf{x}^- \\sim p_\\texttt{data}} \\big[ \\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}_i^-) / \\tau)\\big] \\Big] &\n\\end{aligned}\n$$\nKey Ingredients\n#\nHeavy Data Augmentation\n#\nGiven a training sample, data augmentation techniques are needed for creating noise versions of itself to feed into the loss as positive samples. Proper data augmentation setup is critical for learning good and generalizable embedding features. It introduces the non-essential variations into examples without modifying semantic meanings and thus encourages the model to learn the essential part of the representation. For example, experiments in\nSimCLR\nshowed that the composition of random cropping and random color distortion is crucial for good performance on learning visual representation of images.\nLarge Batch Size\n#\nUsing a large batch size during training is another key ingredient in the success of many contrastive learning methods (e.g.\nSimCLR\n,\nCLIP\n), especially when it relies on in-batch negatives. Only when the batch size is big enough, the loss function can cover a diverse enough collection of negative samples, challenging enough for the model to learn meaningful representation to distinguish different examples.\nHard Negative Mining\n#\nHard negative samples should have different labels from the anchor sample, but have embedding features very close to the anchor embedding. With access to ground truth labels in supervised datasets, it is easy to identify task-specific hard negatives. For example when learning sentence embedding, we can treat sentence pairs labelled as “contradiction” in NLI datasets as hard negative pairs (e.g.\nSimCSE\n, or use top incorrect candidates returned by BM25 with most keywords matched as hard negative samples (\nDPR\n;\nKarpukhin et al., 2020\n).\nHowever, it becomes tricky to do hard negative mining when we want to remain unsupervised. Increasing training batch size or\nmemory bank\nsize implicitly introduces more hard negative samples, but it leads to a heavy burden of large memory usage as a side effect.\nChuang et al. (2020)\nstudied the sampling bias in contrastive learning and proposed debiased loss. In the unsupervised setting, since we do not know the ground truth labels, we may accidentally sample false negative samples. Sampling bias can lead to significant performance drop.\nSampling bias which refers to false negative samples in contrastive learning can lead to a big performance drop. (Image source:\nChuang et al., 2020\n)\nLet us assume the probability of anchor class $c$ is uniform $\\rho(c)=\\eta^+$ and the probability of observing a different class is $\\eta^- = 1-\\eta^+$.\nThe probability of observing a positive example for $\\mathbf{x}$ is $p^+_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}=\\mathbf{h}_x)$;\nThe probability of getting a negative sample for $\\mathbf{x}$ is $p^-_x(\\mathbf{x}’)=p(\\mathbf{x}’\\vert \\mathbf{h}_{x’}\\neq\\mathbf{h}_x)$.\nWhen we are sampling $\\mathbf{x}^-$ , we cannot access the true $p^-_x(\\mathbf{x}^-)$ and thus $\\mathbf{x}^-$ may be sampled from the (undesired) anchor class $c$ with probability $\\eta^+$. The actual sampling data distribution becomes:\n$$\np(\\mathbf{x}') = \\eta^+ p^+_x(\\mathbf{x}') + \\eta^- p_x^-(\\mathbf{x}')\n$$\nThus we can use $p^-_x(\\mathbf{x}’) = (p(\\mathbf{x}’) - \\eta^+ p^+_x(\\mathbf{x}’))/\\eta^-$ for sampling $\\mathbf{x}^-$ to debias the loss. With $N$ samples $\\{\\mathbf{u}_i\\}^N_{i=1}$ from $p$ and $M$ samples $\\{ \\mathbf{v}_i \\}_{i=1}^M$ from $p^+_x$ , we can estimate the expectation of the second term $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ in the denominator of contrastive learning loss:\n$$\ng(\\mathbf{x}, \\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M) = \\max\\Big\\{ \\frac{1}{\\eta^-}\\Big( \\frac{1}{N}\\sum_{i=1}^N \\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}_i)) - \\frac{\\eta^+}{M}\\sum_{i=1}^M \\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}_i)) \\Big), \\exp(-1/\\tau) \\Big\\}\n$$\nwhere $\\tau$ is the temperature and $\\exp(-1/\\tau)$ is the theoretical lower bound of $\\mathbb{E}_{\\mathbf{x}^-\\sim p^-_x}[\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$.\nThe final debiased contrastive loss looks like:\n$$\n\\mathcal{L}^{N,M}_\\text{debias}(f) = \\mathbb{E}_{\\mathbf{x},\\{\\mathbf{u}_i\\}^N_{i=1}\\sim p;\\;\\mathbf{x}^+, \\{\\mathbf{v}_i\\}_{i=1}^M\\sim p^+} \\Big[ -\\log\\frac{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+)}{\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^+) + N g(x,\\{\\mathbf{u}_i\\}^N_{i=1}, \\{\\mathbf{v}_i\\}_{i=1}^M)} \\Big]\n$$\nt-SNE visualization of learned representation with debiased contrastive learning. (Image source:\nChuang et al., 2020\n)\nFollowing the above annotation,\nRobinson et al. (2021)\nmodified the sampling probabilities to target at hard negatives by up-weighting the probability $p^-_x(x’)$ to be proportional to its similarity to the anchor sample. The new sampling probability $q_\\beta(x^-)$ is:\n$$\nq_\\beta(\\mathbf{x}^-) \\propto \\exp(\\beta f(\\mathbf{x})^\\top f(\\mathbf{x}^-)) \\cdot p(\\mathbf{x}^-)\n$$\nwhere $\\beta$ is a hyperparameter to tune.\nWe can estimate the second term in the denominator $\\mathbb{E}_{\\mathbf{x}^- \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{x}^-))]$ using importance sampling where both the partition functions $Z_\\beta, Z^+_\\beta$ can be estimated empirically.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\mathbf{u} \\sim q_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] &= \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{q_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{u}))] = \\mathbb{E}_{\\mathbf{u} \\sim p} [\\frac{1}{Z_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{u}))] \\\\\n\\mathbb{E}_{\\mathbf{v} \\sim q^+_\\beta} [\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] &= \\mathbb{E}_{\\mathbf{v} \\sim p^+} [\\frac{q^+_\\beta}{p}\\exp(f(\\mathbf{x})^\\top f(\\mathbf{v}))] = \\mathbb{E}_{\\mathbf{v} \\sim p} [\\frac{1}{Z^+_\\beta}\\exp((\\beta + 1)f(\\mathbf{x})^\\top f(\\mathbf{v}))]\n\\end{aligned}\n$$\nPseudo code for computing NCE loss, debiased contrastive loss, and hard negative sample objective when setting $M=1$. (Image source:\nRobinson et al., 2021\n)\nVision: Image Embedding\n#\nImage Augmentations\n#\nMost approaches for contrastive representation learning in the vision domain rely on creating a noise version of a sample by applying a sequence of data augmentation techniques. The augmentation should significantly change its visual appearance but keep the semantic meaning unchanged.\nBasic Image Augmentation\n#\nThere are many ways to modify an image while retaining its semantic meaning. We can use any one of the following augmentation or a composition of multiple operations.\nRandom cropping and then resize back to the original size.\nRandom color distortions\nRandom Gaussian blur\nRandom color jittering\nRandom horizontal flip\nRandom grayscale conversion\nMulti-crop augmentation: Use two standard resolution crops and sample a set of additional low resolution crops that cover only small parts of the image. Using low resolution crops reduces the compute cost. (\nSwAV\n)\nAnd many more …\nAugmentation Strategies\n#\nMany frameworks are designed for learning good data augmentation strategies (i.e. a composition of multiple transforms). Here are a few common ones.\nAutoAugment\n(\nCubuk, et al. 2018\n): Inspired by\nNAS\n, AutoAugment frames the problem of learning best data augmentation operations (i.e. shearing, rotation, invert, etc.) for image classification as an RL problem and looks for the combination that leads to the highest accuracy on the evaluation set.\nRandAugment (\nCubuk et al., 2019\n): RandAugment greatly reduces the search space of AutoAugment by controlling the magnitudes of different transformation operations with a single magnitude parameter.\nPBA (Population based augmentation;\nHo et al., 2019\n): PBA combined PBT (\nJaderberg et al, 2017\n) with AutoAugment, using the evolutionary algorithm to train a population of children models in parallel to evolve the best augmentation strategies.\nUDA (Unsupervised Data Augmentation;\nXie et al., 2019\n): Among a set of possible augmentation strategies, UDA selects those to minimize the KL divergence between the predicted distribution over an unlabelled example and its unlabelled augmented version.\nImage Mixture\n#\nImage mixture methods can construct new training examples from existing data points.\nMixup (\nZhang et al., 2018\n): It runs global-level mixture by creating a weighted pixel-wise combination of two existing images $I_1$ and $I_2$: $I_\\text{mixup} \\gets \\alpha I_1 + (1-\\alpha) I_2$ and $\\alpha \\in [0, 1]$.\nCutmix (\nYun et al., 2019\n): Cutmix does region-level mixture by generating a new example by combining a local region of one image with the rest of the other image. $I_\\text{cutmix} \\gets \\mathbf{M}_b \\odot I_1 + (1-\\mathbf{M}_b) \\odot I_2$, where $\\mathbf{M}_b \\in \\{0, 1\\}^I$ is a binary mask and $\\odot$ is element-wise multiplication. It is equivalent to filling the cutout (\nDeVries & Taylor 2017\n) region with the same region from another image.\nMoCHi (“Mixing of Contrastive Hard Negatives”;\nKalantidis et al. 2020\n): Given a query $\\mathbf{q}$, MoCHi maintains a queue of $K$ negative features $Q=\\{\\mathbf{n}_1, \\dots, \\mathbf{n}_K \\}$ and sorts these negative features by similarity to the query, $\\mathbf{q}^\\top \\mathbf{n}$, in descending order. The first $N$ items in the queue are considered as the hardest negatives, $Q^N$. Then synthetic hard examples can be generated by $\\mathbf{h} = \\tilde{\\mathbf{h}} / |\\tilde{\\mathbf{h}}|$ where $\\tilde{\\mathbf{h}} = \\alpha\\mathbf{n}_i + (1-\\alpha) \\mathbf{n}_j$ and $\\alpha \\in (0, 1)$. Even harder examples can be created by mixing with the query feature, $\\mathbf{h}’ = \\tilde{\\mathbf{h}’} / |\\tilde{\\mathbf{h}’}|_2$ where $\\tilde{\\mathbf{h}’} = \\beta\\mathbf{q} + (1-\\beta) \\mathbf{n}_j$ and $\\beta \\in (0, 0.5)$.\nParallel Augmentation\n#\nThis category of approaches produce two noise versions of one anchor image and aim to learn representation such that these two augmented samples share the same embedding.\nSimCLR\n#\nSimCLR\n(\nChen et al, 2020\n) proposed a simple framework for contrastive learning of visual representations. It learns representations for visual inputs by maximizing agreement between differently augmented views of the same sample via a contrastive loss in the latent space.\nA simple framework for contrastive learning of visual representations. (Image source:\nChen et al, 2020\n)\nRandomly sample a minibatch of $N$ samples and each sample is applied with two different data augmentation operations, resulting in $2N$ augmented samples in total.\n$$\n\\tilde{\\mathbf{x}}_i = t(\\mathbf{x}),\\quad\\tilde{\\mathbf{x}}_j = t'(\\mathbf{x}),\\quad t, t' \\sim \\mathcal{T}\n$$\nwhere two separate data augmentation operators, $t$ and $t’$, are sampled from the same family of augmentations $\\mathcal{T}$. Data augmentation includes random crop, resize with random flip, color distortions, and Gaussian blur.\nGiven one positive pair, other $2(N-1)$ data points are treated as negative samples. The representation is produced by a base encoder $f(.)$:\n$$\n\\mathbf{h}_i = f(\\tilde{\\mathbf{x}}_i),\\quad \\mathbf{h}_j = f(\\tilde{\\mathbf{x}}_j)\n$$\nThe contrastive learning loss is defined using cosine similarity $\\text{sim}(.,.)$. Note that the loss operates on an extra projection layer of the representation $g(.)$ rather than on the representation space directly. But only the representation $\\mathbf{h}$ is used for downstream tasks.\n$$\n\\begin{aligned}\n\\mathbf{z}_i &= g(\\mathbf{h}_i),\\quad\n\\mathbf{z}_j = g(\\mathbf{h}_j) \\\\\n\\mathcal{L}_\\text{SimCLR}^{(i,j)} &= - \\log\\frac{\\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_j) / \\tau)}{\\sum_{k=1}^{2N} \\mathbb{1}_{[k \\neq i]} \\exp(\\text{sim}(\\mathbf{z}_i, \\mathbf{z}_k) / \\tau)}\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{[k \\neq i]}$ is an indicator function: 1 if $k\\neq i$ 0 otherwise.\nSimCLR needs a large batch size to incorporate enough negative samples to achieve good performance.\nThe algorithm for SimCLR. (Image source:\nChen et al, 2020\n).\nBarlow Twins\n#\nBarlow Twins\n(\nZbontar et al. 2021\n) feeds two distorted versions of samples into the same network to extract features and learns to make the\ncross-correlation matrix\nbetween these two groups of output features close to the identity. The goal is to keep the representation vectors of different distorted versions of one sample similar, while minimizing the redundancy between these vectors.\nIllustration of Barlow Twins learning pipeline. (Image source:\nZbontar et al. 2021\n).\nLet $\\mathcal{C}$ be a cross-correlation matrix computed between outputs from two identical networks along the batch dimension. $\\mathcal{C}$ is a square matrix with the size same as the feature network’s output dimensionality. Each entry in the matrix $\\mathcal{C}_{ij}$ is the cosine similarity between network output vector dimension at index $i, j$ and batch index $b$, $\\mathbf{z}_{b,i}^A$ and $\\mathbf{z}_{b,j}^B$, with a value between -1 (i.e. perfect anti-correlation) and 1 (i.e. perfect correlation).\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{BT} &= \\underbrace{\\sum_i (1-\\mathcal{C}_{ii})^2}_\\text{invariance term} + \\lambda \\underbrace{\\sum_i\\sum_{i\\neq j} \\mathcal{C}_{ij}^2}_\\text{redundancy reduction term} \\\\ \\text{where } \\mathcal{C}_{ij} &= \\frac{\\sum_b \\mathbf{z}^A_{b,i} \\mathbf{z}^B_{b,j}}{\\sqrt{\\sum_b (\\mathbf{z}^A_{b,i})^2}\\sqrt{\\sum_b (\\mathbf{z}^B_{b,j})^2}}\n\\end{aligned}\n$$\nBarlow Twins is competitive with SOTA methods for self-supervised learning. It naturally avoids trivial constants (i.e. collapsed representations), and is robust to different training batch sizes.\nAlgorithm of Barlow Twins in Pytorch style pseudo code. (Image source:\nZbontar et al. 2021\n).\nBYOL\n#\nDifferent from the above approaches, interestingly,\nBYOL\n(Bootstrap Your Own Latent;\nGrill, et al 2020\n) claims to achieve a new state-of-the-art results\nwithout using negative samples\n. It relies on two neural networks, referred to as\nonline\nand\ntarget\nnetworks that interact and learn from each other. The target network (parameterized by $\\xi$) has the same architecture as the online one (parameterized by $\\theta$), but with polyak averaged weights, $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe goal is to learn a presentation $y$ that can be used in downstream tasks. The online network parameterized by $\\theta$ contains:\nAn encoder $f_\\theta$;\nA projector $g_\\theta$;\nA predictor $q_\\theta$.\nThe target network has the same network architecture, but with different parameter $\\xi$, updated by polyak averaging $\\theta$: $\\xi \\leftarrow \\tau \\xi + (1-\\tau) \\theta$.\nThe model architecture of BYOL. After training, we only care about $f\\_\\theta$ for producing representation, $y=f\\_\\theta(x)$, and everything else is discarded. $\\text{sg}$ means stop gradient. (Image source:\nGrill, et al 2020\n)\nGiven an image $\\mathbf{x}$, the BYOL loss is constructed as follows:\nCreate two augmented views: $\\mathbf{v}=t(\\mathbf{x}); \\mathbf{v}’=t’(\\mathbf{x})$ with augmentations sampled $t \\sim \\mathcal{T}, t’ \\sim \\mathcal{T}’$;\nThen they are encoded into representations, $\\mathbf{y}_\\theta=f_\\theta(\\mathbf{v}), \\mathbf{y}’=f_\\xi(\\mathbf{v}’)$;\nThen they are projected into latent variables, $\\mathbf{z}_\\theta=g_\\theta(\\mathbf{y}_\\theta), \\mathbf{z}’=g_\\xi(\\mathbf{y}’)$;\nThe online network outputs a prediction $q_\\theta(\\mathbf{z}_\\theta)$;\nBoth $q_\\theta(\\mathbf{z}_\\theta)$ and $\\mathbf{z}’$ are L2-normalized, giving us $\\bar{q}_\\theta(\\mathbf{z}_\\theta) = q_\\theta(\\mathbf{z}_\\theta) / | q_\\theta(\\mathbf{z}_\\theta) |$ and $\\bar{\\mathbf{z}’} = \\mathbf{z}’ / |\\mathbf{z}’|$;\nThe loss $\\mathcal{L}^\\text{BYOL}_\\theta$ is MSE between L2-normalized prediction $\\bar{q}_\\theta(\\mathbf{z})$ and $\\bar{\\mathbf{z}’}$;\nThe other symmetric loss $\\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ can be generated by switching $\\mathbf{v}’$ and $\\mathbf{v}$; that is, feeding $\\mathbf{v}’$ to online network and $\\mathbf{v}$ to target network.\nThe final loss is $\\mathcal{L}^\\text{BYOL}_\\theta + \\tilde{\\mathcal{L}}^\\text{BYOL}_\\theta$ and only  parameters $\\theta$ are optimized.\nUnlike most popular contrastive learning based approaches, BYOL does not use negative pairs. Most bootstrapping approaches rely on pseudo-labels or cluster indices, but BYOL directly boostrapps the latent representation.\nIt is quite interesting and surprising that\nwithout\nnegative samples, BYOL still works well. Later I ran into this\npost\nby Abe Fetterman & Josh Albrecht, they highlighted two surprising findings while they were trying to reproduce BYOL:\nBYOL generally performs no better than random when\nbatch normalization is removed\n.\nThe presence of batch normalization implicitly causes a form of contrastive learning.\nThey believe that using negative samples is important for avoiding model collapse (i.e. what if you use all-zeros representation for every data point?). Batch normalization injects dependency on negative samples\ninexplicitly\nbecause no matter how similar a batch of inputs are, the values are re-distributed (spread out $\\sim \\mathcal{N}(0, 1$) and therefore batch normalization prevents model collapse. Strongly recommend you to read the\nfull article\nif you are working in this area.\nMemory Bank\n#\nComputing embeddings for a large number of negative samples in every batch is extremely expensive. One common approach is to store the representation in memory to trade off data staleness for cheaper compute.\nInstance Discrimination with Memoy Bank\n#\nInstance contrastive learning\n(\nWu et al, 2018\n) pushes the class-wise supervision to the extreme by considering each instance as\na distinct class of its own\n. It implies that the number of “classes” will be the same as the number of samples in the training dataset. Hence, it is unfeasible to train a softmax layer with these many heads, but instead it can be approximated by\nNCE\n.\nThe training pipeline of instance-level contrastive learning. The learned embedding is L2-normalized. (Image source:\nWu et al, 2018\n)\nLet $\\mathbf{v} = f_\\theta(x)$ be an embedding function to learn and the vector is normalized to have $|\\mathbf{v}|=1$. A non-parametric classifier predicts the probability of a sample $\\mathbf{v}$ belonging to class $i$ with a temperature parameter $\\tau$:\n$$\nP(C=i\\vert \\mathbf{v}) = \\frac{\\exp(\\mathbf{v}_i^\\top \\mathbf{v} / \\tau)}{\\sum_{j=1}^n \\exp(\\mathbf{v}_j^\\top \\mathbf{v} / \\tau)}\n$$\nInstead of computing the representations for all the samples every time, they implement an\nMemory Bank\nfor storing sample representation in the database from past iterations. Let $V=\\{ \\mathbf{v}_i \\}$ be the memory bank and $\\mathbf{f}_i = f_\\theta(\\mathbf{x}_i)$ be the feature generated by forwarding the network. We can use the representation from the memory bank $\\mathbf{v}_i$ instead of the feature forwarded from the network $\\mathbf{f}_i$ when comparing pairwise similarity.\nThe denominator theoretically requires access to the representations of all the samples, but that is too expensive in practice. Instead we can estimate it via Monte Carlo approximation using a random subset of $M$ indices $\\{j_k\\}_{k=1}^M$.\n$$\nP(i\\vert \\mathbf{v}) \n= \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\sum_{j=1}^N \\exp(\\mathbf{v}_j^\\top \\mathbf{f}_i / \\tau)}\n\\simeq \\frac{\\exp(\\mathbf{v}^\\top \\mathbf{f}_i / \\tau)}{\\frac{N}{M} \\sum_{k=1}^M \\exp(\\mathbf{v}_{j_k}^\\top \\mathbf{f}_i / \\tau)}\n$$\nBecause there is only one instance per class, the training is unstable and fluctuates a lot. To improve the training smoothness, they introduced an extra term for positive samples in the loss function based on the\nproximal optimization method\n. The final NCE loss objective looks like:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{instance} &= - \\mathbb{E}_{P_d}\\big[\\log h(i, \\mathbf{v}^{(t-1)}_i) - \\lambda \\|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i\\|^2_2\\big] - M\\mathbb{E}_{P_n}\\big[\\log(1 - h(i, \\mathbf{v}'^{(t-1)})\\big] \\\\\nh(i, \\mathbf{v}) &= \\frac{P(i\\vert\\mathbf{v})}{P(i\\vert\\mathbf{v}) + MP_n(i)} \\text{ where the noise distribution is uniform }P_n = 1/N\n\\end{aligned}\n$$\nwhere $\\{ \\mathbf{v}^{(t-1)} \\}$ are embeddings stored in the memory bank from the previous iteration. The difference between iterations $|\\mathbf{v}^{(t)}_i - \\mathbf{v}^{(t-1)}_i|^2_2$ will gradually vanish as the learned embedding converges.\nMoCo & MoCo-V2\n#\nMomentum Contrast\n(\nMoCo\n;\nHe et al, 2019\n) provides a framework of unsupervised learning visual representation as a\ndynamic dictionary look-up\n. The dictionary is structured as a large FIFO queue of encoded representations of data samples.\nGiven a query sample $\\mathbf{x}_q$, we get a query representation through an encoder $\\mathbf{q} = f_q(\\mathbf{x}_q)$. A list of key representations $\\{\\mathbf{k}_1, \\mathbf{k}_2, \\dots \\}$ in the dictionary are encoded by a momentum encoder $\\mathbf{k}_i = f_k (\\mathbf{x}^k_i)$. Let’s assume among them there is a single\npositive\nkey $\\mathbf{k}^+$ in the dictionary that matches $\\mathbf{q}$. In the paper, they create $\\mathbf{k}^+$ using a noise copy of $\\mathbf{x}_q$ with different\naugmentation\n. Then the\nInfoNCE\ncontrastive loss with temperature $\\tau$ is used over one positive and $N-1$ negative samples:\n$$\n\\mathcal{L}_\\text{MoCo} = - \\log \\frac{\\exp(\\mathbf{q} \\cdot \\mathbf{k}^+ / \\tau)}{\\sum_{i=1}^N \\exp(\\mathbf{q} \\cdot \\mathbf{k}_i / \\tau)}\n$$\nCompared to the\nmemory bank\n, a queue-based dictionary in MoCo enables us to reuse representations of immediately preceding mini-batches of data.\nThe MoCo dictionary is not differentiable as a queue, so we cannot rely on back-propagation to update the key encoder $f_k$. One naive way might be to use the same encoder for both $f_q$ and $f_k$. Differently, MoCo proposed to use a momentum-based update with a momentum coefficient $m \\in [0, 1)$. Say, the parameters of $f_q$ and $f_k$ are labeled as $\\theta_q$ and $\\theta_k$, respectively.\n$$\n\\theta_k \\leftarrow m \\theta_k + (1-m) \\theta_q\n$$\nIllustration of how Momentum Contrast (MoCo) learns visual representations. (Image source:\nHe et al, 2019\n)\nThe advantage of MoCo compared to\nSimCLR\nis that MoCo decouples the batch size from the number of negatives, but SimCLR requires a large batch size in order to have enough negative samples and suffers performance drops when their batch size is reduced.\nTwo designs in SimCLR, namely, (1) an MLP projection head and (2) stronger data augmentation, are proved to be very efficient.\nMoCo V2\n(\nChen et al, 2020\n) combined these two designs, achieving even better transfer performance with no dependency on a very large batch size.\nCURL\n#\nCURL\n(\nSrinivas, et al. 2020\n) applies the above ideas in\nReinforcement Learning\n. It learns a visual representation for RL tasks by matching embeddings of two data-augmented versions, $o_q$ and $o_k$, of the raw observation $o$ via contrastive loss. CURL primarily relies on random crop data augmentation. The key encoder is implemented as a momentum encoder with weights as EMA of the query encoder weights, same as in\nMoCo\n.\nOne significant difference between RL and supervised visual tasks is that RL depends on\ntemporal consistency\nbetween consecutive frames. Therefore, CURL applies augmentation consistently on each stack of frames to retain information about the temporal structure of the observation.\nThe architecture of CURL. (Image source:\nSrinivas, et al. 2020\n)\nFeature Clustering\n#\nDeepCluster\n#\nDeepCluster\n(\nCaron et al. 2018\n) iteratively clusters features via k-means and uses cluster assignments as pseudo labels to provide supervised signals.\nIllustration of DeepCluster method which iteratively clusters deep features and uses the cluster assignments as pseudo-labels. (Image source:\nCaron et al. 2018\n)\nIn each iteration, DeepCluster clusters data points using the prior representation and then produces the new cluster assignments as the classification targets for the new representation. However this iterative process is prone to trivial solutions. While avoiding the use of negative pairs, it requires a costly clustering phase and specific precautions to avoid collapsing to trivial solutions.\nSwAV\n#\nSwAV\n(\nSwapping Assignments between multiple Views\n;\nCaron et al. 2020\n) is an online contrastive learning algorithm. It computes a code from an augmented version of the image and tries to predict this code using another augmented version of the same image.\nComparison of SwAV and [contrastive instance learning](#instance-discrimination-with-memoy-bank). (Image source:\nCaron et al. 2020\n)\nGiven features of images with two different augmentations, $\\mathbf{z}_t$ and $\\mathbf{z}_s$, SwAV computes corresponding codes $\\mathbf{q}_t$ and $\\mathbf{q}_s$ and the loss quantifies the fit by swapping two codes using $\\ell(.)$ to measure the fit between a feature and a code.\n$$\n\\mathcal{L}_\\text{SwAV}(\\mathbf{z}_t, \\mathbf{z}_s) = \\ell(\\mathbf{z}_t, \\mathbf{q}_s) + \\ell(\\mathbf{z}_s, \\mathbf{q}_t)\n$$\nThe swapped fit prediction depends on the cross entropy between the predicted code and a set of $K$ trainable prototype vectors $\\mathbf{C} = \\{\\mathbf{c}_1, \\dots, \\mathbf{c}_K\\}$. The prototype vector matrix is shared across different batches and represents\nanchor clusters\nthat each instance should be clustered to.\n$$\n\\ell(\\mathbf{z}_t, \\mathbf{q}_s) = - \\sum_k \\mathbf{q}^{(k)}_s\\log\\mathbf{p}^{(k)}_t \\text{ where } \\mathbf{p}^{(k)}_t = \\frac{\\exp(\\mathbf{z}_t^\\top\\mathbf{c}_k  / \\tau)}{\\sum_{k'}\\exp(\\mathbf{z}_t^\\top \\mathbf{c}_{k'} / \\tau)}\n$$\nIn a mini-batch containing $B$ feature vectors $\\mathbf{Z} = [\\mathbf{z}_1, \\dots, \\mathbf{z}_B]$, the mapping matrix between features and prototype vectors is defined as $\\mathbf{Q} = [\\mathbf{q}_1, \\dots, \\mathbf{q}_B] \\in \\mathbb{R}_+^{K\\times B}$. We would like to maximize the similarity between the features and the prototypes:\n$$\n\\begin{aligned}\n\\max_{\\mathbf{Q}\\in\\mathcal{Q}} &\\text{Tr}(\\mathbf{Q}^\\top \\mathbf{C}^\\top \\mathbf{Z}) + \\varepsilon \\mathcal{H}(\\mathbf{Q}) \\\\\n\\text{where }\\mathcal{Q} &= \\big\\{ \\mathbf{Q} \\in \\mathbb{R}_{+}^{K \\times B} \\mid \\mathbf{Q}\\mathbf{1}_B = \\frac{1}{K}\\mathbf{1}_K, \\mathbf{Q}^\\top\\mathbf{1}_K = \\frac{1}{B}\\mathbf{1}_B \\big\\}\n\\end{aligned}\n$$\nwhere $\\mathcal{H}$ is the entropy, $\\mathcal{H}(\\mathbf{Q}) = - \\sum_{ij} \\mathbf{Q}_{ij} \\log \\mathbf{Q}_{ij}$, controlling the smoothness of the code. The coefficient $\\epsilon$ should not be too large; otherwise, all the samples will be assigned uniformly to all the clusters. The candidate set of solutions for $\\mathbf{Q}$ requires every mapping matrix to have each row sum up to $1/K$ and each column to sum up to $1/B$, enforcing that each prototype gets selected at least $B/K$ times on average.\nSwAV relies on the iterative Sinkhorn-Knopp algorithm (\nCuturi 2013\n) to find the solution for $\\mathbf{Q}$.\nWorking with Supervised Datasets\n#\nCLIP\n#\nCLIP\n(\nContrastive Language-Image Pre-training\n;\nRadford et al. 2021\n) jointly trains a text encoder and an image feature extractor over the pretraining task that predicts which caption goes with which image.\nIllustration of CLIP contrastive pre-training over text-image pairs. (Image source:\nRadford et al. 2021\n)\nGiven a batch of $N$ (image, text) pairs, CLIP computes the dense cosine similarity matrix between all $N\\times N$ possible (image, text) candidates within this batch. The text and image encoders are jointly trained to maximize the similarity between $N$ correct pairs of (image, text) associations while minimizing the similarity for $N(N-1)$ incorrect pairs via a symmetric cross entropy loss over the dense matrix.\nSee the numy-like pseudo code for CLIP in\nCLIP algorithm in Numpy style pseudo code. (Image source:\nRadford et al. 2021\n)\nCompared to other methods above for learning good visual representation, what makes CLIP really special is\n“the appreciation of using natural language as a training signal”\n. It does demand access to supervised dataset in which we know which text matches which image. It is trained on 400 million (text, image) pairs, collected from the Internet. The query list contains all the words occurring at least 100 times in the English version of Wikipedia. Interestingly, they found that Transformer-based language models are 3x slower than a bag-of-words (BoW) text encoder at zero-shot ImageNet classification. Using contrastive objective instead of trying to predict the exact words associated with images (i.e. a method commonly adopted by image caption prediction tasks) can further improve the data efficiency another 4x.\nUsing bag-of-words text encoding and contrastive training objectives can bring in multiple folds of data efficiency improvement. (Image source:\nRadford et al. 2021\n)\nCLIP produces good visual representation that can non-trivially transfer to many CV benchmark datasets, achieving results competitive with supervised baseline. Among tested transfer tasks, CLIP struggles with very fine-grained classification, as well as abstract or systematic tasks such as counting the number of objects. The transfer performance of CLIP models is smoothly correlated with the amount of model compute.\nSupervised Contrastive Learning\n#\nThere are several known issues with cross entropy loss, such as the lack of robustness to noisy labels and the possibility of poor margins. Existing improvement for cross entropy loss involves the curation of better training data, such as label smoothing and data augmentation.\nSupervised Contrastive Loss\n(\nKhosla et al. 2021\n) aims to leverage label information more effectively than cross entropy, imposing that normalized embeddings from the same class are closer together than embeddings from different classes.\nSupervised vs self-supervised contrastive losses. Supervised contrastive learning considers different samples from the same class as positive examples, in addition to augmented versions. (Image source:\nKhosla et al. 2021\n)\nGiven a set of randomly sampled $n$ (image, label) pairs, $\\{\\mathbf{x}_i, y_i\\}_{i=1}^n$, $2n$ training pairs can be created by applying two random augmentations of every sample, $\\{\\tilde{\\mathbf{x}}_i, \\tilde{y}_i\\}_{i=1}^{2n}$.\nSupervised contrastive loss $\\mathcal{L}_\\text{supcon}$ utilizes multiple positive and negative samples, very similar to\nsoft nearest-neighbor loss\n:\n$$\n\\mathcal{L}_\\text{supcon} = - \\sum_{i=1}^{2n} \\frac{1}{2 \\vert N_i \\vert - 1} \\sum_{j \\in N(y_i), j \\neq i} \\log \\frac{\\exp(\\mathbf{z}_i \\cdot \\mathbf{z}_j / \\tau)}{\\sum_{k \\in I, k \\neq i}\\exp({\\mathbf{z}_i \\cdot \\mathbf{z}_k / \\tau})}\n$$\nwhere $\\mathbf{z}_k=P(E(\\tilde{\\mathbf{x}_k}))$, in which $E(.)$ is an encoder network (augmented image mapped to vector) $P(.)$ is a projection network (one vector mapped to another). $N_i= \\{j \\in I: \\tilde{y}_j = \\tilde{y}_i \\}$ contains a set of indices of samples with label $y_i$. Including more positive samples into the set $N_i$ leads to improved results.\nAccording to their experiments, supervised contrastive loss:\ndoes outperform the base cross entropy, but only by a small amount.\noutperforms the cross entropy on robustness benchmark (ImageNet-C, which applies common naturally occuring perturbations such as noise, blur and contrast changes to the ImageNet dataset).\nis less sensitive to hyperparameter changes.\nLanguage: Sentence Embedding\n#\nIn this section, we focus on how to learn sentence embedding.\nText Augmentation\n#\nMost contrastive methods in vision applications depend on creating an augmented version of each image. However, it is more challenging to construct text augmentation which does not alter the semantics of a sentence.  In this section we look into three approaches for augmenting text sequences, including lexical edits, back-translation and applying cutoff or dropout.\nLexical Edits\n#\nEDA\n(\nEasy Data Augmentation\n;\nWei & Zou 2019\n) defines a set of simple but powerful operations for text augmentation. Given a sentence, EDA randomly chooses and applies one of four simple operations:\nSynonym replacement (SR): Replace $n$ random non-stop words with their synonyms.\nRandom insertion (RI): Place a random synonym of a randomly selected non-stop word in the sentence at a random position.\nRandom swap (RS): Randomly swap two words and repeat $n$ times.\nRandom deletion (RD): Randomly delete each word in the sentence with probability $p$.\nwhere $p=\\alpha$ and $n=\\alpha \\times \\text{sentence_length}$, with the intuition that longer sentences can absorb more noise while maintaining the original label. The hyperparameter $\\alpha$ roughly indicates the percent of words in one sentence that may be changed by one augmentation.\nEDA is shown to improve the classification accuracy on several classification benchmark datasets compared to baseline without EDA. The performance lift is more significant on a smaller training set. All the four operations in EDA help improve the classification accuracy, but get to optimal at different $\\alpha$’s.\nEDA leads to performance improvement on several classification benchmarks. (Image source:\nWei & Zou 2019\n)\nIn\nContextual Augmentation\n(\nSosuke Kobayashi, 2018\n), new substitutes for word $w_i$ at position $i$ can be smoothly sampled from a given probability distribution, $p(.\\mid S\\setminus\\{w_i\\})$, which is predicted by a bidirectional LM like BERT.\nBack-translation\n#\nCERT\n(\nContrastive self-supervised Encoder Representations from Transformers\n;\nFang et al. (2020)\n;\ncode\n) generates augmented sentences via\nback-translation\n. Various translation models for different languages can be employed for creating different versions of augmentations. Once we have a noise version of text samples, many contrastive learning frameworks introduced above, such as\nMoCo\n, can be used to learn sentence embedding.\nDropout and Cutoff\n#\nShen et al. (2020)\nproposed to apply\nCutoff\nto text augmentation, inspired by\ncross-view training\n. They proposed three cutoff augmentation strategies:\nToken cutoff\nremoves the information of a few selected tokens. To make sure there is no data leakage, corresponding tokens in the input, positional and other relevant embedding matrices should all be zeroed out.,\nFeature cutoff\nremoves a few feature columns.\nSpan cutoff\nremoves a continuous chunk of texts.\nSchematic illustration of token, feature and span cutoff augmentation strategies. (Image source:\nShen et al. 2020\n)\nMultiple augmented versions of one sample can be created. When training,\nShen et al. (2020)\napplied an additional KL-divergence term to measure the consensus between predictions from different augmented samples.\nSimCSE\n(\nGao et al. 2021\n;\ncode\n) learns from unsupervised data by predicting a sentence from itself with only\ndropout\nnoise. In other words, they treat dropout as data augmentation for text sequences. A sample is simply fed into the encoder twice with different dropout masks and these two versions are the positive pair where the other in-batch samples are considered as negative pairs. It feels quite similar to the cutoff augmentation, but dropout is more flexible with less well-defined semantic meaning of what content can be masked off.\nSimCSE creates augmented samples by applying different dropout masks. The supervised version leverages NLI datasets to predict positive (entailment) or negative (contradiction) given a pair of sentences. (Image source:\nGao et al. 2021\n)\nThey ran experiments on 7 STS (Semantic Text Similarity) datasets and computed cosine similarity between sentence embeddings.  They also tried out an optional MLM auxiliary objective loss to help avoid catastrophic forgetting of token-level knowledge. This aux loss was found to help improve performance on transfer tasks, but a consistent drop on the main STS tasks.\nExperiment numbers on a collection of STS benchmarks with SimCES. (Image source:\nGao et al. 2021\n)\nSupervision from NLI\n#\nThe pre-trained BERT sentence embedding without any fine-tuning has been found to have poor performance for semantic similarity tasks. Instead of using the raw embeddings directly, we need to refine the embedding with further fine-tuning.\nNatural Language Inference (NLI)\ntasks are the main data sources to provide supervised signals for learning sentence embedding; such as\nSNLI\n,\nMNLI\n, and\nQQP\n.\nSentence-BERT\n#\nSBERT (Sentence-BERT)\n(\nReimers & Gurevych, 2019\n) relies on siamese and triplet network architectures to learn sentence embeddings such that the sentence similarity can be estimated by cosine similarity between pairs of embeddings. Note that learning SBERT depends on supervised data, as it is fine-tuned on several NLI datasets.\nThey experimented with a few different prediction heads on top of BERT model:\nSoftmax classification objective: The classification head of the siamese network is built on the concatenation of two embeddings $f(\\mathbf{x}), f(\\mathbf{x}’)$ and $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$. The predicted output is $\\hat{y}=\\text{softmax}(\\mathbf{W}_t [f(\\mathbf{x}); f(\\mathbf{x}’); \\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert])$. They showed that the most important component is the element-wise difference $\\vert f(\\mathbf{x}) - f(\\mathbf{x}’) \\vert$.\nRegression objective: This is the regression loss on $\\cos(f(\\mathbf{x}), f(\\mathbf{x}’))$, in which the pooling strategy has a big impact. In the experiments, they observed that\nmax\nperforms much worse than\nmean\nand\nCLS\n-token.\nTriplet objective: $\\max(0, |f(\\mathbf{x}) - f(\\mathbf{x}^+)|- |f(\\mathbf{x}) - f(\\mathbf{x}^-)| + \\epsilon)$, where $\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-$ are embeddings of the anchor, positive and negative sentences.\nIn the experiments, which objective function works the best depends on the datasets, so there is no universal winner.\nIllustration of Sentence-BERT training framework with softmax classification head and regression head. (Image source:\nReimers & Gurevych, 2019\n)\nThe\nSentEval\nlibrary (\nConneau and Kiela, 2018\n) is commonly used for evaluating the quality of learned sentence embedding. SBERT outperformed other baselines at that time (Aug 2019) on 5 out of 7 tasks.\nThe performance of Sentence-BERT on the SentEval benchmark. (Image source:\nReimers & Gurevych, 2019\n)\nBERT-flow\n#\nThe embedding representation space is deemed\nisotropic\nif embeddings are uniformly distributed on each dimension; otherwise, it is\nanisotropic\n.\nLi et al, (2020)\nshowed that a pre-trained BERT learns a non-smooth\nanisotropic\nsemantic space of sentence embeddings and thus leads to poor performance for text similarity tasks without fine-tuning. Empirically, they observed two issues with BERT sentence embedding:\nWord frequency biases the embedding space. High-frequency words are close to the origin, but low-frequency ones are far away from the origin.\nLow-frequency words scatter sparsely. The embeddings of low-frequency words tend to be farther to their $k$-NN neighbors, while the embeddings of high-frequency words concentrate more densely.\nBERT-flow\n(\nLi et al, 2020\n;\ncode\n) was proposed to transform the embedding to a smooth and isotropic Gaussian distribution via\nnormalizing flows\n.\nIllustration of the flow-based calibration over the original sentence embedding space in BERT-flow. (Image source:\nLi et al, 2020\n)\nLet $\\mathcal{U}$ be the observed BERT sentence embedding space and $\\mathcal{Z}$ be the desired latent space which is a standard Gaussian. Thus, $p_\\mathcal{Z}$ is a Gaussian density function and $f_\\phi: \\mathcal{Z}\\to\\mathcal{U}$ is an invertible transformation:\n$$\n\\mathbf{z}\\sim p_\\mathcal{Z}(\\mathbf{z}) \\quad \n\\mathbf{u}=f_\\phi(\\mathbf{z}) \\quad\n\\mathbf{z}=f^{-1}_\\phi(\\mathbf{u}) \n$$\nA flow-based generative model learns the invertible mapping function by maximizing the likelihood of $\\mathcal{U}$’s marginal:\n$$\n\\max_\\phi\\mathbb{E}_{\\mathbf{u}=\\text{BERT}(s), s\\sim\\mathcal{D}} \\Big[ \\log p_\\mathcal{Z}(f^{-1}_\\phi(\\mathbf{u})) + \\log\\big\\vert\\det\\frac{\\partial f^{-1}_\\phi(\\mathbf{u})}{\\partial\\mathbf{u}}\\big\\vert \\Big]\n$$\nwhere $s$ is a sentence sampled from the text corpus $\\mathcal{D}$. Only the flow parameters $\\phi$ are optimized while parameters in the pretrained BERT stay unchanged.\nBERT-flow was shown to improve the performance on most STS tasks either with or without supervision from NLI datasets. Because learning normalizing flows for calibration does not require labels, it can utilize the entire dataset including validation and test sets.\nWhitening Operation\n#\nSu et al. (2021)\napplied\nwhitening\noperation to improve the\nisotropy\nof the learned representation and also to reduce the dimensionality of sentence embedding.\nThey transform the mean value of the sentence vectors to 0 and the covariance matrix to the identity matrix. Given a set of samples $\\{\\mathbf{x}_i\\}_{i=1}^N$, let $\\tilde{\\mathbf{x}}_i$ and $\\tilde{\\Sigma}$ be the transformed samples and corresponding covariance matrix:\n$$\n\\begin{aligned}\n\\mu &= \\frac{1}{N}\\sum_{i=1}^N \\mathbf{x}_i \\quad \\Sigma = \\frac{1}{N}\\sum_{i=1}^N (\\mathbf{x}_i - \\mu)^\\top (\\mathbf{x}_i - \\mu) \\\\\n\\tilde{\\mathbf{x}}_i &= (\\mathbf{x}_i - \\mu)W \\quad \\tilde{\\Sigma} = W^\\top\\Sigma W = I \\text{ thus } \\Sigma = (W^{-1})^\\top W^{-1}\n\\end{aligned}\n$$\nIf we get\nSVD\ndecomposition of $\\Sigma = U\\Lambda U^\\top$, we will have $W^{-1}=\\sqrt{\\Lambda} U^\\top$ and  $W=U\\sqrt{\\Lambda^{-1}}$. Note that within SVD, $U$ is an orthogonal matrix with column vectors as eigenvectors and $\\Lambda$ is a diagonal matrix with all positive elements as sorted eigenvalues.\nA dimensionality reduction strategy can be applied by only taking the first $k$ columns of $W$, named\nWhitening\n-$k$.\nPseudo code of the whitening-$k$ operation. (Image source:\nSu et al. 2021\n)\nWhitening operations were shown to outperform BERT-flow and achieve SOTA with 256 sentence dimensionality on many STS benchmarks, either with or without NLI supervision.\nUnsupervised Sentence Embedding Learning\n#\nContext Prediction\n#\nQuick-Thought (QT) vectors\n(\nLogeswaran & Lee, 2018\n) formulate sentence representation learning as a\nclassification\nproblem: Given a sentence and its context, a classifier distinguishes context sentences from other contrastive sentences based on their vector representations (\n“cloze test”\n). Such a formulation removes the softmax output layer which causes training slowdown.\nIllustration of how Quick-Thought sentence embedding vectors are learned. (Image source:\nLogeswaran & Lee, 2018\n)\nLet $f(.)$ and $g(.)$ be two functions that encode a sentence $s$ into a fixed-length vector. Let $C(s)$ be the set of sentences in the context of $s$ and $S(s)$ be the set of candidate sentences including only one sentence $s_c \\in C(s)$ and many other non-context negative sentences. Quick Thoughts model learns to optimize the probability of predicting the only true context sentence $s_c \\in S(s)$. It is essentially NCE loss when considering the sentence $(s, s_c)$ as the positive pairs while other pairs $(s, s’)$ where $s’ \\in S(s), s’\\neq s_c$ as negatives.\n$$\n\\mathcal{L}_\\text{QT} \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)} \\log p(s_c \\vert s, S(s)) \n= - \\sum_{s \\in \\mathcal{D}} \\sum_{s_c \\in C(s)}\\frac{\\exp(f(s)^\\top g(s_c))}{\\sum_{s'\\in S(s)} \\exp(f(s)^\\top g(s'))}\n$$\nMutual Information Maximization\n#\nIS-BERT (Info-Sentence BERT)\n(\nZhang et al. 2020\n;\ncode\n) adopts a self-supervised learning objective based on\nmutual information maximization\nto learn good sentence embeddings in the\nunsupervised\nmanners.\nIllustration of Info-Sentence BERT. (Image source:\nZhang et al. 2020\n)\nIS-BERT works as follows:\nUse BERT to encode an input sentence $s$ to a token embedding of length $l$, $\\mathbf{h}_{1:l}$.\nThen apply 1-D conv net with different kernel sizes (e.g. 1, 3, 5) to process the token embedding sequence to capture the n-gram local contextual dependencies: $\\mathbf{c}_i = \\text{ReLU}(\\mathbf{w} \\cdot \\mathbf{h}_{i:i+k-1} + \\mathbf{b})$. The output sequences are padded to stay the same sizes of the inputs.\nThe final local representation of the $i$-th token $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$ is the concatenation of representations of different kernel sizes.\nThe global sentence representation $\\mathcal{E}_\\theta(\\mathbf{x})$ is computed by applying a mean-over-time pooling layer on the token representations $\\mathcal{F}_\\theta(\\mathbf{x}) = \\{\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}) \\in \\mathbb{R}^d\\}_{i=1}^l$.\nSince the mutual information estimation is generally intractable for continuous and high-dimensional random variables, IS-BERT relies on the Jensen-Shannon estimator (\nNowozin et al., 2016\n,\nHjelm et al., 2019\n) to maximize the mutual information between $\\mathcal{E}_\\theta(\\mathbf{x})$ and $\\mathcal{F}_\\theta^{(i)} (\\mathbf{x})$.\n$$\nI^\\text{JSD}_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})) = \\mathbb{E}_{\\mathbf{x}\\sim P} [-\\text{sp}(-T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}); \\mathcal{E}_\\theta(\\mathbf{x})))] \\\\ - \\mathbb{E}_{\\mathbf{x}\\sim P, \\mathbf{x}' \\sim\\tilde{P}} [\\text{sp}(T_\\omega(\\mathcal{F}_\\theta^{(i)} (\\mathbf{x}'); \\mathcal{E}_\\theta(\\mathbf{x})))]\n$$\nwhere $T_\\omega: \\mathcal{F}\\times\\mathcal{E} \\to \\mathbb{R}$ is a learnable network with parameters $\\omega$, generating discriminator scores. The negative sample $\\mathbf{x}’$ is sampled from the distribution $\\tilde{P}=P$. And $\\text{sp}(x)=\\log(1+e^x)$ is the softplus activation function.\nThe unsupervised numbers on SentEval with IS-BERT outperforms most of the unsupervised baselines (Sep 2020), but unsurprisingly weaker than supervised runs. When using labelled NLI datasets, IS-BERT produces results comparable with SBERT (See Fig. 25 & 30).\nThe performance of IS-BERT on the SentEval benchmark. (Image source:\nZhang et al. 2020\n)\nCitation\n#\nCited as:\nWeng, Lilian. (May 2021). Contrastive representation learning. Lil’Log. https://lilianweng.github.io/posts/2021-05-31-contrastive/.\nOr\n@article{weng2021contrastive,\n  title   = \"Contrastive Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"May\",\n  url     = \"https://lilianweng.github.io/posts/2021-05-31-contrastive/\"\n}\nReferences\n#\n[1] Sumit Chopra, Raia Hadsell and Yann LeCun.\n“Learning a similarity metric discriminatively, with application to face verification.”\nCVPR 2005.\n[2] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering.”\nCVPR 2015.\n[3] Hyun Oh Song et al.\n“Deep Metric Learning via Lifted Structured Feature Embedding.”\nCVPR 2016. [\ncode\n]\n[4] Ruslan Salakhutdinov and Geoff Hinton.\n“Learning a Nonlinear Embedding by Preserving Class Neighbourhood Structure”\nAISTATS 2007.\n[5] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nAISTATS 2010.\n[6] Kihyuk Sohn et al.\n“Improved Deep Metric Learning with Multi-class N-pair Loss Objective”\nNIPS 2016.\n[7] Nicholas Frosst, Nicolas Papernot and Geoffrey Hinton.\n“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”\nICML 2019\n[8] Tongzhou Wang and Phillip Isola.\n“Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere.”\nICML 2020. [\ncode\n]\n[9] Zhirong Wu et al.\n“Unsupervised feature learning via non-parametric instance-level discrimination.”\nCVPR 2018.\n[10] Ekin D. Cubuk et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv preprint arXiv:1805.09501 (2018).\n[11] Daniel Ho et al.\n“Population Based Augmentation: Efficient Learning of Augmentation Policy Schedules.”\nICML 2019.\n[12] Ekin D. Cubuk & Barret Zoph et al.\n“RandAugment: Practical automated data augmentation with a reduced search space.”\narXiv preprint arXiv:1909.13719 (2019).\n[13] Hongyi Zhang et al.\n“mixup: Beyond Empirical Risk Minimization.”\nICLR 2017.\n[14] Sangdoo Yun et al.\n“CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features.”\nICCV 2019.\n[15] Yannis Kalantidis et al.\n“Mixing of Contrastive Hard Negatives”\nNeuriPS 2020.\n[16] Ashish Jaiswal et al.\n“A Survey on Contrastive Self-Supervised Learning.”\narXiv preprint arXiv:2011.00362 (2021)\n[17] Jure Zbontar et al.\n“Barlow Twins: Self-Supervised Learning via Redundancy Reduction.”\narXiv preprint arXiv:2103.03230 (2021) [\ncode\n]\n[18] Alec Radford, et al.\n“Learning Transferable Visual Models From Natural Language Supervision”\narXiv preprint arXiv:2103.00020 (2021)\n[19] Mathilde Caron et al.\n“Unsupervised Learning of Visual Features by Contrasting Cluster Assignments (SwAV).”\nNeuriPS 2020.\n[20] Mathilde Caron et al.\n“Deep Clustering for Unsupervised Learning of Visual Features.”\nECCV 2018.\n[21] Prannay Khosla et al.\n“Supervised Contrastive Learning.”\nNeurIPS 2020.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748 (2018).\n[23] Jason Wei and Kai Zou.\n“EDA: Easy data augmentation techniques for boosting performance on text classification tasks.”\nEMNLP-IJCNLP 2019.\n[24] Sosuke Kobayashi.\n“Contextual Augmentation: Data Augmentation by Words with Paradigmatic Relations.”\nNAACL 2018\n[25] Hongchao Fang et al.\n“CERT: Contrastive self-supervised learning for language understanding.”\narXiv preprint arXiv:2005.12766 (2020).\n[26] Dinghan Shen et al.\n“A Simple but Tough-to-Beat Data Augmentation Approach for Natural Language Understanding and Generation.”\narXiv preprint arXiv:2009.13818 (2020) [\ncode\n]\n[27] Tianyu Gao et al.\n“SimCSE: Simple Contrastive Learning of Sentence Embeddings.”\narXiv preprint arXiv:2104.08821 (2020). [\ncode\n]\n[28] Nils Reimers and Iryna Gurevych.\n“Sentence-BERT: Sentence embeddings using Siamese BERT-networks.”\nEMNLP 2019.\n[29] Jianlin Su et al.\n“Whitening sentence representations for better semantics and faster retrieval.”\narXiv preprint arXiv:2103.15316 (2021). [\ncode\n]\n[30] Yan Zhang et al.\n“An unsupervised sentence embedding method by mutual information maximization.”\nEMNLP 2020. [\ncode\n]\n[31] Bohan Li et al.\n“On the sentence embeddings from pre-trained language models.”\nEMNLP 2020.\n[32] Lajanugen Logeswaran and Honglak Lee.\n“An efficient framework for learning sentence representations.”\nICLR 2018.\n[33] Joshua Robinson, et al.\n“Contrastive Learning with Hard Negative Samples.”\nICLR 2021.\n[34] Ching-Yao Chuang et al.\n“Debiased Contrastive Learning.”\nNeuriPS 2020.",
            "metadata": {
              "title": "Contrastive Representation Learning | Lil'Log",
              "description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "keywords": "representation-learning, long-read, language-model, unsupervised-learning, data-augmentation",
              "author": "Lilian Weng",
              "og:title": "Contrastive Representation Learning",
              "og:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
              "twitter:card": "summary",
              "twitter:title": "Contrastive Representation Learning",
              "twitter:description": "The goal of contrastive representation learning is to learn such an embedding space in which similar sample pairs stay close to each other while dissimilar ones are far apart. Contrastive learning can be applied to both supervised and unsupervised settings. When working with unsupervised data, contrastive learning is one of the most powerful approaches in self-supervised learning.",
              "article:section": "posts",
              "article:published_time": "2021-05-31T00:00:00+00:00",
              "article:modified_time": "2021-05-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c8f3f2a59bb8/code/body-000.txt",
                "chars": 259,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "bytes": 82669,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-c8feb8e3831d6f407222.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/triplet-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "bytes": 238558,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-864616500d13b290a57d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/lifted-structured-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "bytes": 618000,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4d1eafbd2698e4b13414.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-sampling-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "bytes": 447800,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2202dbf059680ff25f64.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-debias-t-SNE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "bytes": 331316,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-56fdc531021fd8fc266d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/contrastive-hard-negatives-code.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "bytes": 92328,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-a3de29261702db65276c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "bytes": 292083,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fbb7be242e78cf4064e.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCLR-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "bytes": 165448,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7c6e570b2b4acaea53ee.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "bytes": 410905,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0dc7fb2e267a076918a0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/barlow-twins-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "bytes": 160971,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-64c06b583b29bc8d849d.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BYOL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "bytes": 575598,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-24abca83dac665bdfd2c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/instance-level-discrimination.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "bytes": 191327,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-68a57a589ced1a8dcbeb.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/MoCo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "bytes": 458778,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dec760a7d6d875b1e5f6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CURL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "bytes": 413067,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-3b05f2c9b09900dd678c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/deepcluster.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "bytes": 307781,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-9fe78703c0d6dd59901b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SwAV.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "bytes": 395407,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-bcffab9e56e403b12eb6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "bytes": 378369,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-14fc3bb2a028bd633430.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "bytes": 269518,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1cdb06387d4aabe19e7f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/CLIP-efficiency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "bytes": 1172082,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-dc3294612801cee60ee0.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/sup-con.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "bytes": 299081,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4ecf4ae1a9c6c75e0b98.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/EDA-exp1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "bytes": 102477,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-2f938fd27f3112a7668b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/text-cutoff.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "bytes": 302804,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-476b14449fa38214486c.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "bytes": 459618,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-d417f179aa932198443f.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SimCSE-STS-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "bytes": 248555,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-61290a159906f77df170.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "bytes": 263986,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-25636cdf26fe48bc32a6.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/SBERT-SentEval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "bytes": 127994,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-1f6149bb39a134da1e75.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/BERT-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "bytes": 167429,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-75a0434d42ea9e13e5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/whitening-SBERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "bytes": 235880,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-0873d959165b59705852.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/quick-thought.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "bytes": 403903,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-7fc9d0b8fcf86efd800b.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "bytes": 237372,
                "reused": false,
                "local_path": "attachments/c8f3f2a59bb8/images/body-4a85aecfe0dc34b27289.png",
                "src": "https://lilianweng.github.io/posts/2021-05-31-contrastive/IS-BERT-SentEval.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "label": "Chopra et al. 2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "Schroff et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06452",
                "label": "Song et al. 2015",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2016/hash/6b180037abbebea991d8b1232f8a8ca9-Abstract.html",
                "label": "Sohn 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a.html",
                "label": "Gutmann & Hyvarinen",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v2/salakhutdinov07a.html",
                "label": "Salakhutdinov & Hinton 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01889",
                "label": "Frosst et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.10242",
                "label": "Wang & Isola 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "DPR",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.00224",
                "label": "Chuang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.04592",
                "label": "Robinson et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "AutoAugment",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.05393",
                "label": "Ho et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.04899",
                "label": "Yun et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.04552",
                "label": "DeVries & Taylor 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.01028",
                "label": "Kalantidis et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.03230",
                "label": "Zbontar et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "Grill, et al 2020",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "Wu et al, 2018",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/~boyd/papers/prox_algs.html",
                "label": "proximal optimization method",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "He et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "Chen et al, 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "Srinivas, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.05520",
                "label": "Caron et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09882",
                "label": "Caron et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1306.0895",
                "label": "Cuturi 2013",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.00020",
                "label": "Radford et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.11362",
                "label": "Khosla et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11196",
                "label": "Wei & Zou 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.06201",
                "label": "Sosuke Kobayashi, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.12766",
                "label": "Fang et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/UCSD-AI4H/CERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.13818",
                "label": "Shen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "cross-view training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08821",
                "label": "Gao et al. 2021",
                "type": "a"
              },
              {
                "href": "https://github.com/princeton-nlp/SimCSE",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://cims.nyu.edu/~sbowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/c/quora-question-pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.10084",
                "label": "Reimers & Gurevych, 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/SentEval",
                "label": "SentEval",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.05449",
                "label": "Conneau and Kiela, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.05864",
                "label": "Li et al, (2020)",
                "type": "a"
              },
              {
                "href": "https://github.com/bohanli/BERT-flow",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.15316",
                "label": "Su et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Singular_value_decomposition",
                "label": "SVD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02893",
                "label": "Logeswaran & Lee, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.12061",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/yanzhangnlp/IS-BERT",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.00709",
                "label": "Nowozin et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.06670",
                "label": "Hjelm et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/rksltnl/Deep-Metric-Learning-CVPR16",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v97/frosst19a.html",
                "label": "“Analyzing and Improving Representations with the Soft Nearest Neighbor Loss.”",
                "type": "a"
              },
              {
                "href": "https://ssnl.github.io/hypersphere/",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978",
                "label": "“Unsupervised feature learning via non-parametric instance-level discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2011.00362",
                "label": "“A Survey on Contrastive Self-Supervised Learning.”",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/barlowtwins",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/dinghanshen/cutoff",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/bojone/BERT-whitening",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:20Z",
            "source_url": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
            "papers": [
              {
                "status": "ok",
                "url": "http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf",
                "bytes": 313804,
                "reused": false,
                "local_path": "papers/repair/84881b743b9447eb9afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": false,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06452",
                "bytes": 9011569,
                "reused": false,
                "local_path": "papers/repair/738c3f04b7e4d7dad3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": false,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01889",
                "bytes": 3823806,
                "reused": false,
                "local_path": "papers/repair/66ab4748bfca0238682e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.10242",
                "bytes": 4185717,
                "reused": false,
                "local_path": "papers/repair/8a0c585591f7f1918d90.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.00224",
                "bytes": 5343399,
                "reused": false,
                "local_path": "papers/repair/7dcaf70ed91e5defcf23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.04592",
                "bytes": 2199907,
                "reused": false,
                "local_path": "papers/repair/3f84b66b72f5c381c05a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": true,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.05393",
                "bytes": 873126,
                "reused": true,
                "local_path": "papers/repair/4634b6280b855d570ac8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": true,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": true,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.04899",
                "bytes": 1682836,
                "reused": true,
                "local_path": "papers/repair/fec62c4fe8efdeebd877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.04552",
                "bytes": 741919,
                "reused": true,
                "local_path": "papers/repair/c3d681ed19bf88f43a98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.01028",
                "bytes": 970998,
                "reused": true,
                "local_path": "papers/repair/d4d3c2412459021d347a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": false,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.03230",
                "bytes": 2434163,
                "reused": false,
                "local_path": "papers/repair/7f141d9ed4155ccf53f5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": false,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": false,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": false,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": false,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.05520",
                "bytes": 8629266,
                "reused": false,
                "local_path": "papers/repair/0a5b97b834b6a105dd9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09882",
                "bytes": 702914,
                "reused": false,
                "local_path": "papers/repair/0838c337bef6ccd33d62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1306.0895",
                "bytes": 1004298,
                "reused": false,
                "local_path": "papers/repair/598da2f78a40c9c822ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.00020",
                "bytes": 6813639,
                "reused": true,
                "local_path": "papers/repair/7db0b9244bb1fd42ae98.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.11362",
                "bytes": 2197586,
                "reused": false,
                "local_path": "papers/repair/a64eec551d692894bad9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11196",
                "bytes": 365049,
                "reused": true,
                "local_path": "papers/repair/389e34d78a0045e6d861.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.06201",
                "bytes": 722323,
                "reused": true,
                "local_path": "papers/repair/aebd3f77254c72e012a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.12766",
                "bytes": 412104,
                "reused": false,
                "local_path": "papers/repair/bae8e6b74f13390eb0a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.13818",
                "bytes": 398629,
                "reused": true,
                "local_path": "papers/repair/40a2d9b786e78e3cf30e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08821",
                "bytes": 1672580,
                "reused": true,
                "local_path": "papers/repair/e7a40652bdd04cd4b25f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.10084",
                "bytes": 548961,
                "reused": true,
                "local_path": "papers/repair/20151599fbbbabacaa9e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.05449",
                "bytes": 1257905,
                "reused": false,
                "local_path": "papers/repair/748bb3642ea0aef5571f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.05864",
                "bytes": 408978,
                "reused": false,
                "local_path": "papers/repair/3bfe284fc1ebd8a9d3a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.15316",
                "bytes": 659541,
                "reused": false,
                "local_path": "papers/repair/6e8262dafcfd96e9b679.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02893",
                "bytes": 232651,
                "reused": false,
                "local_path": "papers/repair/12ee892560b48ed47fb8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.12061",
                "bytes": 408861,
                "reused": false,
                "local_path": "papers/repair/5c6f2a504c1b0ff66969.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.00709",
                "bytes": 3615251,
                "reused": false,
                "local_path": "papers/repair/b555d3a1dac849208314.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.06670",
                "bytes": 4984410,
                "reused": false,
                "local_path": "papers/repair/ca0c4e18cba031b31bd0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978",
                "bytes": 4452342,
                "reused": false,
                "local_path": "papers/repair/2408633e99d87285a643.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2011.00362",
                "bytes": 5998084,
                "reused": false,
                "local_path": "papers/repair/20fd1312b2e030a81069.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 62279,
            "expected_body_images": 30,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c8f3f2a59bb8/pages/source.html",
            "local_html": "attachments/c8f3f2a59bb8/pages/article.html",
            "body_base_path": "attachments/c8f3f2a59bb8/pages/",
            "body_markdown_path": "attachments/c8f3f2a59bb8/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
          "status": "ok",
          "article_id": "76583c4985bd",
          "local_path": "series-follow/1601/repair/74bca82addbb696cd397.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
              "bytes": 77905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/22f8744911da963ff507.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
              "bytes": 83063,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2431b04e51e95d44cbfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
              "bytes": 147122,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3704ca968b8b036dd979.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
              "bytes": 449224,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/264593afb504dba40862.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
              "bytes": 270328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/fe1f57c36a0c6b35ff30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
              "bytes": 299310,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/686784e7314725fbdcc3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
              "bytes": 375554,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/abc3c1e68e088b944f70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
              "bytes": 278212,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/20f5ad7f538bcfcaa51f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
              "bytes": 3492681,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/09be84ee222f7edd8341.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
              "bytes": 340862,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/41918aaaac4a38312f21.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
              "bytes": 373018,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/151ce877219f628d821e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
              "bytes": 130110,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/52dcd8696c072fec5989.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
              "bytes": 519536,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/60ae1da08ae38b4e5477.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
              "bytes": 124124,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1f3e79d5973995850e17.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
              "bytes": 548196,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b8bdf2d20d1fcc25c810.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
              "bytes": 218342,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/015dfefe2091cea2d5d5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
              "bytes": 306334,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/de572b70c4267a43c66a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
              "bytes": 470728,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cf42d45d1104e492f130.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
              "bytes": 176722,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/452ce3c3d7e9a8712c06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
              "bytes": 411449,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9d2b0d8db4abe7b366db.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
            "keywords": "半监督学习,少数据,标注",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "publish_date": "2021-12",
            "corpus_stage": "数据处理",
            "notes": "半监督学习系列综述之一",
            "id": "76583c4985bd",
            "collected_at": "2026-10-02T14:13:01",
            "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
            "body_markdown": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.\nPre-training + fine-tuning\n: Pre-train a powerful task-agnostic model on a large unsupervised data corpus, e.g.\npre-training LMs\non free text, or pre-training vision models on unlabelled images via\nself-supervised learning\n, and then fine-tune it on the downstream task with a small set of labeled samples.\nSemi-supervised learning\n: Learn from the labelled and unlabeled samples together. A lot of research has happened on vision tasks within this approach.\nActive learning\n: Labeling is expensive, but we still want to collect more given a cost budget. Active learning learns to select most valuable unlabeled samples to be collected next and helps us act smartly with a limited budget.\nPre-training + dataset auto-generation\n: Given a capable pre-trained model, we can utilize it to auto-generate a lot more labeled samples. This has been especially popular within the language domain driven by the success of few-shot learning.\nI plan to write a series of posts on the topic of “Learning with not enough data”. Part 1 is on\nSemi-Supervised Learning\n.\nWhat is semi-supervised learning?\n#\nSemi-supervised learning uses both labeled and unlabeled data to train a model.\nInterestingly most existing literature on semi-supervised learning focuses on vision tasks. And instead pre-training + fine-tuning is a more common paradigm for language tasks.\nAll the methods introduced in this post have a loss combining two parts: $\\mathcal{L} = \\mathcal{L}_s +  \\mu(t) \\mathcal{L}_u$. The supervised loss $\\mathcal{L}_s$ is easy to get given all the labeled examples. We will focus on how the unsupervised loss $\\mathcal{L}_u$ is designed. A common choice of the weighting term $\\mu(t)$ is a ramp function increasing the importance of $\\mathcal{L}_u$ in time, where $t$ is the training step.\nDisclaimer\n: The post is not gonna cover semi-supervised methods with focus on model architecture modification. Check\nthis survey\nfor how to use generative models and graph-based methods in semi-supervised learning.\nNotations\n#\nSymbol\nMeaning\n$L$\nNumber of unique labels.\n$(\\mathbf{x}^l, y) \\sim \\mathcal{X}, y \\in \\{0, 1\\}^L$\nLabeled dataset. $y$ is a one-hot representation of the true label.\n$\\mathbf{u} \\sim \\mathcal{U}$\nUnlabeled dataset.\n$\\mathcal{D} = \\mathcal{X} \\cup \\mathcal{U}$\nThe entire dataset, including both labeled and unlabeled examples.\n$\\mathbf{x}$\nAny sample which can be either labeled or unlabeled.\n$\\bar{\\mathbf{x}}$\n$\\mathbf{x}$ with augmentation applied.\n$\\mathbf{x}_i$\nThe $i$-th sample.\n$\\mathcal{L}$, $\\mathcal{L}_s$, $\\mathcal{L}_u$\nLoss, supervised loss, and unsupervised loss.\n$\\mu(t)$\nThe unsupervised loss weight, increasing in time.\n$p(y \\vert \\mathbf{x}), p_\\theta(y \\vert \\mathbf{x})$\nThe conditional probability over the label set given the input.\n$f_\\theta(.)$\nThe implemented neural network with weights $\\theta$, the model that we want to train.\n$\\mathbf{z} = f_\\theta(\\mathbf{x})$\nA vector of logits output by $f$.\n$\\hat{y} = \\text{softmax}(\\mathbf{z})$\nThe predicted label distribution.\n$D[.,.]$\nA distance function between two distributions, such as MSE, cross entropy, KL divergence, etc.\n$\\beta$\nEMA weighting hyperparameter for\nteacher\nmodel weights.\n$\\alpha, \\lambda$\nParameters for MixUp, $\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)$.\n$T$\nTemperature for sharpening the predicted distribution.\n$\\tau$\nA confidence threshold for selecting the qualified prediction.\nHypotheses\n#\nSeveral hypotheses have been discussed in literature to support certain design decisions in semi-supervised learning methods.\nH1:\nSmoothness Assumptions\n: If two data samples are close in a high-density region of the feature space, their labels should be the same or very similar.\nH2:\nCluster Assumptions\n: The feature space has both dense regions and sparse regions. Densely grouped data points naturally form a cluster. Samples in the same cluster are expected to have the same label. This is a small extension of H1.\nH3:\nLow-density Separation Assumptions\n: The decision boundary between classes tends to be located in the sparse, low density regions, because otherwise the decision boundary would cut a high-density cluster into two classes, corresponding to two clusters, which invalidates H1 and H2.\nH4:\nManifold Assumptions\n: The high-dimensional data tends to locate on a low-dimensional manifold. Even though real-world data might be observed in very high dimensions (e.g. such as images of real-world objects/scenes), they actually can be captured by a lower dimensional manifold where certain attributes are captured and similar points are grouped closely (e.g. images of real-world objects/scenes are not drawn from a uniform distribution over all pixel combinations). This enables us to learn a more efficient representation for us to discover and measure similarity between unlabeled data points. This is also the foundation for representation learning. [see\na helpful link\n].\nConsistency Regularization\n#\nConsistency Regularization\n, also known as\nConsistency Training\n, assumes that randomness within the neural network (e.g. with Dropout) or data augmentation transformations should not modify model predictions given the same input. Every method in this section has a consistency regularization loss as $\\mathcal{L}_u$.\nThis idea has been adopted in several\nself-supervised\nlearning\nmethods, such as SimCLR, BYOL, SimCSE, etc. Different augmented versions of the same sample should result in the same representation.\nCross-view training\nin language modeling and multi-view learning in self-supervised learning all share the same motivation.\nΠ-model\n#\nOverview of the Π-model. Two versions of the same input with different stochastic augmentation and dropout masks pass through the network and the outputs are expected to be consistent. (Image source:\nLaine & Aila (2017)\n)\nSajjadi et al. (2016)\nproposed an unsupervised learning loss to minimize the difference between two passes through the network with stochastic transformations (e.g. dropout, random max-pooling) for the same data point. The label is not explicitly used, so the loss can be applied to unlabeled dataset.\nLaine & Aila (2017)\nlater coined the name,\nΠ-Model\n, for such a setup.\n$$\n\\mathcal{L}_u^\\Pi = \\sum_{\\mathbf{x} \\in \\mathcal{D}} \\text{MSE}(f_\\theta(\\mathbf{x}), f'_\\theta(\\mathbf{x}))\n$$\nwhere $f’$ is the same neural network with different stochastic augmentation or dropout masks applied. This loss utilizes the entire dataset.\nTemporal ensembling\n#\nOverview of Temporal Ensembling. The per-sample EMA label prediction is the learning target. (Image source:\nLaine & Aila (2017)\n)\nΠ-model requests the network to run two passes per sample, doubling the computation cost. To reduce the cost,\nTemporal Ensembling\n(\nLaine & Aila 2017\n) maintains an exponential moving average (EMA) of the model prediction in time per training sample $\\tilde{\\mathbf{z}}_i$ as the learning target, which is only evaluated and updated once per epoch. Because the ensemble output $\\tilde{\\mathbf{z}}_i$ is initialized to $\\mathbf{0}$, it is normalized by $(1-\\alpha^t)$ to correct this startup bias. Adam optimizer has such\nbias correction\nterms for the same reason.\n$$\n\\tilde{\\mathbf{z}}^{(t)}_i = \\frac{\\alpha \\tilde{\\mathbf{z}}^{(t-1)}_i + (1-\\alpha) \\mathbf{z}_i}{1-\\alpha^t}\n$$\nwhere $\\tilde{\\mathbf{z}}^{(t)}$ is the ensemble prediction at epoch $t$ and $\\mathbf{z}_i$ is the model prediction in the current round. Note that since $\\tilde{\\mathbf{z}}^{(0)} = \\mathbf{0}$, with correction, $\\tilde{\\mathbf{z}}^{(1)}$ is simply equivalent to $\\mathbf{z}_i$ at epoch 1.\nMean teachers\n#\nOverview of the Mean Teacher framework. (Image source:\nTarvaninen & Valpola, 2017\n)\nTemporal Ensembling keeps track of an EMA of label predictions for each training sample as a learning target. However, this label prediction only changes\nevery epoch\n, making the approach clumsy when the training dataset is large.\nMean Teacher\n(\nTarvaninen & Valpola, 2017\n) is proposed to overcome the slowness of target update by tracking the moving average of model weights instead of model outputs. Let’s call the original model with weights $\\theta$ as the\nstudent\nmodel and the model with moving averaged weights $\\theta’$ across consecutive student models as the\nmean teacher\n: $\\theta’ \\gets \\beta \\theta’ + (1-\\beta)\\theta$\nThe consistency regularization loss is the distance between predictions by the student and teacher and the student-teacher gap should be minimized. The mean teacher is expected to provide more accurate predictions than the student. It got confirmed in the empirical experiments, as shown in\nClassification error on SVHN of Mean Teacher and the Π Model. The mean teacher (in orange) has better performance than the student model (in blue). (Image source:\nTarvaninen & Valpola, 2017\n)\nAccording to their ablation studies,\nInput augmentation (e.g. random flips of input images, Gaussian noise) or student model dropout is necessary for good performance. Dropout is not needed on the teacher model.\nThe performance is sensitive to the EMA decay hyperparameter $\\beta$. A good strategy is to use a small $\\beta=0.99$ during the ramp up stage and a larger $\\beta=0.999$ in the later stage when the student model improvement slows down.\nThey found that MSE as the consistency cost function performs better than other cost functions like KL divergence.\nNoisy samples as learning targets\n#\nSeveral recent consistency training methods learn to minimize prediction difference between the original unlabeled sample and its corresponding augmented version. It is quite similar to the Π-model but the consistency regularization loss is\nonly\napplied to the unlabeled data.\nConsistency training with noisy samples.\nAdversarial Training (\nGoodfellow et al. 2014\n) applies adversarial noise onto the input and trains the model to be robust to such adversarial attack. The setup works in supervised learning,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{adv}(\\mathbf{x}^l, \\theta) &= D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[q(y\\mid \\mathbf{x}^l), p_\\theta(y\\mid \\mathbf{x}^l + r_\\text{adv})] \\\\\nr_\\text{adv} &\\approx \\epsilon \\frac{g}{\\|g\\|_2} \\approx \\epsilon\\text{sign}(g)\\quad\\text{where }g = \\nabla_{r} D[y, p_\\theta(y\\mid \\mathbf{x}^l + r)]\n\\end{aligned}\n$$\nwhere $q(y \\mid \\mathbf{x}^l)$ is the true distribution, approximated by one-hot encoding of the ground truth label, $y$. $p_\\theta(y \\mid \\mathbf{x}^l)$ is the model prediction. $D[.,.]$ is a distance function measuring the divergence between two distributions.\nVirtual Adversarial Training\n(\nVAT\n;\nMiyato et al. 2018\n) extends the idea to work in semi-supervised learning. Because $q(y \\mid \\mathbf{x}^l)$ is unknown, VAT replaces it with the current model prediction for the original input with the current weights $\\hat{\\theta}$.  Note that $\\hat{\\theta}$ is a fixed copy of model weights, so there is no gradient update on $\\hat{\\theta}$.\n$$\n\\begin{aligned}\n\\mathcal{L}_u^\\text{VAT}(\\mathbf{x}, \\theta) &= D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r_\\text{vadv})] \\\\\nr_\\text{vadv} &= {\\arg\\max}_{r; \\|r\\| \\leq \\epsilon} D[p_{\\hat{\\theta}}(y\\mid \\mathbf{x}), p_\\theta(y\\mid \\mathbf{x} + r)]\n\\end{aligned}\n$$\nThe VAT loss applies to both labeled and unlabeled samples. It is a negative smoothness measure of the current model’s prediction manifold at each data point. The optimization of such loss motivates the manifold to be smoother.\nInterpolation Consistency Training\n(\nICT\n;\nVerma et al. 2019\n) enhances the dataset by adding more interpolations of data points and expects the model prediction to be consistent with interpolations of the corresponding labels. MixUp (\nZheng et al. 2018\n) operation mixes two images via a simple weighted sum and combines it with label smoothing. Following the idea of MixUp, ICT expects the prediction model to produce a label on a mixup sample to match the interpolation of predictions of corresponding inputs:\n$$\n\\begin{aligned}\n\\text{mixup}_\\lambda (\\mathbf{x}_i, \\mathbf{x}_j) &= \\lambda \\mathbf{x}_i + (1-\\lambda)\\mathbf{x}_j \\\\\np(\\text{mixup}_\\lambda (y \\mid \\mathbf{x}_i, \\mathbf{x}_j)) &\\approx \\lambda p(y \\mid \\mathbf{x}_i) + (1-\\lambda) p(y \\mid \\mathbf{x}_j)\n\\end{aligned}\n$$\nwhere $\\theta’$ is a moving average of $\\theta$, which is a\nmean teacher\n.\nOverview of Interpolation Consistency Training. MixUp is applied to produce more interpolated samples with interpolated labels as learning targets. (Image source:\nVerma et al. 2019\n)\nBecause the probability of two randomly selected unlabeled samples belonging to different classes is high (e.g. There are 1000 object classes in ImageNet), the interpolation by applying a mixup between two random unlabeled samples is likely to happen around the decision boundary. According to the low-density separation\nassumptions\n, the decision boundary tends to locate in the low density regions.\n$$\n\\mathcal{L}^\\text{ICT}_{u} = \\mathbb{E}_{\\mathbf{u}_i, \\mathbf{u}_j \\sim \\mathcal{U}} \\mathbb{E}_{\\lambda \\sim \\text{Beta}(\\alpha, \\alpha)} D[p_\\theta(y \\mid \\text{mixup}_\\lambda (\\mathbf{u}_i, \\mathbf{u}_j)), \\text{mixup}_\\lambda(p_{\\theta’}(y \\mid \\mathbf{u}_i), p_{\\theta'}(y \\mid \\mathbf{u}_j)]\n$$\nwhere $\\theta’$ is a moving average of $\\theta$.\nSimilar to VAT,\nUnsupervised Data Augmentation\n(\nUDA\n;\nXie et al. 2020\n) learns to predict the same output for an unlabeled example and the augmented one. UDA especially focuses on studying how the\n“quality”\nof noise can impact the semi-supervised learning performance with consistency training. It is crucial to use advanced data augmentation methods for producing meaningful and effective noisy samples. Good data augmentation should produce valid (i.e. does not change the label) and diverse noise, and carry targeted inductive biases.\nFor images, UDA adopts RandAugment (\nCubuk et al. 2019\n) which uniformly samples augmentation operations available in\nPIL\n, no learning or optimization, so it is much cheaper than AutoAugment.\nComparison of various semi-supervised learning methods on CIFAR-10 classification. Fully supervised Wide-ResNet-28-2 and PyramidNet+ShakeDrop have an error rate of **5.4** and **2.7** respectively when trained on 50,000 examples without RandAugment. (Image source:\nXie et al. 2020\n)\nFor language, UDA combines back-translation and TF-IDF based word replacement. Back-translation preserves the high-level meaning but may not retain certain words, while TF-IDF based word replacement drops uninformative words with low TF-IDF scores. In the experiments on language tasks, they found UDA to be complementary to transfer learning and representation learning; For example, BERT fine-tuned (i.e. $\\text{BERT}_\\text{FINETUNE}$ in Fig. 8.) on in-domain unlabeled data can further improve the performance.\nComparison of UDA with different initialization configurations on various text classification tasks. (Image source:\nXie et al. 2020\n)\nWhen calculating $\\mathcal{L}_u$, UDA found two training techniques to help improve the results.\nLow confidence masking\n: Mask out examples with low prediction confidence if lower than a threshold $\\tau$.\nSharpening prediction distribution\n: Use a low temperature $T$ in softmax to sharpen the predicted probability distribution.\nIn-domain data filtration\n: In order to extract more in-domain data from a large out-of-domain dataset, they trained a classifier to predict in-domain labels and then retain samples with high confidence predictions as in-domain candidates.\n$$\n\\begin{aligned}\n&\\mathcal{L}_u^\\text{UDA} = \\mathbb{1}[\\max_{y'} p_{\\hat{\\theta}}(y'\\mid \\mathbf{x}) > \\tau ] \\cdot D[p^\\text{(sharp)}_{\\hat{\\theta}}(y \\mid \\mathbf{x}; T), p_\\theta(y \\mid \\bar{\\mathbf{x}})] \\\\\n&\\text{where } p_{\\hat{\\theta}}^\\text{(sharp)}(y \\mid \\mathbf{x}; T) = \\frac{\\exp(z^{(y)} / T)}{ \\sum_{y'} \\exp(z^{(y')} / T) }\n\\end{aligned}\n$$\nwhere $\\hat{\\theta}$ is a fixed copy of model weights, same as in VAT, so no gradient update, and $\\bar{\\mathbf{x}}$ is the augmented data point. $\\tau$ is the prediction confidence threshold and $T$ is the distribution sharpening temperature.\nPseudo Labeling\n#\nPseudo Labeling\n(\nLee 2013\n) assigns fake labels to unlabeled samples based on the maximum softmax probabilities predicted by the current model and then trains the model on both labeled and unlabeled samples simultaneously in a pure supervised setup.\nWhy could pseudo labels work? Pseudo label is in effect equivalent to\nEntropy Regularization\n(\nGrandvalet & Bengio 2004\n), which minimizes the conditional entropy of class probabilities for unlabeled data to favor low density separation between classes. In other words, the predicted class probabilities is in fact a measure of class overlap, minimizing the entropy is equivalent to reduced class overlap and thus low density separation.\nt-SNE visualization of outputs on MNIST test set by models training (a) without and (b) with pseudo labeling on 60000 unlabeled samples, in addition to 600 labeled data. Pseudo labeling leads to better segregation in the learned embedding space.  (Image source:\nLee 2013\n)\nTraining with pseudo labeling naturally comes as an iterative process. We refer to the model that produces pseudo labels as teacher and the model that learns with pseudo labels as student.\nLabel propagation\n#\nLabel Propagation\n(\nIscen et al. 2019\n) is an idea to construct a similarity graph among samples based on feature embedding. Then the pseudo labels are “diffused” from known samples to unlabeled ones where the propagation weights are proportional to pairwise similarity scores in the graph. Conceptually it is similar to a k-NN classifier and both suffer from the problem of not scaling up well with a large dataset.\nIllustration of how Label Propagation works. (Image source:\nIscen et al. 2019\n)\nSelf-Training\n#\nSelf-Training\nis not a new concept (\nScudder 1965\n,\nNigram & Ghani CIKM 2000\n). It is an iterative algorithm, alternating between the following two steps until every unlabeled sample has a label assigned:\nInitially it builds a classifier on labeled data.\nThen it uses this classifier to predict labels for the unlabeled data and converts the most confident ones into labeled samples.\nXie et al. (2020)\napplied self-training in deep learning and achieved great results. On the ImageNet classification task, they first trained an EfficientNet (\nTan & Le 2019\n) model as teacher to generate pseudo labels for 300M unlabeled images and then trained a larger EfficientNet as student to learn with both true labeled and pseudo labeled images. One critical element in their setup is to have\nnoise\nduring student model training but have no noise for the teacher to produce pseudo labels. Thus their method is called\nNoisy Student\n. They applied stochastic depth (\nHuang et al. 2016\n), dropout and RandAugment to noise the student. Noise is important for the student to perform better than the teacher. The added noise has a compound effect to encourage the model’s decision making frontier to be smooth, on both labeled and unlabeled data.\nA few other important technical configs in noisy student self-training are:\nThe student model should be sufficiently large (i.e. larger than the teacher) to fit more data.\nNoisy student should be paired with data balancing, especially important to balance the number of pseudo labeled images in each class.\nSoft pseudo labels work better than hard ones.\nNoisy student also improves adversarial robustness against an FGSM (Fast Gradient Sign Attack = The attack uses the gradient of the loss w.r.t the input data and adjusts the input data to maximize the loss) attack though the model is not optimized for adversarial robustness.\nSentAugment, proposed by\nDu et al. (2020)\n, aims to solve the problem when there is not enough in-domain unlabeled data for self-training in the language domain. It relies on sentence embedding to find unlabeled in-domain samples from a large corpus and uses the retrieved sentences for self-training.\nReducing confirmation bias\n#\nConfirmation bias is a problem with incorrect pseudo labels provided by an imperfect teacher model. Overfitting to wrong labels may not give us a better student model.\nTo reduce confirmation bias,\nArazo et al. (2019)\nproposed  two techniques. One is to adopt MixUp with soft labels. Given two samples, $(\\mathbf{x}_i, \\mathbf{x}_j)$ and their corresponding true or pseudo labels $(y_i, y_j)$, the interpolated label equation can be translated to a cross entropy loss with softmax outputs:\n$$\n\\begin{aligned}\n&\\bar{\\mathbf{x}} = \\lambda \\mathbf{x}_i + (1-\\lambda) \\mathbf{x}_j \\\\\n&\\bar{y} = \\lambda y_i + (1-\\lambda) y_j \\Leftrightarrow\n\\mathcal{L} = \\lambda [y_i^\\top \\log f_\\theta(\\bar{\\mathbf{x}})] + (1-\\lambda) [y_j^\\top \\log f_\\theta(\\bar{\\mathbf{x}})]\n\\end{aligned}\n$$\nMixup is insufficient if there are too few labeled samples. They further set a minimum number of labeled samples in every mini batch by oversampling the labeled samples. This works better than upweighting labeled samples, because it leads to more frequent updates rather than few updates of larger magnitude which could be less stable. Like consistency regularization, data augmentation and dropout are also important for pseudo labeling to work well.\nMeta Pseudo Labels\n(\nPham et al. 2021\n) adapts the teacher model constantly with the feedback of how well the student performs on the labeled dataset. The teacher and the student are trained in parallel, where the teacher learns to generate better pseudo labels and the student learns from the pseudo labels.\nLet the teacher and student model weights be $\\theta_T$ and $\\theta_S$, respectively. The student model’s loss on the labeled samples is defined as a function $\\theta^\\text{PL}_S(.)$ of $\\theta_T$ and we would like to minimize this loss by optimizing the teacher model accordingly.\n$$\n\\begin{aligned}\n\\min_{\\theta_T} &\\mathcal{L}_s(\\theta^\\text{PL}_S(\\theta_T)) = \\min_{\\theta_T} \\mathbb{E}_{(\\mathbf{x}^l, y) \\in \\mathcal{X}} \\text{CE}[y, f_{\\theta_S}(\\mathbf{x}^l)]  \\\\\n\\text{where } &\\theta^\\text{PL}_S(\\theta_T)\n= \\arg\\min_{\\theta_S} \\mathcal{L}_u (\\theta_T, \\theta_S)\n= \\arg\\min_{\\theta_S} \\mathbb{E}_{\\mathbf{u} \\sim \\mathcal{U}} \\text{CE}[(f_{\\theta_T}(\\mathbf{u}), f_{\\theta_S}(\\mathbf{u}))]\n\\end{aligned}\n$$\nHowever, it is not trivial to optimize the above equation. Borrowing the idea of\nMAML\n, it approximates the multi-step $\\arg\\min_{\\theta_S}$ with the one-step gradient update of $\\theta_S$,\n$$\n\\begin{aligned}\n\\theta^\\text{PL}_S(\\theta_T) &\\approx \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\\\\n\\min_{\\theta_T} \\mathcal{L}_s (\\theta^\\text{PL}_S(\\theta_T)) &\\approx \\min_{\\theta_T} \\mathcal{L}_s \\big( \\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S) \\big)\n\\end{aligned}\n$$\nWith soft pseudo labels, the above objective is differentiable. But if using hard pseudo labels, it is not differentiable and thus we need to use RL, e.g. REINFORCE.\nThe optimization procedure is alternative between training two models:\nStudent model update\n: Given a batch of unlabeled samples $\\{ \\mathbf{u} \\}$, we generate pseudo labels by $f_{\\theta_T}(\\mathbf{u})$ and optimize $\\theta_S$ with one step SGD: $\\theta’_S = \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)}$.\nTeacher model update\n: Given a batch of labeled samples $\\{(\\mathbf{x}^l, y)\\}$, we reuse the student’s update to optimize $\\theta_T$: $\\theta’_T = \\theta_T  - \\eta_T \\cdot \\nabla_{\\theta_T} \\mathcal{L}_s ( \\color{green}{\\theta_S - \\eta_S \\cdot \\nabla_{\\theta_S} \\mathcal{L}_u(\\theta_T, \\theta_S)} )$. In addition, the UDA objective is applied to the teacher model to incorporate consistency regularization.\nComparison of Meta Pseudo Labels with other semi- or self-supervised learning methods on image classification tasks. (Image source:\nPham et al. 2021\n)\nPseudo Labeling with Consistency Regularization\n#\nIt is possible to combine the above two approaches together, running semi-supervised learning with both pseudo labeling and consistency training.\nMixMatch\n#\nMixMatch\n(\nBerthelot et al. 2019\n), as a holistic approach to semi-supervised learning, utilizes unlabeled data by merging the following techniques:\nConsistency regularization\n: Encourage the model to output the same predictions on perturbed unlabeled samples.\nEntropy minimization\n: Encourage the model to output confident predictions on unlabeled data.\nMixUp\naugmentation: Encourage the model to have linear behaviour between samples.\nGiven a batch of labeled data $\\mathcal{X}$ and unlabeled data $\\mathcal{U}$, we create augmented versions of them via $\\text{MixMatch}(.)$, $\\bar{\\mathcal{X}}$ and $\\bar{\\mathcal{U}}$, containing augmented samples and guessed labels for unlabeled examples.\n$$\n\\begin{aligned}\n\\bar{\\mathcal{X}}, \\bar{\\mathcal{U}} &= \\text{MixMatch}(\\mathcal{X}, \\mathcal{U}, T, K, \\alpha) \\\\\n\\mathcal{L}^\\text{MM}_s &= \\frac{1}{\\vert \\bar{\\mathcal{X}} \\vert} \\sum_{(\\bar{\\mathbf{x}}^l, y)\\in \\bar{\\mathcal{X}}} D[y, p_\\theta(y \\mid \\bar{\\mathbf{x}}^l)] \\\\\n\\mathcal{L}^\\text{MM}_u &= \\frac{1}{L\\vert \\bar{\\mathcal{U}} \\vert} \\sum_{(\\bar{\\mathbf{u}}, \\hat{y})\\in \\bar{\\mathcal{U}}} \\| \\hat{y} - p_\\theta(y \\mid \\bar{\\mathbf{u}}) \\|^2_2 \\\\\n\\end{aligned}\n$$\nwhere $T$ is the sharpening temperature to reduce the guessed label overlap; $K$ is the number of augmentations generated per unlabeled example; $\\alpha$ is the parameter in MixUp.\nFor each $\\mathbf{u}$, MixMatch generates $K$ augmentations, $\\bar{\\mathbf{u}}^{(k)} = \\text{Augment}(\\mathbf{u})$ for $k=1, \\dots, K$ and the pseudo label is guessed based on the average: $\\hat{y} = \\frac{1}{K} \\sum_{k=1}^K p_\\theta(y \\mid \\bar{\\mathbf{u}}^{(k)})$.\nThe process of \"label guessing\" in MixMatch: averaging $K$ augmentations, correcting the predicted marginal distribution and finally sharpening the distribution. (Image source:\nBerthelot et al. 2019\n)\nAccording to their ablation studies, it is critical to have MixUp especially on the unlabeled data. Removing temperature sharpening on the pseudo label distribution hurts the performance quite a lot. Average over multiple augmentations for label guessing is also necessary.\nReMixMatch\n(\nBerthelot et al. 2020\n) improves MixMatch by introducing two new mechanisms:\nIllustration of two improvements introduced in ReMixMatch over MixMatch. (Image source:\nBerthelot et al. 2020\n)\nDistribution alignment.\nIt encourages the marginal distribution $p(y)$ to be close to the marginal distribution of the ground truth labels. Let $p(y)$ be the class distribution in the true labels and $\\tilde{p}(\\hat{y})$ be a running average of the predicted class distribution among the unlabeled data. The model prediction on an unlabeled sample $p_\\theta(y \\vert \\mathbf{u})$ is normalized to be $\\text{Normalize}\\big( \\frac{p_\\theta(y \\vert \\mathbf{u}) p(y)}{\\tilde{p}(\\hat{y})} \\big)$ to match the true marginal distribution.\nNote that entropy minimization is not a useful objective if the marginal distribution is not uniform.\nI do feel the assumption that the class distributions on the labeled and unlabeled data should match is too strong and not necessarily to be true in the real-world setting.\nAugmentation anchoring\n. Given an unlabeled sample, it first generates an “anchor” version with weak augmentation and then averages $K$ strongly augmented versions using CTAugment (Control Theory Augment). CTAugment only samples augmentations that keep the model predictions within the network tolerance.\nThe ReMixMatch loss is a combination of several terms,\na supervised loss with data augmentation and MixUp applied;\nan unsupervised loss with data augmentation and MixUp applied, using pseudo labels as targets;\na CE loss on a single heavily-augmented unlabeled image without MixUp;\na\nrotation\nloss as in self-supervised learning.\nDivideMix\n#\nDivideMix\n(\nJunnan Li et al. 2020\n) combines semi-supervised learning with Learning with noisy labels (LNL). It models the per-sample loss distribution via a\nGMM\nto dynamically divide the training data into a labeled set with clean examples and an unlabeled set with noisy ones. Following the idea in\nArazo et al. 2019\n, they fit a two-component GMM on the per-sample cross entropy loss $\\ell_i = y_i^\\top \\log f_\\theta(\\mathbf{x}_i)$. Clean samples are expected to get lower loss faster than noisy samples. The component with smaller mean is the cluster corresponding to clean labels and let’s denote it as $c$. If the GMM posterior probability $w_i = p_\\text{GMM}(c \\mid \\ell_i)$ (i.e. the probability of the sampling belonging to the clean sample set) is larger than the threshold $\\tau$, this sample is considered as a clean sample and otherwise a noisy one.\nThe data clustering step is named\nco-divide\n. To avoid confirmation bias, DivideMix simultaneously trains two diverged networks where each network uses the dataset division from the other network; e.g. thinking about how Double Q Learning works.\nDivideMix trains two networks independently to reduce confirmation bias. They run co-divide, co-refinement, and co-guessing together. (Image source:\nJunnan Li et al. 2020\n)\nCompared to MixMatch, DivideMix has an additional\nco-divide\nstage for handling noisy samples, as well as the following improvements during training:\nLabel co-refinement\n: It linearly combines the ground-truth label $y_i$ with the network’s prediction $\\hat{y}_i$, which is averaged across multiple augmentations of $\\mathbf{x}_i$, guided by the clean set probability $w_i$ produced by the other network.\nLabel co-guessing\n: It averages the predictions from two models for unlabelled data samples.\nThe algorithm of DivideMix. (Image source:\nJunnan Li et al. 2020\n)\nFixMatch\n#\nFixMatch\n(\nSohn et al. 2020\n) generates pseudo labels on unlabeled samples with weak augmentation and only keeps predictions with high confidence. Here both weak augmentation and high confidence filtering help produce high-quality trustworthy pseudo label targets. Then FixMatch learns to predict these pseudo labels given a heavily-augmented sample.\nIllustration of how FixMatch works. (Image source:\nSohn et al. 2020\n)\n$$\n\\begin{aligned}\n\\mathcal{L}_s &= \\frac{1}{B} \\sum^B_{b=1} \\text{CE}[y_b, p_\\theta(y \\mid \\mathcal{A}_\\text{weak}(\\mathbf{x}_b))] \\\\\n\\mathcal{L}_u &= \\frac{1}{\\mu B} \\sum_{b=1}^{\\mu B} \\mathbb{1}[\\max(\\hat{y}_b) \\geq \\tau]\\;\\text{CE}(\\hat{y}_b, p_\\theta(y \\mid \\mathcal{A}_\\text{strong}(\\mathbf{u}_b)))\n\\end{aligned}\n$$\nwhere $\\hat{y}_b$ is the pseudo label for an unlabeled example; $\\mu$ is a hyperparameter that determines the relative sizes of $\\mathcal{X}$ and $\\mathcal{U}$.\nWeak augmentation $\\mathcal{A}_\\text{weak}(.)$: A standard flip-and-shift augmentation\nStrong augmentation $\\mathcal{A}_\\text{strong}(.)$ : AutoAugment, Cutout, RandAugment, CTAugment\nPerformance of FixMatch and several other semi-supervised learning methods on image classification tasks. (Image source:\nSohn et al. 2020\n)\nAccording to the ablation studies of FixMatch,\nSharpening the predicted distribution with a temperature parameter $T$ does not have a significant impact when the threshold $\\tau$ is used.\nCutout and CTAugment as part of strong augmentations are necessary for good performance.\nWhen the weak augmentation for label guessing is replaced with strong augmentation, the model diverges early in training. If discarding weak augmentation completely, the model overfit the guessed labels.\nUsing weak instead of strong augmentation for pseudo label prediction leads to unstable performance. Strong data augmentation is critical.\nCombined with Powerful Pre-Training\n#\nIt is a common paradigm, especially in language tasks, to first pre-train a task-agnostic model on a large unsupervised data corpus via self-supervised learning and then fine-tune it on the downstream task with a small labeled dataset. Research has shown that we can obtain extra gain if combining semi-supervised learning with pretraining.\nZoph et al. (2020)\nstudied to what degree\nself-training\ncan work better than pre-training. Their experiment setup was to use ImageNet for pre-training or self-training to improve COCO. Note that when using ImageNet for self-training, it discards labels and only uses ImageNet samples as unlabeled data points.\nHe et al. (2018)\nhas demonstrated that ImageNet classification pre-training does not work well if the downstream task is very different, such as object detection.\nThe effect of (a) data augment (from weak to strong) and (b) the labeled dataset size on the object detection performance. In the legend: `Rand Init` refers to a model initialized w/ random weights; `ImageNet` is initialized with a pre-trained checkpoint at 84.5% top-1 ImageNet accuracy; `ImageNet++` is initialized with a checkpoint with a higher accuracy 86.9%. (Image source:\nZoph et al. 2020\n)\nTheir experiments demonstrated a series of interesting findings:\nThe effectiveness of pre-training diminishes with more labeled samples available for the downstream task. Pre-training is helpful in the low-data regimes (20%) but neutral or harmful in the high-data regime.\nSelf-training helps in high data/strong augmentation regimes, even when pre-training hurts.\nSelf-training can bring in additive improvement on top of pre-training, even using the same data source.\nSelf-supervised pre-training (e.g. via SimCLR) hurts the performance in a high data regime, similar to how supervised pre-training does.\nJoint-training supervised and self-supervised objectives help resolve the mismatch between the pre-training and downstream tasks. Pre-training, joint-training and self-training are all additive.\nNoisy labels or un-targeted labeling (i.e. pre-training labels are not aligned with downstream task labels) is worse than targeted pseudo labeling.\nSelf-training is computationally more expensive than fine-tuning on a pre-trained model.\nChen et al. (2020)\nproposed a three-step procedure to merge the benefits of self-supervised pretraining, supervised fine-tuning and self-training together:\nUnsupervised or self-supervised pretrain a big model.\nSupervised fine-tune it on a few labeled examples. It is important to use a big (deep and wide) neural network.\nBigger models yield better performance with fewer labeled samples.\nDistillation with unlabeled examples by adopting pseudo labels in self-training.\nIt is possible to distill the knowledge from a large model into a small one because the task-specific use does not require extra capacity of the learned representation.\nThe distillation loss is formatted as the following, where the teacher network is fixed with weights $\\hat{\\theta}_T$.\n$$\n     \\mathcal{L}_\\text{distill} = - (1-\\alpha) \\underbrace{\\sum_{(\\mathbf{x}^l_i, y_i) \\in \\mathcal{X}} \\big[ \\log p_{\\theta_S}(y_i \\mid \\mathbf{x}^l_i) \\big]}_\\text{Supervised loss} - \\alpha \\underbrace{\\sum_{\\mathbf{u}_i \\in \\mathcal{U}} \\Big[ \\sum_{i=1}^L p_{\\hat{\\theta}_T}(y^{(i)} \\mid \\mathbf{u}_i; T) \\log p_{\\theta_S}(y^{(i)} \\mid \\mathbf{u}_i; T) \\Big]}_\\text{Distillation loss using unlabeled data}\n     $$\nA semi-supervised learning framework leverages unlabeled data corpus by (Left) task-agnostic unsupervised pretraining and (Right) task-specific self-training and distillation. (Image source:\nChen et al. 2020\n)\nThey experimented on the ImageNet classification task. The self-supervised pre-training uses SimCLRv2, a directly improved version of\nSimCLR\n. Observations in their empirical studies confirmed several learnings, aligned with\nZoph et al. 2020\n:\nBigger models are more label-efficient;\nBigger/deeper project heads in SimCLR improve representation learning;\nDistillation using unlabeled data improves semi-supervised learning.\nComparison of performance by SimCLRv2 + semi-supervised distillation on ImageNet classification. (Image source:\nChen et al. 2020\n)\n💡 Quick summary of common themes among recent semi-supervised learning methods, many aiming to reduce confirmation bias:\nApply valid and diverse noise to samples by advanced data augmentation methods.\nWhen dealing with images, MixUp is an effective augmentation. Mixup could work on language too, resulting in a small incremental improvement (\nGuo et al. 2019\n).\nSet a threshold and discard pseudo labels with low confidence.\nSet a minimum number of labeled samples per mini-batch.\nSharpen the pseudo label distribution to reduce the class overlap.\nCitation\n#\nCited as:\nWeng, Lilian. (Dec 2021). Learning with not enough data part 1: semi-supervised learning. Lil’Log. https://lilianweng.github.io/posts/2021-12-05-semi-supervised/.\nOr\n@article{weng2021semi,\n  title   = \"Learning with not Enough Data Part 1: Semi-Supervised Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Dec\",\n  url     = \"https://lilianweng.github.io/posts/2021-12-05-semi-supervised/\"\n}\nReferences\n#\n[1] Ouali, Hudelot & Tami.\n“An Overview of Deep Semi-Supervised Learning”\narXiv preprint arXiv:2006.05278 (2020).\n[2] Sajjadi, Javanmardi & Tasdizen\n“Regularization With Stochastic Transformations and Perturbations for Deep Semi-Supervised Learning.”\narXiv preprint arXiv:1606.04586 (2016).\n[3] Pham et al.\n“Meta Pseudo Labels.”\nCVPR 2021.\n[4] Laine & Aila.\n“Temporal Ensembling for Semi-Supervised Learning”\nICLR 2017.\n[5] Tarvaninen & Valpola.\n“Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results.”\nNeuriPS 2017\n[6] Xie et al.\n“Unsupervised Data Augmentation for Consistency Training.”\nNeuriPS 2020.\n[7] Miyato et al.\n“Virtual Adversarial Training: A Regularization Method for Supervised and Semi-Supervised Learning.”\nIEEE transactions on pattern analysis and machine intelligence 41.8 (2018).\n[8] Verma et al.\n“Interpolation consistency training for semi-supervised learning.”\nIJCAI 2019\n[9] Lee.\n“Pseudo-label: The simple and efficient semi-supervised learning method for deep neural networks.”\nICML 2013 Workshop: Challenges in Representation Learning.\n[10] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019.\n[11] Xie et al.\n“Self-training with Noisy Student improves ImageNet classification”\nCVPR 2020.\n[12] Jingfei Du et al.\n“Self-training Improves Pre-training for Natural Language Understanding.”\n2020\n[13] Iscen et al.\n“Label propagation for deep semi-supervised learning.”\nCVPR 2019\n[14] Arazo et al.\n“Pseudo-labeling and confirmation bias in deep semi-supervised learning.”\nIJCNN 2020.\n[15] Berthelot et al.\n“MixMatch: A holistic approach to semi-supervised learning.”\nNeuriPS 2019\n[16] Berthelot et al.\n“ReMixMatch: Semi-supervised learning with distribution alignment and augmentation anchoring.”\nICLR 2020\n[17] Sohn et al.\n“FixMatch: Simplifying semi-supervised learning with consistency and confidence.”\nCVPR 2020\n[18] Junnan Li et al.\n“DivideMix: Learning with Noisy Labels as Semi-supervised Learning.”\n2020 [\ncode\n]\n[19] Zoph et al.\n“Rethinking pre-training and self-training.”\n2020.\n[20] Chen et al.\n“Big Self-Supervised Models are Strong Semi-Supervised Learners”\n2020",
            "metadata": {
              "title": "Learning with not Enough Data Part 1: Semi-Supervised Learning | Lil'Log",
              "description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "keywords": "data, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "og:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
              "twitter:card": "summary",
              "twitter:title": "Learning with not Enough Data Part 1: Semi-Supervised Learning",
              "twitter:description": "When facing a limited amount of labeled data for supervised learning tasks, four approaches are commonly discussed.",
              "article:section": "posts",
              "article:published_time": "2021-12-05T00:00:00+00:00",
              "article:modified_time": "2021-12-05T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/76583c4985bd/code/body-000.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "bytes": 77905,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-22f8744911da963ff507.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/PI-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "bytes": 83063,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-2431b04e51e95d44cbfc.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/temperal-ensembling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "bytes": 147122,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-3704ca968b8b036dd979.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "bytes": 449224,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-264593afb504dba40862.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/mean-teacher-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "bytes": 270328,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-fe1f57c36a0c6b35ff30.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/consistency-training-with-noisy-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "bytes": 299310,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-686784e7314725fbdcc3.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ICT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "bytes": 375554,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-abc3c1e68e088b944f70.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-image-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "bytes": 278212,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-20f5ad7f538bcfcaa51f.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/UDA-language-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "bytes": 3492681,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-09be84ee222f7edd8341.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/pseudo-label-segregation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "bytes": 340862,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-41918aaaac4a38312f21.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/label-propagation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "bytes": 373018,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-151ce877219f628d821e.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MPL-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "bytes": 130110,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-52dcd8696c072fec5989.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/MixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "bytes": 519536,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-60ae1da08ae38b4e5477.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/ReMixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "bytes": 124124,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-1f3e79d5973995850e17.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "bytes": 548196,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-b8bdf2d20d1fcc25c810.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/DivideMix-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "bytes": 218342,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-015dfefe2091cea2d5d5.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "bytes": 306334,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-de572b70c4267a43c66a.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/FixMatch-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "bytes": 470728,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-cf42d45d1104e492f130.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/self-training-pre-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "bytes": 176722,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-452ce3c3d7e9a8712c06.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "bytes": 411449,
                "reused": false,
                "local_path": "attachments/76583c4985bd/images/body-9d2b0d8db4abe7b366db.png",
                "src": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/big-self-supervised-model-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "pre-training LMs",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.05278",
                "label": "this survey",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/66939/what-is-the-manifold-assumption-in-semi-supervised-learning",
                "label": "a helpful link",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02242",
                "label": "Laine & Aila (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04586",
                "label": "Sajjadi et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://stats.stackexchange.com/questions/232741/why-is-it-important-to-include-a-bias-correction-term-for-the-adam-optimizer-for",
                "label": "bias correction",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01780",
                "label": "Tarvaninen & Valpola, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6572",
                "label": "Goodfellow et al. 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03976",
                "label": "Miyato et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1903.03825",
                "label": "Verma et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.09412",
                "label": "Zheng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.12848",
                "label": "Xie et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.13719",
                "label": "Cubuk et al. 2019",
                "type": "a"
              },
              {
                "href": "https://pillow.readthedocs.io/en/stable/",
                "label": "PIL",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.664.3543&rep=rep1&type=pdf",
                "label": "Lee 2013",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2004/hash/96f2b50b5d3613adf9c27049b2a888c7-Abstract.html",
                "label": "Grandvalet & Bengio 2004",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04717",
                "label": "Iscen et al. 2019",
                "type": "a"
              },
              {
                "href": "https://ieeexplore.ieee.org/document/1053799",
                "label": "Scudder 1965",
                "type": "a"
              },
              {
                "href": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "label": "Nigram & Ghani CIKM 2000",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.04252",
                "label": "Xie et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.11946",
                "label": "Tan & Le 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09382",
                "label": "Huang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2010.02194",
                "label": "Du et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.02983",
                "label": "Arazo et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10580",
                "label": "Pham et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.02249",
                "label": "Berthelot et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.09785",
                "label": "Berthelot et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.07394",
                "label": "Junnan Li et al. 2020",
                "type": "a"
              },
              {
                "href": "https://scikit-learn.org/stable/modules/mixture.html",
                "label": "GMM",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11238",
                "label": "Arazo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.07685",
                "label": "Sohn et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.06882",
                "label": "Zoph et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "He et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10029",
                "label": "Chen et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.08941",
                "label": "Guo et al. 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/LiJunnan1992/DivideMix",
                "label": "code",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:21Z",
            "source_url": "https://lilianweng.github.io/posts/2021-12-05-semi-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.05278",
                "bytes": 3172260,
                "reused": false,
                "local_path": "papers/repair/85bc9fdf7b6d2f5c5ff6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02242",
                "bytes": 322144,
                "reused": false,
                "local_path": "papers/repair/1366267456ae3965f8c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04586",
                "bytes": 282460,
                "reused": false,
                "local_path": "papers/repair/dfcdfea8469d7c081d06.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01780",
                "bytes": 863822,
                "reused": false,
                "local_path": "papers/repair/f5e8782daef1aa339f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6572",
                "bytes": 1036360,
                "reused": false,
                "local_path": "papers/repair/1b6f12d7db56a03ce596.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03976",
                "bytes": 8496008,
                "reused": false,
                "local_path": "papers/repair/7c610a3bc37a3c724c6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.03825",
                "bytes": 2774709,
                "reused": false,
                "local_path": "papers/repair/c0ed786bf3a3169d24a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.09412",
                "bytes": 740562,
                "reused": false,
                "local_path": "papers/repair/7af2d52fbf38a69ec251.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.12848",
                "bytes": 1625724,
                "reused": false,
                "local_path": "papers/repair/17af125202b45606d9ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.13719",
                "bytes": 1263406,
                "reused": false,
                "local_path": "papers/repair/c267ff367c4770ddb6c0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04717",
                "bytes": 626230,
                "reused": false,
                "local_path": "papers/repair/ae6e8a0596cf6995095d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.kamalnigam.com/papers/cotrain-CIKM00.pdf",
                "bytes": 230483,
                "reused": false,
                "local_path": "papers/repair/aa557a37f131c5edaca1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.04252",
                "bytes": 2801395,
                "reused": false,
                "local_path": "papers/repair/2d5071bca517ed21302d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.11946",
                "bytes": 933600,
                "reused": false,
                "local_path": "papers/repair/b9c9141c18b68865cdc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09382",
                "bytes": 989025,
                "reused": false,
                "local_path": "papers/repair/531ae1708a14ac8b81dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2010.02194",
                "bytes": 2525939,
                "reused": false,
                "local_path": "papers/repair/46cf1aae6a3b935b22db.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.02983",
                "bytes": 904317,
                "reused": false,
                "local_path": "papers/repair/4e39b8b3af735acbdef2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10580",
                "bytes": 1245388,
                "reused": false,
                "local_path": "papers/repair/19c860b2949c2d91d5ec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": false,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.02249",
                "bytes": 520905,
                "reused": false,
                "local_path": "papers/repair/c84670ad345d150685e0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.09785",
                "bytes": 420212,
                "reused": false,
                "local_path": "papers/repair/e1bda50022ee2a740e73.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.07394",
                "bytes": 771769,
                "reused": false,
                "local_path": "papers/repair/a688eaa44d9b3d4d3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11238",
                "bytes": 3862031,
                "reused": false,
                "local_path": "papers/repair/4f8506d9f9d2559e3846.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.07685",
                "bytes": 770166,
                "reused": false,
                "local_path": "papers/repair/f068f1c17b46bc3eed3a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.06882",
                "bytes": 1655938,
                "reused": false,
                "local_path": "papers/repair/d7e01a0318a00ae28138.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": false,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10029",
                "bytes": 823706,
                "reused": false,
                "local_path": "papers/repair/558bd6a836d462b86d7a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.08941",
                "bytes": 345640,
                "reused": true,
                "local_path": "papers/repair/646a76cd251b8253359a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 39098,
            "expected_body_images": 20,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/76583c4985bd/pages/source.html",
            "local_html": "attachments/76583c4985bd/pages/article.html",
            "body_base_path": "attachments/76583c4985bd/pages/",
            "body_markdown_path": "attachments/76583c4985bd/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
          "status": "partial",
          "article_id": "8a21c0acfb00",
          "local_path": "series-follow/1601/repair/d28ee743c76f5eaa3eb7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
              "bytes": 337534,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4166a5ced4caf6791370.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
              "bytes": 147142,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d50c93dfe76da4d51e52.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
              "bytes": 94880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c273a3bd2d035c6f2911.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
              "bytes": 121482,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1601/repair/assets/ec939fa4e1c720a45f69.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
              "bytes": 113689,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/63a237a784c9d55c73a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
              "bytes": 65056,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3b94a58b47770eed7ab3.png"
            }
          ],
          "article": {
            "id": "8a21c0acfb00",
            "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "bytes": 337534,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-4166a5ced4caf6791370.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/exploration_vs_exploitation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "bytes": 147142,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-d50c93dfe76da4d51e52.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_bandit.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "bytes": 94880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-c273a3bd2d035c6f2911.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bern_UCB.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "bytes": 121482,
                "reused": false,
                "content_type": "image/jpeg",
                "local_path": "attachments/8a21c0acfb00/images/body-ec939fa4e1c720a45f69.jpg",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/klay-thompson.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "bytes": 113689,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-63a237a784c9d55c73a0.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "bytes": 65056,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/8a21c0acfb00/images/body-3b94a58b47770eed7ab3.png",
                "src": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/bandit_solution_summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=sGuiWX07sKw",
                "src": "https://youtu.be/sGuiWX07sKw",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/8a21c0acfb00/videos/repair-sGuiWX07sKw.mp4",
                "bytes": 1536006447,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5957.781000",
                "reused": false
              }
            ],
            "body_markdown": "The algorithms are implemented for Bernoulli bandit in\nlilianweng/multi-armed-bandit\n.\nExploitation vs Exploration\n#\nThe exploration vs exploitation dilemma exists in many aspects of our life. Say, your favorite restaurant is right around the corner. If you go there every day, you would be confident of what you will get, but miss the chances of discovering an even better option. If you try new places all the time, very likely you are gonna have to eat unpleasant food from time to time. Similarly, online advisors try to balance between the known most attractive ads and the new ads that might be even more successful.\nA real-life example of the exploration vs exploitation dilemma: where to eat? (Image source: UC Berkeley AI course\nslide\n,\nlecture 11\n.)\nIf we have learned all the information about the environment, we are able to find the best strategy by even just simulating brute-force, let alone many other smart approaches. The dilemma comes from the\nincomplete\ninformation: we need to gather enough information to make best overall decisions while keeping the risk under control. With exploitation, we take advantage of the best option we know. With exploration, we take some risk to collect information about unknown options. The best long-term strategy may involve short-term sacrifices. For example, one exploration trial could be a total failure, but it warns us of not taking that action too often in the future.\nWhat is Multi-Armed Bandit?\n#\nThe\nmulti-armed bandit\nproblem is a classic problem that well demonstrates the exploration vs exploitation dilemma. Imagine you are in a casino facing multiple slot machines and each is configured with an unknown probability of how likely you can get a reward at one play. The question is:\nWhat is the best strategy to achieve highest long-term rewards?\nIn this post, we will only discuss the setting of having an infinite number of trials. The restriction on a finite number of trials introduces a new type of exploration problem. For instance, if the number of trials is smaller than the number of slot machines, we cannot even try every machine to estimate the reward probability (!) and hence we have to behave smartly w.r.t. a limited set of knowledge and resources (i.e. time).\nAn illustration of how a Bernoulli multi-armed bandit works. The reward probabilities are **unknown** to the player.\nA naive approach can be that you continue to playing with one machine for many many rounds so as to eventually estimate the “true” reward probability according to the\nlaw of large numbers\n. However, this is quite wasteful and surely does not guarantee the best long-term reward.\nDefinition\n#\nNow let’s give it a scientific definition.\nA Bernoulli multi-armed bandit can be described as a tuple of $\\langle \\mathcal{A}, \\mathcal{R} \\rangle$, where:\nWe have $K$ machines with reward probabilities, $\\{ \\theta_1, \\dots, \\theta_K \\}$.\nAt each time step t, we take an action a on one slot machine and receive a reward r.\n$\\mathcal{A}$ is a set of actions, each referring to the interaction with one slot machine. The value of action a is the expected reward, $Q(a) = \\mathbb{E} [r \\vert a] = \\theta$. If action $a_t$ at the time step t is on the i-th machine, then $Q(a_t) = \\theta_i$.\n$\\mathcal{R}$ is a reward function. In the case of Bernoulli bandit, we observe a reward r in a\nstochastic\nfashion. At the time step t, $r_t = \\mathcal{R}(a_t)$ may return reward 1 with a probability $Q(a_t)$ or 0 otherwise.\nIt is a simplified version of\nMarkov decision process\n, as there is no state $\\mathcal{S}$.\nThe goal is to maximize the cumulative reward $\\sum_{t=1}^T r_t$.\nIf we know the optimal action with the best reward, then the goal is same as to minimize the potential\nregret\nor loss by not picking the optimal action.\nThe optimal reward probability $\\theta^{*}$ of the optimal action $a^{*}$ is:\n$$\n\\theta^{*}=Q(a^{*})=\\max_{a \\in \\mathcal{A}} Q(a) = \\max_{1 \\leq i \\leq K} \\theta_i\n$$\nOur loss function is the total regret we might have by not selecting the optimal action up to the time step T:\n$$\n\\mathcal{L}_T = \\mathbb{E} \\Big[ \\sum_{t=1}^T \\big( \\theta^{*} - Q(a_t) \\big) \\Big]\n$$\nBandit Strategies\n#\nBased on how we do exploration, there several ways to solve the multi-armed bandit.\nNo exploration: the most naive approach and a bad one.\nExploration at random\nExploration smartly with preference to uncertainty\nε-Greedy Algorithm\n#\nThe ε-greedy algorithm takes the best action most of the time, but does random exploration occasionally. The action value is estimated according to the past experience by averaging the rewards associated with the target action a that we have observed so far (up to the current time step t):\n$$\n\\hat{Q}_t(a) = \\frac{1}{N_t(a)} \\sum_{\\tau=1}^t r_\\tau \\mathbb{1}[a_\\tau = a]\n$$\nwhere $\\mathbb{1}$ is a binary indicator function and $N_t(a)$ is how many times the action a has been selected so far, $N_t(a) = \\sum_{\\tau=1}^t \\mathbb{1}[a_\\tau = a]$.\nAccording to the ε-greedy algorithm, with a small probability $\\epsilon$ we take a random action, but otherwise (which should be the most of the time, probability 1-$\\epsilon$) we pick the best action that we have learnt so far: $\\hat{a}^{*}_t = \\arg\\max_{a \\in \\mathcal{A}} \\hat{Q}_t(a)$.\nCheck my toy implementation\nhere\n.\nUpper Confidence Bounds\n#\nRandom exploration gives us an opportunity to try out options that we have not known much about. However, due to the randomness, it is possible we end up exploring a bad action which we have confirmed in the past (bad luck!). To avoid such inefficient exploration, one approach is to decrease the parameter ε in time and the other is to be optimistic about options with\nhigh uncertainty\nand thus to prefer actions for which we haven’t had a confident value estimation yet. Or in other words, we favor exploration of actions with a strong potential to have a optimal value.\nThe Upper Confidence Bounds (UCB) algorithm measures this potential by an upper confidence bound of the reward value, $\\hat{U}_t(a)$, so that the true value is below with bound $Q(a) \\leq \\hat{Q}_t(a) + \\hat{U}_t(a)$ with high probability. The upper bound $\\hat{U}_t(a)$ is a function of $N_t(a)$; a larger number of trials $N_t(a)$ should give us a smaller bound $\\hat{U}_t(a)$.\nIn UCB algorithm, we always select the greediest action to maximize the upper confidence bound:\n$$\na^{UCB}_t = argmax_{a \\in \\mathcal{A}} \\hat{Q}_t(a) + \\hat{U}_t(a)\n$$\nNow, the question is\nhow to estimate the upper confidence bound\n.\nHoeffding’s Inequality\n#\nIf we do not want to assign any prior knowledge on how the distribution looks like, we can get help from\n“Hoeffding’s Inequality”\n— a theorem applicable to any bounded distribution.\nLet $X_1, \\dots, X_t$ be i.i.d. (independent and identically distributed) random variables and they are all bounded by the interval [0, 1]. The sample mean is $\\overline{X}_t = \\frac{1}{t}\\sum_{\\tau=1}^t X_\\tau$. Then for $u > 0$, we have:\n$$\n\\mathbb{P} [ \\mathbb{E}[X] > \\overline{X}_t + u] \\leq e^{-2tu^2}\n$$\nGiven one target action $a$, let us consider:\n$r_t(a)$ as the random variables,\n$Q(a)$ as the true mean,\n$\\hat{Q}_t(a)$ as the sample mean,\nAnd $u$ as the upper confidence bound, $u = U_t(a)$\nThen we have,\n$$\n\\mathbb{P} [ Q(a) > \\hat{Q}_t(a) + U_t(a)] \\leq e^{-2t{U_t(a)}^2}\n$$\nWe want to pick a bound so that with high chances the true mean is blow the sample mean + the upper confidence bound. Thus $e^{-2t U_t(a)^2}$ should be a small probability. Let’s say we are ok with a tiny threshold p:\n$$\ne^{-2t U_t(a)^2} = p \\text{  Thus, } U_t(a) = \\sqrt{\\frac{-\\log p}{2 N_t(a)}}\n$$\nUCB1\n#\nOne heuristic is to reduce the threshold p in time, as we want to make more confident bound estimation with more rewards observed. Set $p=t^{-4}$ we get\nUCB1\nalgorithm:\n$$\nU_t(a) = \\sqrt{\\frac{2 \\log t}{N_t(a)}} \\text{  and  }\na^{UCB1}_t = \\arg\\max_{a \\in \\mathcal{A}} Q(a) + \\sqrt{\\frac{2 \\log t}{N_t(a)}}\n$$\nBayesian UCB\n#\nIn UCB or UCB1 algorithm, we do not assume any prior on the reward distribution and therefore we have to rely on the Hoeffding’s Inequality for a very generalize estimation. If we are able to know the distribution upfront, we would be able to make better bound estimation.\nFor example, if we expect the mean reward of every slot machine to be Gaussian as in Fig 2, we can set the upper bound as 95% confidence interval by setting $\\hat{U}_t(a)$ to be twice the standard deviation.\nWhen the expected reward has a Gaussian distribution. $\\sigma(a\\_i)$ is the standard deviation and $c\\sigma(a\\_i)$ is the upper confidence bound. The constant $c$ is a adjustable hyperparameter. (Image source:\nUCL RL course lecture 9's slides\n)\nCheck my toy implementation of\nUCB1\nand\nBayesian UCB\nwith Beta prior on θ.\nThompson Sampling\n#\nThompson sampling has a simple idea but it works great for solving the multi-armed bandit problem.\nOops, I guess not this Thompson? (Credit goes to\nBen Taborsky\n; he has a full theorem of how Thompson invented while pondering over who to pass the ball. Yes I stole his joke.)\nAt each time step, we want to select action a according to the probability that a is\noptimal\n:\n$$\n\\begin{aligned}\n\\pi(a \\; \\vert \\; h_t) \n&= \\mathbb{P} [ Q(a) > Q(a'), \\forall a' \\neq a \\; \\vert \\; h_t] \\\\\n&= \\mathbb{E}_{\\mathcal{R} \\vert h_t} [ \\mathbb{1}(a = \\arg\\max_{a \\in \\mathcal{A}} Q(a)) ]\n\\end{aligned}\n$$\nwhere $\\pi(a ; \\vert ; h_t)$ is the probability of taking action a given the history $h_t$.\nFor the Bernoulli bandit, it is natural to assume that $Q(a)$ follows a\nBeta\ndistribution, as $Q(a)$ is essentially the success probability θ in\nBernoulli\ndistribution.  The value of $\\text{Beta}(\\alpha, \\beta)$ is within the interval [0, 1]; α and β correspond to the counts when we\nsucceeded\nor\nfailed\nto get a reward respectively.\nFirst, let us initialize the Beta parameters α and β based on some prior knowledge or belief for every action. For example,\nα = 1 and β = 1; we expect the reward probability to be 50% but we are not very confident.\nα = 1000 and β = 9000; we strongly believe that the reward probability is 10%.\nAt each time t, we sample an expected reward, $\\tilde{Q}(a)$, from the prior distribution $\\text{Beta}(\\alpha_i, \\beta_i)$ for every action. The best action is selected among samples: $a^{TS}_t = \\arg\\max_{a \\in \\mathcal{A}} \\tilde{Q}(a)$. After the true reward is observed, we can update the Beta distribution accordingly, which is essentially doing Bayesian inference to compute the posterior with the known prior and the likelihood of getting the sampled data.\n$$\n\\begin{aligned}\n\\alpha_i & \\leftarrow \\alpha_i + r_t \\mathbb{1}[a^{TS}_t = a_i] \\\\ \n\\beta_i & \\leftarrow \\beta_i + (1-r_t) \\mathbb{1}[a^{TS}_t = a_i]\n\\end{aligned}\n$$\nThompson sampling implements the idea of\nprobability matching\n. Because its reward estimations $\\tilde{Q}$ are sampled from posterior distributions, each of these probabilities is equivalent to the probability that the corresponding action is optimal, conditioned on observed history.\nHowever, for many practical and complex problems, it can be computationally intractable to estimate the posterior distributions with observed true rewards using Bayesian inference. Thompson sampling still can work out if we are able to approximate the posterior distributions using methods like Gibbs sampling, Laplace approximate, and the bootstraps. This\ntutorial\npresents a comprehensive review; strongly recommend it if you want to learn more about Thompson sampling.\nCase Study\n#\nI implemented the above algorithms in\nlilianweng/multi-armed-bandit\n. A\nBernoulliBandit\nobject can be constructed with a list of random or predefined reward probabilities. The bandit algorithms are implemented as subclasses of\nSolver\n, taking a Bandit object as the target problem. The cumulative regrets are tracked in time.\nThe result of a small experiment on solving a Bernoulli bandit with K = 10 slot machines with reward probabilities, {0.0, 0.1, 0.2, ..., 0.9}. Each solver runs 10000 steps.\n(Left) The plot of time step vs the cumulative regrets. \n(Middle) The plot of true reward probability vs estimated probability. \n(Right) The fraction of each action is picked during the 10000-step run.*\nSummary\n#\nWe need exploration because information is valuable. In terms of the exploration strategies, we can do no exploration at all, focusing on the short-term returns. Or we occasionally explore at random. Or even further, we explore and we are picky about which options to explore — actions with higher uncertainty are favored because they can provide higher information gain.\nCited as:\n@article{weng2018bandit,\n  title   = \"The Multi-Armed Bandit Problem and Its Solutions\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/\"\n}\nReferences\n#\n[1] CS229 Supplemental Lecture notes:\nHoeffding’s inequality\n.\n[2] RL Course by David Silver - Lecture 9:\nExploration and Exploitation\n[3] Olivier Chapelle and Lihong Li.\n“An empirical evaluation of thompson sampling.”\nNIPS. 2011.\n[4] Russo, Daniel, et al.\n“A Tutorial on Thompson Sampling.”\narXiv:1707.02038 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:18Z",
            "title": "The Multi-Armed Bandit Problem and Its Solutions | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/8a21c0acfb00/code/body-000.txt",
                "chars": 255,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "bytes": 87277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7f286fae95f9b1c990be.pdf"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "retried_at": "2026-10-20T17:52:05Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.02038.pdf",
                "bytes": 3259310,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/11b5feb4dc8735d58193.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "bytes": 239361,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6b691aa46c22c662cdf.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 13130,
            "expected_body_images": 6,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/8a21c0acfb00/pages/source.html",
            "local_html": "attachments/8a21c0acfb00/pages/article.html",
            "body_base_path": "attachments/8a21c0acfb00/pages/",
            "body_markdown_path": "attachments/8a21c0acfb00/pages/article.md",
            "links": [
              {
                "href": "http://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/lecture_slides.html",
                "label": "slide",
                "type": "a"
              },
              {
                "href": "http://ai.berkeley.edu/slides/Lecture%2011%20--%20Reinforcement%20Learning%20II/SP14%20CS188%20Lecture%2011%20--%20Reinforcement%20Learning%20II.pptx",
                "label": "lecture 11",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Multi-armed_bandit",
                "label": "multi-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "law of large numbers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_decision_process",
                "label": "Markov decision process",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Regret_(decision_theory)",
                "label": "regret",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/solvers.py",
                "label": "here",
                "type": "a"
              },
              {
                "href": "http://cs229.stanford.edu/extra-notes/hoeffding.pdf",
                "label": "“Hoeffding’s Inequality”",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/XX.pdf",
                "label": "UCL RL course lecture 9's slides",
                "type": "a"
              },
              {
                "href": "https://www.linkedin.com/in/benjamin-taborsky",
                "label": "Ben Taborsky",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beta_distribution",
                "label": "Beta",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bernoulli_distribution",
                "label": "Bernoulli",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_matching",
                "label": "probability matching",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.02038.pdf",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit",
                "label": "lilianweng/multi-armed-bandit",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/multi-armed-bandit/blob/master/bandits.py",
                "label": "BernoulliBandit",
                "type": "a"
              },
              {
                "href": "https://youtu.be/sGuiWX07sKw",
                "label": "Exploration and Exploitation",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/4321-an-empirical-evaluation-of-thompson-sampling.pdf",
                "label": "“An empirical evaluation of thompson sampling.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
          "status": "partial",
          "article_id": "9e1d58627b38",
          "local_path": "series-follow/1601/repair/3966b026c35e1e97e15a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
              "bytes": 58269,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/418c8992a5cc9d9deeb1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
              "bytes": 107025,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d53eaab123d7a3b8d561.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
              "bytes": 33772,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1a3ee27cdec9dd4e95e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
              "bytes": 55693,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1601/repair/assets/8b930e0942e1d249d7cd.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
              "bytes": 27143,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/508e643f8751bb71fcf3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
              "bytes": 32728,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/aa4ac628fe85693e0ba3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
              "bytes": 21618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8917c12943284b1507b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
              "bytes": 133435,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c1fcc0568374ce65ea91.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
              "bytes": 35850,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/be7712dd68a63d561005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
              "bytes": 128382,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d374974862f12f0f0ada.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
              "bytes": 91431,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0d8b962a59d7ad31b2ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
              "bytes": 136647,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3ceb5a7713444f264e70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
              "bytes": 61555,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/070437b06f4b4d8a0287.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "A (Long) Peek into Reinforcement Learning",
            "keywords": "强化学习,RL,入门",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "publish_date": "2018-02",
            "corpus_stage": "强化学习/对齐",
            "notes": "强化学习入门经典综述",
            "id": "9e1d58627b38",
            "collected_at": "2026-10-02T14:13:19",
            "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-09-03: Updated the algorithm of\nSARSA\nand\nQ-learning\nso that the difference is more pronounced.\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in\nChinese\n].\nA couple of exciting news in Artificial Intelligence (AI) has just happened in recent years.  AlphaGo defeated the best professional human player in the game of Go. Very soon the extended algorithm AlphaGo Zero beat AlphaGo by 100-0 without supervised learning on human knowledge. Top professional game players lost to the bot developed by OpenAI on DOTA2 1v1 competition. After knowing these, it is pretty hard not to be curious about the magic behind these algorithms — Reinforcement Learning (RL). I’m writing this post to briefly go over the field. We will first introduce several fundamental concepts and then dive into classic approaches to solving RL problems. Hopefully, this post could be a good starting point for newbies, bridging the future study on the cutting-edge research.\nWhat is Reinforcement Learning?\n#\nSay, we have an agent in an unknown environment and this agent can obtain some rewards by interacting with the environment. The agent ought to take actions so as to maximize cumulative rewards. In reality, the scenario could be a bot playing a game to achieve high scores, or a robot trying to complete physical tasks with physical items; and not just limited to these.\nAn agent interacts with the environment, trying to take smart actions to maximize cumulative rewards.\nThe goal of Reinforcement Learning (RL) is to learn a good strategy for the agent from experimental trials and relative simple feedback received. With the optimal strategy, the agent is capable to actively adapt to the environment to maximize future rewards.\nKey Concepts\n#\nNow Let’s formally define a set of key concepts in RL.\nThe agent is acting in an\nenvironment\n. How the environment reacts to certain actions is defined by a\nmodel\nwhich we may or may not know. The agent can stay in one of many\nstates\n($s \\in \\mathcal{S}$) of the environment, and choose to take one of many\nactions\n($a \\in \\mathcal{A}$) to switch from one state to another. Which state the agent will arrive in is decided by transition probabilities between states ($P$). Once an action is taken, the environment delivers a\nreward\n($r \\in \\mathcal{R}$) as feedback.\nThe model defines the reward function and transition probabilities. We may or may not know how the model works and this differentiate two circumstances:\nKnow the model\n: planning with perfect information; do model-based RL. When we fully know the environment, we can find the optimal solution by\nDynamic Programming\n(DP). Do you still remember “longest increasing subsequence” or “traveling salesmen problem” from your Algorithms 101 class? LOL. This is not the focus of this post though.\nDoes not know the model\n: learning with incomplete information; do model-free RL or try to learn the model explicitly as part of the algorithm. Most of the following content serves the scenarios when the model is unknown.\nThe agent’s\npolicy\n$\\pi(s)$ provides the guideline on what is the optimal action to take in a certain state with\nthe goal to maximize the total rewards\n. Each state is associated with a\nvalue\nfunction $V(s)$ predicting the expected amount of future rewards we are able to receive in this state by acting the corresponding policy. In other words, the value function quantifies how good a state is. Both policy and value functions are what we try to learn in reinforcement learning.\nSummary of approaches in RL based on whether we want to model the value, policy, or the environment. (Image source: reproduced from David Silver's RL course\nlecture 1\n.)\nThe interaction between the agent and the environment involves a sequence of actions and observed rewards in time, $t=1, 2, \\dots, T$. During the process, the agent accumulates the knowledge about the environment, learns the optimal policy, and makes decisions on which action to take next so as to efficiently learn the best policy. Let’s label the state, action, and reward at time step t as $S_t$, $A_t$, and $R_t$, respectively. Thus the interaction sequence is fully described by one\nepisode\n(also known as “trial” or “trajectory”) and the sequence ends at the terminal state $S_T$:\n$$\nS_1, A_1, R_2, S_2, A_2, \\dots, S_T\n$$\nTerms you will encounter a lot when diving into different categories of RL algorithms:\nModel-based\n: Rely on the model of the environment; either the model is known or the algorithm learns it explicitly.\nModel-free\n: No dependency on the model during learning.\nOn-policy\n: Use the deterministic outcomes or samples from the target policy to train the algorithm.\nOff-policy\n: Training on a distribution of transitions or episodes produced by a different behavior policy rather than that produced by the target policy.\nModel: Transition and Reward\n#\nThe model is a descriptor of the environment. With the model, we can learn or infer how the environment would interact with and provide feedback to the agent. The model has two major parts, transition probability function $P$ and reward function $R$.\nLet’s say when we are in state s, we decide to take action a to arrive in the next state s’ and obtain reward r. This is known as one\ntransition\nstep, represented by a tuple (s, a, s’, r).\nThe transition function P records the probability of transitioning from state s to s’ after taking action a while obtaining reward r. We use $\\mathbb{P}$ as a symbol of “probability”.\n$$\nP(s', r \\vert s, a)  = \\mathbb{P} [S_{t+1} = s', R_{t+1} = r \\vert S_t = s, A_t = a]\n$$\nThus the state-transition function can be defined as a function of $P(s’, r \\vert s, a)$:\n$$\nP_{ss'}^a = P(s' \\vert s, a)  = \\mathbb{P} [S_{t+1} = s' \\vert S_t = s, A_t = a] = \\sum_{r \\in \\mathcal{R}} P(s', r \\vert s, a)\n$$\nThe reward function R predicts the next reward triggered by one action:\n$$\nR(s, a) = \\mathbb{E} [R_{t+1} \\vert S_t = s, A_t = a] = \\sum_{r\\in\\mathcal{R}} r \\sum_{s' \\in \\mathcal{S}} P(s', r \\vert s, a)\n$$\nPolicy\n#\nPolicy, as the agent’s behavior function $\\pi$, tells us which action to take in state s. It is a mapping from state s to action a and can be either deterministic or stochastic:\nDeterministic: $\\pi(s) = a$.\nStochastic: $\\pi(a \\vert s) = \\mathbb{P}_\\pi [A=a \\vert S=s]$.\nValue Function\n#\nValue function measures the goodness of a state or how rewarding a state or an action is by a prediction of future reward. The future reward, also known as\nreturn\n, is a total sum of discounted rewards going forward. Let’s compute the return $G_t$ starting from time t:\n$$\nG_t = R_{t+1} + \\gamma R_{t+2} + \\dots = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}\n$$\nThe discounting factor $\\gamma \\in [0, 1]$ penalize the rewards in the future, because:\nThe future rewards may have higher uncertainty; i.e. stock market.\nThe future rewards do not provide immediate benefits; i.e. As human beings, we might prefer to have fun today rather than 5 years later ;).\nDiscounting provides mathematical convenience; i.e., we don’t need to track future steps forever to compute return.\nWe don’t need to worry about the infinite loops in the state transition graph.\nThe\nstate-value\nof a state s is the expected return if we are in this state at time t, $S_t = s$:\n$$\nV_{\\pi}(s) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s]\n$$\nSimilarly, we define the\naction-value\n(“Q-value”; Q as “Quality” I believe?) of a state-action pair as:\n$$\nQ_{\\pi}(s, a) = \\mathbb{E}_{\\pi}[G_t \\vert S_t = s, A_t = a]\n$$\nAdditionally, since we follow the target policy $\\pi$, we can make use of the probility distribution over possible actions and the Q-values to recover the state-value:\n$$\nV_{\\pi}(s) = \\sum_{a \\in \\mathcal{A}} Q_{\\pi}(s, a) \\pi(a \\vert s)\n$$\nThe difference between action-value and state-value is the action\nadvantage\nfunction (“A-value”):\n$$\nA_{\\pi}(s, a) = Q_{\\pi}(s, a) - V_{\\pi}(s)\n$$\nOptimal Value and Policy\n#\nThe optimal value function produces the maximum return:\n$$\nV_{*}(s) = \\max_{\\pi} V_{\\pi}(s),\nQ_{*}(s, a) = \\max_{\\pi} Q_{\\pi}(s, a)\n$$\nThe optimal policy achieves optimal value functions:\n$$\n\\pi_{*} = \\arg\\max_{\\pi} V_{\\pi}(s),\n\\pi_{*} = \\arg\\max_{\\pi} Q_{\\pi}(s, a)\n$$\nAnd of course, we have $V_{\\pi_{*}}(s)=V_{*}(s)$ and $Q_{\\pi_{*}}(s, a) = Q_{*}(s, a)$.\nMarkov Decision Processes\n#\nIn more formal terms, almost all the RL problems can be framed as\nMarkov Decision Processes\n(MDPs). All states in MDP has “Markov” property, referring to the fact that the future only depends on the current state, not the history:\n$$\n\\mathbb{P}[ S_{t+1} \\vert S_t ] = \\mathbb{P} [S_{t+1} \\vert S_1, \\dots, S_t]\n$$\nOr in other words, the future and the past are\nconditionally independent\ngiven the present, as the current state encapsulates all the statistics we need to decide the future.\nThe agent-environment interaction in a Markov decision process. (Image source: Sec. 3.1 Sutton & Barto (2017).)\nA Markov deicison process consists of five elements $\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, P, R, \\gamma \\rangle$, where the symbols carry the same meanings as key concepts in the\nprevious\nsection, well aligned with RL problem settings:\n$\\mathcal{S}$ - a set of states;\n$\\mathcal{A}$ - a set of actions;\n$P$ - transition probability function;\n$R$ - reward function;\n$\\gamma$ - discounting factor for future rewards.\nIn an unknown environment, we do not have perfect knowledge about $P$ and $R$.\nA fun example of Markov decision process: a typical work day. (Image source:\nrandomant.net/reinforcement-learning-concepts\n)\nBellman Equations\n#\nBellman equations refer to a set of equations that decompose the value function into the immediate reward plus the discounted future values.\n$$\n\\begin{aligned}\nV(s) &= \\mathbb{E}[G_t \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma R_{t+2} + \\gamma^2 R_{t+3} + \\dots \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma (R_{t+2} + \\gamma R_{t+3} + \\dots) \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma G_{t+1} \\vert S_t = s] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\vert S_t = s]\n\\end{aligned}\n$$\nSimilarly for Q-value,\n$$\n\\begin{aligned}\nQ(s, a) \n&= \\mathbb{E} [R_{t+1} + \\gamma V(S_{t+1}) \\mid S_t = s, A_t = a] \\\\\n&= \\mathbb{E} [R_{t+1} + \\gamma \\mathbb{E}_{a\\sim\\pi} Q(S_{t+1}, a) \\mid S_t = s, A_t = a]\n\\end{aligned}\n$$\nBellman Expectation Equations\n#\nThe recursive update process can be further decomposed to be equations built on both state-value and action-value functions. As we go further in future action steps, we extend V and Q alternatively by following the policy $\\pi$.\nIllustration of how Bellman expection equations update state-value and action-value functions.\n$$\n\\begin{aligned}\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) Q_{\\pi}(s, a) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\\\\nV_{\\pi}(s) &= \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s) \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_{\\pi} (s') \\big) \\\\\nQ_{\\pi}(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\sum_{a' \\in \\mathcal{A}} \\pi(a' \\vert s') Q_{\\pi} (s', a')\n\\end{aligned}\n$$\nBellman Optimality Equations\n#\nIf we are only interested in the optimal values, rather than computing the expectation following a policy, we could jump right into the maximum returns during the alternative updates without using a policy. RECAP: the optimal values $V_*$ and $Q_*$ are the best returns we can obtain, defined\nhere\n.\n$$\n\\begin{aligned}\nV_*(s) &= \\max_{a \\in \\mathcal{A}} Q_*(s,a)\\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\\\\nV_*(s) &= \\max_{a \\in \\mathcal{A}} \\big( R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a V_*(s') \\big) \\\\\nQ_*(s, a) &= R(s, a) + \\gamma \\sum_{s' \\in \\mathcal{S}} P_{ss'}^a \\max_{a' \\in \\mathcal{A}} Q_*(s', a')\n\\end{aligned}\n$$\nUnsurprisingly they look very similar to Bellman expectation equations.\nIf we have complete information of the environment, this turns into a planning problem, solvable by DP. Unfortunately, in most scenarios, we do not know $P_{ss’}^a$ or $R(s, a)$, so we cannot solve MDPs by directly applying Bellmen equations, but it lays the theoretical foundation for many RL algorithms.\nCommon Approaches\n#\nNow it is the time to go through the major approaches and classic algorithms for solving RL problems. In future posts, I plan to dive into each approach further.\nDynamic Programming\n#\nWhen the model is fully known, following Bellman equations, we can use\nDynamic Programming\n(DP) to iteratively evaluate value functions and improve policy.\nPolicy Evaluation\n#\nPolicy Evaluation is to compute the state-value $V_\\pi$ for a given policy $\\pi$:\n$$\nV_{t+1}(s) \n= \\mathbb{E}_\\pi [r + \\gamma V_t(s') | S_t = s]\n= \\sum_a \\pi(a \\vert s) \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_t(s'))\n$$\nPolicy Improvement\n#\nBased on the value functions, Policy Improvement generates a better policy $\\pi’ \\geq \\pi$ by acting greedily.\n$$\nQ_\\pi(s, a) \n= \\mathbb{E} [R_{t+1} + \\gamma V_\\pi(S_{t+1}) \\vert S_t=s, A_t=a]\n= \\sum_{s', r} P(s', r \\vert s, a) (r + \\gamma V_\\pi(s'))\n$$\nPolicy Iteration\n#\nThe\nGeneralized Policy Iteration (GPI)\nalgorithm refers to an iterative procedure to improve the policy when combining policy evaluation and improvement.\n$$\n\\pi_0 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_0} \\xrightarrow[]{\\text{improve}}\n\\pi_1 \\xrightarrow[]{\\text{evaluation}} V_{\\pi_1} \\xrightarrow[]{\\text{improve}}\n\\pi_2 \\xrightarrow[]{\\text{evaluation}} \\dots \\xrightarrow[]{\\text{improve}}\n\\pi_* \\xrightarrow[]{\\text{evaluation}} V_*\n$$\nIn GPI, the value function is approximated repeatedly to be closer to the true value of the current policy and in the meantime, the policy is improved repeatedly to approach optimality. This policy iteration process works and always converges to the optimality, but why this is the case?\nSay, we have a policy $\\pi$ and then generate an improved version $\\pi’$ by greedily taking actions, $\\pi’(s) = \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)$. The value of this improved $\\pi’$ is guaranteed to be better because:\n$$\n\\begin{aligned}\nQ_\\pi(s, \\pi'(s))\n&= Q_\\pi(s, \\arg\\max_{a \\in \\mathcal{A}} Q_\\pi(s, a)) \\\\\n&= \\max_{a \\in \\mathcal{A}} Q_\\pi(s, a) \\geq Q_\\pi(s, \\pi(s)) = V_\\pi(s)\n\\end{aligned}\n$$\nMonte-Carlo Methods\n#\nFirst, let’s recall that $V(s) = \\mathbb{E}[ G_t \\vert S_t=s]$. Monte-Carlo (MC) methods uses a simple idea: It learns from episodes of raw experience without modeling the environmental dynamics and computes the observed mean return as an approximation of the expected return. To compute the empirical return $G_t$, MC methods need to learn from\ncomplete\nepisodes $S_1, A_1, R_2, \\dots, S_T$ to compute $G_t = \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1}$ and all the episodes must eventually terminate.\nThe empirical mean return for state s is:\n$$\nV(s) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s]}\n$$\nwhere $\\mathbb{1}[S_t = s]$ is a binary indicator function. We may count the visit of state s every time so that there could exist multiple visits of one state in one episode (“every-visit”), or only count it the first time we encounter a state in one episode (“first-visit”). This way of approximation can be easily extended to action-value functions by counting (s, a) pair.\n$$\nQ(s, a) = \\frac{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a] G_t}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}\n$$\nTo learn the optimal policy by MC, we iterate it by following a similar idea to\nGPI\n.\nImprove the policy greedily with respect to the current value function: $\\pi(s) = \\arg\\max_{a \\in \\mathcal{A}} Q(s, a)$.\nGenerate a new episode with the new policy $\\pi$ (i.e. using algorithms like\nε-greedy\nhelps us balance between exploitation and exploration.)\nEstimate Q using the new episode: $q_\\pi(s, a) = \\frac{\\sum_{t=1}^T \\big( \\mathbb{1}[S_t = s, A_t = a] \\sum_{k=0}^{T-t-1} \\gamma^k R_{t+k+1} \\big)}{\\sum_{t=1}^T \\mathbb{1}[S_t = s, A_t = a]}$\nTemporal-Difference Learning\n#\nSimilar to Monte-Carlo methods, Temporal-Difference (TD) Learning is model-free and learns from episodes of experience. However, TD learning can learn from\nincomplete\nepisodes and hence we don’t need to track the episode up to termination. TD learning is so important that Sutton & Barto (2017) in their RL book describes it as “one idea … central and novel to reinforcement learning”.\nBootstrapping\n#\nTD learning methods update targets with regard to existing estimates rather than exclusively relying on actual rewards and complete returns as in MC methods. This approach is known as\nbootstrapping\n.\nValue Estimation\n#\nThe key idea in TD learning is to update the value function $V(S_t)$ towards an estimated return $R_{t+1} + \\gamma V(S_{t+1})$ (known as “\nTD target\n”). To what extent we want to update the value function is controlled by the learning rate hyperparameter α:\n$$\n\\begin{aligned}\nV(S_t) &\\leftarrow (1- \\alpha) V(S_t) + \\alpha G_t \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (G_t - V(S_t)) \\\\\nV(S_t) &\\leftarrow V(S_t) + \\alpha (R_{t+1} + \\gamma V(S_{t+1}) - V(S_t))\n\\end{aligned}\n$$\nSimilarly, for action-value estimation:\n$$\nQ(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t))\n$$\nNext, let’s dig into the fun part on how to learn optimal policy in TD learning (aka “TD control”). Be prepared, you are gonna see many famous names of classic algorithms in this section.\nSARSA: On-Policy TD control\n#\n“SARSA” refers to the procedure of updaing Q-value by following a sequence of $\\dots, S_t, A_t, R_{t+1}, S_{t+1}, A_{t+1}, \\dots$. The idea follows the same route of\nGPI\n. Within one episode, it works as follows:\nInitialize $t=0$.\nStart with $S_0$ and choose action $A_0 = \\arg\\max_{a \\in \\mathcal{A}} Q(S_0, a)$, where\n$\\epsilon$-greedy\nis commonly applied.\nAt time $t$, after applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nThen pick the next action in the same way as in step 2: $A_{t+1} = \\arg\\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a)$.\nUpdate the Q-value function: $ Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t)) $.\nSet $t = t+1$ and repeat from step 3.\nIn each step of SARSA, we need to choose the\nnext\naction according to the\ncurrent\npolicy.\nQ-Learning: Off-policy TD control\n#\nThe development of Q-learning (\nWatkins & Dayan, 1992\n) is a big breakout in the early days of Reinforcement Learning. Within one episode, it works as follows:\nInitialize $t=0$.\nStarts with $S_0$.\nAt time step $t$, we pick the action according to Q values, $A_t = \\arg\\max_{a \\in \\mathcal{A}} Q(S_t, a)$ and $\\epsilon$-greedy is commonly applied.\nAfter applying action $A_t$, we observe reward $R_{t+1}$ and get into the next state $S_{t+1}$.\nUpdate the Q-value function: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha (R_{t+1} + \\gamma \\max_{a \\in \\mathcal{A}} Q(S_{t+1}, a) - Q(S_t, A_t))$.\n$t = t+1$ and repeat from step 3.\nThe key difference from SARSA is that Q-learning does not follow the current policy to pick the second action $A_{t+1}$. It estimates $Q^*$ out of the best Q values, but which action (denoted as $a^*$) leads to this maximal Q does not matter and in the next step Q-learning may not follow $a^*$.\nThe backup diagrams for Q-learning and SARSA. (Image source: Replotted based on Figure 6.5 in Sutton & Barto (2017))\nDeep Q-Network\n#\nTheoretically, we can memorize $Q_*(.)$ for all state-action pairs in Q-learning, like in a gigantic table. However, it quickly becomes computationally infeasible when the state and action space are large. Thus people use functions (i.e. a machine learning model) to approximate Q values and this is called\nfunction approximation\n. For example, if we use a function with parameter $\\theta$ to calculate Q values, we can label Q value function as $Q(s, a; \\theta)$.\nUnfortunately Q-learning may suffer from instability and divergence when combined with an nonlinear Q-value function approximation and\nbootstrapping\n(See\nProblems #2\n).\nDeep Q-Network (“DQN”; Mnih et al. 2015) aims to greatly improve and stabilize the training procedure of Q-learning by two innovative mechanisms:\nExperience Replay\n: All the episode steps $e_t = (S_t, A_t, R_t, S_{t+1})$ are stored in one replay memory $D_t = \\{ e_1, \\dots, e_t \\}$. $D_t$ has experience tuples over many episodes. During Q-learning updates, samples are drawn at random from the replay memory and thus one sample could be used multiple times. Experience replay improves data efficiency, removes correlations in the observation sequences, and smooths over changes in the data distribution.\nPeriodically Updated Target\n: Q is optimized towards target values that are only periodically updated. The Q network is cloned and kept frozen as the optimization target every C steps (C is a hyperparameter). This modification makes the training more stable as it overcomes the short-term oscillations.\nThe loss function looks like this:\n$$\n\\mathcal{L}(\\theta) = \\mathbb{E}_{(s, a, r, s') \\sim U(D)} \\Big[ \\big( r + \\gamma \\max_{a'} Q(s', a'; \\theta^{-}) - Q(s, a; \\theta) \\big)^2 \\Big]\n$$\nwhere $U(D)$ is a uniform distribution over the replay memory D; $\\theta^{-}$ is the parameters of the frozen target Q-network.\nIn addition, it is also found to be helpful to clip the error term to be between [-1, 1]. (I always get mixed feeling with parameter clipping, as many studies have shown that it works empirically but it makes the math much less pretty. :/)\nAlgorithm for DQN with experience replay and occasionally frozen optimization target. The prepossessed sequence is the output of some processes running on the input images of Atari games. Don't worry too much about it; just consider them as input feature vectors. (Image source: Mnih et al. 2015)\nThere are many extensions of DQN to improve the original design, such as DQN with dueling architecture (Wang et al. 2016) which estimates state-value function V(s) and advantage function A(s, a) with shared network parameters.\nCombining TD and MC Learning\n#\nIn the previous\nsection\non value estimation in TD learning, we only trace one step further down the action chain when calculating the TD target. One can easily extend it to take multiple steps to estimate the return.\nLet’s label the estimated return following n steps as $G_t^{(n)}, n=1, \\dots, \\infty$, then:\n$n$\n$G_t$\nNotes\n$n=1$\n$G_t^{(1)} = R_{t+1} + \\gamma V(S_{t+1})$\nTD learning\n$n=2$\n$G_t^{(2)} = R_{t+1} + \\gamma R_{t+2} + \\gamma^2 V(S_{t+2})$\n…\n$n=n$\n$ G_t^{(n)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1} R_{t+n} + \\gamma^n V(S_{t+n}) $\n…\n$n=\\infty$\n$G_t^{(\\infty)} = R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{T-t-1} R_T + \\gamma^{T-t} V(S_T) $\nMC estimation\nThe generalized n-step TD learning still has the\nsame\nform for updating the value function:\n$$\nV(S_t) \\leftarrow V(S_t) + \\alpha (G_t^{(n)} - V(S_t))\n$$\nWe are free to pick any $n$ in TD learning as we like. Now the question becomes what is the best $n$? Which $G_t^{(n)}$ gives us the best return approximation? A common yet smart solution is to apply a weighted sum of all possible n-step TD targets rather than to pick a single best n. The weights decay by a factor λ with n, $\\lambda^{n-1}$; the intuition is similar to\nwhy\nwe want to discount future rewards when computing the return: the more future we look into the less confident we would be. To make all the weight (n → ∞) sum up to 1, we multiply every weight by (1-λ), because:\n$$\n\\begin{aligned}\n\\text{let } S &= 1 + \\lambda + \\lambda^2 + \\dots \\\\\nS &= 1 + \\lambda(1 + \\lambda + \\lambda^2 + \\dots) \\\\\nS &= 1 + \\lambda S \\\\\nS &= 1 / (1-\\lambda)\n\\end{aligned}\n$$\nThis weighted sum of many n-step returns is called λ-return $G_t^{\\lambda} = (1-\\lambda) \\sum_{n=1}^{\\infty} \\lambda^{n-1} G_t^{(n)}$. TD learning that adopts λ-return for value updating is labeled as\nTD(λ)\n. The original version we introduced\nabove\nis equivalent to\nTD(0)\n.\nComparison of the backup diagrams of Monte-Carlo, Temporal-Difference learning, and Dynamic Programming for state value functions. (Image source: David Silver's RL course\nlecture 4\n: \"Model-Free Prediction\")\nPolicy Gradient\n#\nAll the methods we have introduced above aim to learn the state/action value function and then to select actions accordingly. Policy Gradient methods instead learn the policy directly with a parameterized function respect to $\\theta$, $\\pi(a \\vert s; \\theta)$. Let’s define the reward function (opposite of loss function) as\nthe expected return\nand train the algorithm with the goal to maximize the reward function. My\nnext post\ndescribed why the policy gradient theorem works (proof) and introduced a number of policy gradient algorithms.\nIn discrete space:\n$$\n\\mathcal{J}(\\theta) = V_{\\pi_\\theta}(S_1) = \\mathbb{E}_{\\pi_\\theta}[V_1]\n$$\nwhere $S_1$ is the initial starting state.\nOr in continuous space:\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) V_{\\pi_\\theta}(s) = \\sum_{s \\in \\mathcal{S}} \\Big( d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s, \\theta) Q_\\pi(s, a) \\Big)\n$$\nwhere $d_{\\pi_\\theta}(s)$ is stationary distribution of Markov chain for $\\pi_\\theta$. If you are unfamiliar with the definition of a “stationary distribution,” please check this\nreference\n.\nUsing\ngradient ascent\nwe can find the best θ that produces the highest return. It is natural to expect policy-based methods are more useful in continuous space, because there is an infinite number of actions and/or states to estimate the values for in continuous space and hence value-based approaches are computationally much more expensive.\nPolicy Gradient Theorem\n#\nComputing the gradient\nnumerically\ncan be done by perturbing θ by a small amount ε in the k-th dimension. It works even when $J(\\theta)$ is not differentiable (nice!), but unsurprisingly very slow.\n$$\n\\frac{\\partial \\mathcal{J}(\\theta)}{\\partial \\theta_k} \\approx \\frac{\\mathcal{J}(\\theta + \\epsilon u_k) - \\mathcal{J}(\\theta)}{\\epsilon}\n$$\nOr\nanalytically\n,\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [r] = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) R(s, a)\n$$\nActually we have nice theoretical support for (replacing $d(.)$ with $d_\\pi(.)$):\n$$\n\\mathcal{J}(\\theta) = \\sum_{s \\in \\mathcal{S}} d_{\\pi_\\theta}(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\propto \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a)\n$$\nCheck Sec 13.1 in Sutton & Barto (2017) for why this is the case.\nThen,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n\\nabla \\mathcal{J}(\\theta) &= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\nabla \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n&= \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\frac{\\nabla \\pi(a \\vert s; \\theta)}{\\pi(a \\vert s; \\theta)} Q_\\pi(s, a) \\\\\n& = \\sum_{s \\in \\mathcal{S}} d(s) \\sum_{a \\in \\mathcal{A}} \\pi(a \\vert s; \\theta) \\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a) \\\\\n& = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s; \\theta) Q_\\pi(s, a)]\n\\end{aligned}\n$$\nThis result is named “Policy Gradient Theorem” which lays the theoretical foundation for various policy gradient algorithms:\n$$\n\\nabla \\mathcal{J}(\\theta) = \\mathbb{E}_{\\pi_\\theta} [\\nabla \\ln \\pi(a \\vert s, \\theta) Q_\\pi(s, a)]\n$$\nREINFORCE\n#\nREINFORCE, also known as Monte-Carlo policy gradient, relies on $Q_\\pi(s, a)$, an estimated return by\nMC\nmethods using episode samples, to update the policy parameter $\\theta$.\nA commonly used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to reduce the variance of gradient estimation while keeping the bias unchanged. For example, a common baseline is state-value, and if applied, we would use $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update.\nInitialize θ at random\nGenerate one episode $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$\nFor t=1, 2, … , T:\nEstimate the the return G_t since the time step t.\n$\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla \\ln \\pi(A_t \\vert S_t, \\theta)$.\nActor-Critic\n#\nIf the value function is learned in addition to the policy, we would get Actor-Critic algorithm.\nCritic\n: updates value function parameters w and depending on the algorithm it could be action-value $Q(a \\vert s; w)$ or state-value $V(s; w)$.\nActor\n: updates policy parameters θ, in the direction suggested by the critic, $\\pi(a \\vert s; \\theta)$.\nLet’s see how it works in an action-value actor-critic algorithm.\nInitialize s, θ, w at random; sample $a \\sim \\pi(a \\vert s; \\theta)$.\nFor t = 1… T:\nSample reward $r_t  \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$.\nThen sample the next action $a’ \\sim \\pi(s’, a’; \\theta)$.\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q(s, a; w) \\nabla_\\theta \\ln \\pi(a \\vert s; \\theta)$.\nCompute the correction for action-value at time t:\n$G_{t:t+1} = r_t + \\gamma Q(s’, a’; w) - Q(s, a; w)$\nand use it to update value function parameters:\n$w \\leftarrow w + \\alpha_w G_{t:t+1} \\nabla_w Q(s, a; w) $.\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\n$\\alpha_\\theta$ and $\\alpha_w$ are two learning rates for policy and value function parameter updates, respectively.\nA3C\n#\nAsynchronous Advantage Actor-Critic\n(Mnih et al., 2016), short for A3C, is a classic policy gradient method with the special focus on parallel training.\nIn A3C, the critics learn the state-value function, $V(s; w)$, while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is good for parallel training by default, i.e. on one machine with multi-core CPU.\nThe loss function for state-value is to minimize the mean squared error, $\\mathcal{J}_v (w) = (G_t - V(s; w))^2$ and we use gradient descent to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, θ and w; similar thread-specific parameters, θ’ and w'.\nInitialize the time step t = 1\nWhile T <= T_MAX:\nReset gradient: dθ = 0 and dw = 0.\nSynchronize thread-specific parameters with global ones: θ’ = θ and w’ = w.\n$t_\\text{start}$ = t and get $s_t$.\nWhile ($s_t \\neq \\text{TERMINAL}$) and ($t - t_\\text{start} <= t_\\text{max}$):\nPick the action $a_t \\sim \\pi(a_t \\vert s_t; \\theta’)$ and receive a new reward $r_t$ and a new state $s_{t+1}$.\nUpdate t = t + 1 and T = T + 1.\nInitialize the variable that holds the return estimation $$R = \\begin{cases}\n0 & \\text{if } s_t \\text{ is TERMINAL} \\\nV(s_t; w’) & \\text{otherwise}\n\\end{cases}$$.\nFor $i = t-1, \\dots, t_\\text{start}$:\n$R \\leftarrow r_i + \\gamma R$; here R is a MC measure of $G_i$.\nAccumulate gradients w.r.t. θ’: $d\\theta \\leftarrow d\\theta + \\nabla_{\\theta’} \\log \\pi(a_i \\vert s_i; \\theta’)(R - V(s_i; w’))$;\nAccumulate gradients w.r.t. w’: $dw \\leftarrow dw + \\nabla_{w’} (R - V(s_i; w’))^2$.\nUpdate synchronously θ using dθ, and w using dw.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a reformation of minibatch-based stochastic gradient update: the values of w or θ get corrected by a little bit in the direction of each training thread independently.\nEvolution Strategies\n#\nEvolution Strategies\n(ES) is a type of model-agnostic optimization approach. It learns the optimal solution by imitating Darwin’s theory of the evolution of species by natural selection. Two prerequisites for applying ES: (1) our solutions can freely interact with the environment and see whether they can solve the problem; (2) we are able to compute a\nfitness\nscore of how good each solution is. We don’t have to know the environment configuration to solve the problem.\nSay, we start with a population of random solutions. All of them are capable of interacting with the environment and only candidates with high fitness scores can survive (\nonly the fittest can survive in a competition for limited resources\n). A new generation is then created by recombining the settings (\ngene mutation\n) of high-fitness survivors. This process is repeated until the new solutions are good enough.\nVery different from the popular MDP-based approaches as what we have introduced above, ES aims to learn the policy parameter $\\theta$ without value approximation. Let’s assume the distribution over the parameter $\\theta$ is an\nisotropic\nmultivariate Gaussian with mean $\\mu$ and fixed covariance $\\sigma^2I$. The gradient of $F(\\theta)$ is calculated:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} F(\\theta) \\\\\n=& \\nabla_\\theta \\int_\\theta F(\\theta) \\Pr(\\theta) && \\text{Pr(.) is the Gaussian density function.} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\frac{\\nabla_\\theta \\Pr(\\theta)}{\\Pr(\\theta)} \\\\\n=& \\int_\\theta F(\\theta) \\Pr(\\theta) \\nabla_\\theta \\log \\Pr(\\theta) \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} [F(\\theta) \\nabla_\\theta \\log \\Pr(\\theta)] && \\text{Similar to how we do policy gradient update.} \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\log \\Big( \\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(\\theta - \\mu)^2}{2 \\sigma^2 }} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\nabla_\\theta \\Big( -\\log \\sqrt{2\\pi\\sigma^2} - \\frac{(\\theta - \\mu)^2}{2 \\sigma^2} \\Big) \\Big] \\\\\n=& \\mathbb{E}_{\\theta \\sim N(\\mu, \\sigma^2)} \\Big[ F(\\theta) \\frac{\\theta - \\mu}{\\sigma^2} \\Big]\n\\end{aligned}\n$$\nWe can rewrite this formula in terms of a “mean” parameter $\\theta$ (different from the $\\theta$ above; this $\\theta$ is the base gene for further mutation), $\\epsilon \\sim N(0, I)$ and therefore $\\theta + \\epsilon \\sigma \\sim N(\\theta, \\sigma^2)$. $\\epsilon$ controls how much Gaussian noises should be added to create mutation:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\epsilon \\sim N(0, I)} F(\\theta + \\sigma \\epsilon) = \\frac{1}{\\sigma} \\mathbb{E}_{\\epsilon \\sim N(0, I)} [F(\\theta + \\sigma \\epsilon) \\epsilon]\n$$\nA simple parallel evolution-strategies-based RL algorithm. Parallel workers share the random seeds so that they can reconstruct the Gaussian noises with tiny communication bandwidth. (Image source: Salimans et al. 2017.)\nES, as a black-box optimization algorithm, is another approach to RL problems (\nIn my original writing, I used the phrase “a nice alternative”;\nSeita\npointed me to this\ndiscussion\nand thus I updated my wording.\n). It has a couple of good characteristics (Salimans et al., 2017) keeping it fast and easy to train:\nES does not need value function approximation;\nES does not perform gradient back-propagation;\nES is invariant to delayed or long-term rewards;\nES is highly parallelizable with very little data communication.\nKnown Problems\n#\nExploration-Exploitation Dilemma\n#\nThe problem of exploration vs exploitation dilemma has been discussed in my previous\npost\n. When the RL problem faces an unknown environment, this issue is especially a key to finding a good solution: without enough exploration, we cannot learn the environment well enough; without enough exploitation, we cannot complete our reward optimization task.\nDifferent RL algorithms balance between exploration and exploitation in different ways. In\nMC\nmethods,\nQ-learning\nor many on-policy algorithms, the exploration is commonly implemented by\nε-greedy\n; In\nES\n, the exploration is captured by the policy parameter perturbation. Please keep this into consideration when developing a new RL algorithm.\nDeadly Triad Issue\n#\nWe do seek the efficiency and flexibility of TD methods that involve bootstrapping. However, when off-policy, nonlinear function approximation, and bootstrapping are combined in one RL algorithm, the training could be unstable and hard to converge. This issue is known as the\ndeadly triad\n(Sutton & Barto, 2017). Many architectures using deep learning models were proposed to resolve the problem, including DQN to stabilize the training with experience replay and occasionally frozen target network.\nCase Study: AlphaGo Zero\n#\nThe game of\nGo\nhas been an extremely hard problem in the field of Artificial Intelligence for decades until recent years. AlphaGo and AlphaGo Zero are two programs developed by a team at DeepMind. Both involve deep Convolutional Neural Networks (\nCNN\n) and Monte Carlo Tree Search (MCTS) and both have been approved to achieve the level of professional human Go players. Different from AlphaGo that relied on supervised learning from expert human moves, AlphaGo Zero used only reinforcement learning and self-play without human knowledge beyond the basic rules.\nThe board of Go. Two players play black and white stones alternatively on the vacant intersections of a board with 19 x 19 lines. A group of stones must have at least one open point (an intersection, called a \"liberty\") to remain on the board and must have at least two or more enclosed liberties (called \"eyes\") to stay \"alive\". No stone shall repeat a previous position.\nWith all the knowledge of RL above, let’s take a look at how AlphaGo Zero works. The main component is a deep\nCNN\nover the game board configuration (precisely, a\nResNet\nwith batch normalization and ReLU). This network outputs two values:\n$$\n(p, v) = f_\\theta(s)\n$$\n$s$: the game board configuration, 19 x 19 x 17 stacked feature planes; 17 features for each position, 8 past configurations (including current) for the current player + 8 past configurations for the opponent + 1 feature indicating the color (1=black, 0=white). We need to code the color specifically because the network is playing with itself and the colors of current player and opponents are switching between steps.\n$p$: the probability of selecting a move over 19^2 + 1 candidates (19^2 positions on the board, in addition to passing).\n$v$: the winning probability given the current setting.\nDuring self-play, MCTS further improves the action probability distribution $\\pi \\sim p(.)$ and then the action $a_t$ is sampled from this improved policy. The reward $z_t$ is a binary value indicating whether the current player\neventually\nwins the game. Each move generates an episode tuple $(s_t, \\pi_t, z_t)$ and it is saved into the replay memory. The details on MCTS are skipped for the sake of space in this post; please read the original\npaper\nif you are interested.\nAlphaGo Zero is trained by self-play while MCTS improves the output policy further in every step. (Image source: Figure 1a in Silver et al., 2017).\nThe network is trained with the samples in the replay memory to minimize the loss:\n$$\n\\mathcal{L} = (z - v)^2 - \\pi^\\top \\log p + c \\| \\theta \\|^2\n$$\nwhere $c$ is a hyperparameter controlling the intensity of L2 penalty to avoid overfitting.\nAlphaGo Zero simplified AlphaGo by removing supervised learning and merging separated policy and value networks into one. It turns out that AlphaGo Zero achieved largely improved performance with a much shorter training time! I strongly recommend reading these\ntwo\npapers\nside by side and compare the difference, super fun.\nI know this is a long read, but hopefully worth it.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com].\nSee you in the next post! :)\nCited as:\n@article{weng2018bandit,\n  title   = \"A (Long) Peek into Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-02-19-rl-overview/\"\n}\nReferences\n#\n[1] Yuxi Li.\nDeep reinforcement learning: An overview.\narXiv preprint arXiv:1701.07274. 2017.\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] Volodymyr Mnih, et al.\nAsynchronous methods for deep reinforcement learning.\nICML. 2016.\n[4] Tim Salimans, et al.\nEvolution strategies as a scalable alternative to reinforcement learning.\narXiv preprint arXiv:1703.03864 (2017).\n[5] David Silver, et al.\nMastering the game of go without human knowledge\n. Nature 550.7676 (2017): 354.\n[6] David Silver, et al.\nMastering the game of Go with deep neural networks and tree search.\nNature 529.7587 (2016): 484-489.\n[7] Volodymyr Mnih, et al.\nHuman-level control through deep reinforcement learning.\nNature 518.7540 (2015): 529.\n[8] Ziyu Wang, et al.\nDueling network architectures for deep reinforcement learning.\nICML. 2016.\n[9]\nReinforcement Learning lectures\nby David Silver on YouTube.\n[10] OpenAI Blog:\nEvolution Strategies as a Scalable Alternative to Reinforcement Learning\n[11] Frank Sehnke, et al.\nParameter-exploring policy gradients.\nNeural Networks 23.4 (2010): 551-559.\n[12] Csaba Szepesvári.\nAlgorithms for reinforcement learning.\n1st Edition. Synthesis lectures on artificial intelligence and machine learning 4.1 (2010): 1-103.\nIf you notice mistakes and errors in this post, please don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be super happy to correct them right away!",
            "metadata": {
              "title": "A (Long) Peek into Reinforcement Learning | Lil'Log",
              "description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "A (Long) Peek into Reinforcement Learning",
              "og:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
              "twitter:card": "summary",
              "twitter:title": "A (Long) Peek into Reinforcement Learning",
              "twitter:description": "[Updated on 2020-09-03: Updated the algorithm of SARSA and Q-learning so that the difference is more pronounced.\n\n[Updated on 2021-09-19: Thanks to 爱吃猫的鱼, we have this post in Chinese].",
              "article:section": "posts",
              "article:published_time": "2018-02-19T00:00:00+00:00",
              "article:modified_time": "2018-02-19T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/9e1d58627b38/code/body-000.txt",
                "chars": 241,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "bytes": 58269,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-418c8992a5cc9d9deeb1.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "bytes": 107025,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d53eaab123d7a3b8d561.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/RL_algorithm_categorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "bytes": 33772,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-1a3ee27cdec9dd4e95e7.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/agent_environment_MDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "bytes": 55693,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8b930e0942e1d249d7cd.jpg",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/mdp_example.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "bytes": 27143,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-508e643f8751bb71fcf3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/bellman_equation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "bytes": 32728,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-aa4ac628fe85693e0ba3.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/MC_control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "bytes": 21618,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-8917c12943284b1507b6.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/sarsa_vs_q_learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "bytes": 133435,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-c1fcc0568374ce65ea91.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/DQN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "bytes": 35850,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-be7712dd68a63d561005.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_lambda.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "bytes": 128382,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-d374974862f12f0f0ada.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/TD_MC_DP_backups.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "bytes": 91431,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-0d8b962a59d7ad31b2ef.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/EA_RL_parallel.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "bytes": 136647,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-3ceb5a7713444f264e70.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/go_config.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "bytes": 61555,
                "reused": false,
                "local_path": "attachments/9e1d58627b38/images/body-070437b06f4b4d8a0287.png",
                "src": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/alphago-zero-selfplay.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=2pWv7GOvuf0",
                "src": "https://youtu.be/2pWv7GOvuf0",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/9e1d58627b38/videos/repair-2pWv7GOvuf0.mp4",
                "bytes": 397520008,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "5292.421000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "src": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "status": "playlist_discovery_failed",
                "kind": "playlist",
                "reason": "播放列表返回空或不完整结果，保留原记录并等待重试",
                "error": "WARNING: [youtube:tab] YouTube said: The playlist does not exist.\nERROR: [youtube:tab] PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT: YouTube said: The playlist does not exist.\n",
                "retried_at": "2026-10-20T22:23:33Z"
              }
            ],
            "links": [
              {
                "href": "https://paperexplained.cn/articles/article/detail/33/",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dynamic_programming",
                "label": "Dynamic Programming",
                "type": "a"
              },
              {
                "href": "https://youtu.be/2pWv7GOvuf0",
                "label": "lecture 1",
                "type": "a"
              },
              {
                "href": "https://randomant.net/reinforcement-learning-concepts/",
                "label": "randomant.net/reinforcement-learning-concepts",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "ε-greedy",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "label": "Watkins & Dayan, 1992",
                "type": "a"
              },
              {
                "href": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "label": "lecture 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "next post",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "reference",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolution Strategies",
                "type": "a"
              },
              {
                "href": "https://math.stackexchange.com/questions/1991961/gaussian-distribution-is-isotropic",
                "label": "isotropic",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/",
                "label": "Seita",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/r/MachineLearning/comments/6gke6a/d_requesting_openai_to_justify_the_grandiose/dir9wde/",
                "label": "discussion",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Go_(game)",
                "label": "Go",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "CNN",
                "type": "a"
              },
              {
                "href": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "label": "two",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07274.pdf",
                "label": "Deep reinforcement learning: An overview.",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Reinforcement Learning: An Introduction; 2nd Edition",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "label": "Asynchronous methods for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.03864.pdf",
                "label": "Evolution strategies as a scalable alternative to reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "label": "Human-level control through deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.06581.pdf",
                "label": "Dueling network architectures for deep reinforcement learning.",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/playlist?list=PL7-jPKtc4r78-wCZcQn5IqyuWhBZ8fOxT",
                "label": "Reinforcement Learning lectures",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/evolution-strategies/",
                "label": "Evolution Strategies as a Scalable Alternative to Reinforcement Learning",
                "type": "a"
              },
              {
                "href": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "label": "Parameter-exploring policy gradients.",
                "type": "a"
              },
              {
                "href": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "label": "Algorithms for reinforcement learning.",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:33Z",
            "source_url": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
            "papers": [
              {
                "status": "invalid_file_type",
                "url": "https://link.springer.com/content/pdf/10.1007/BF00992698.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:14Z"
              },
              {
                "status": "http_404",
                "url": "http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MC-TD.pdf",
                "retried_at": "2026-10-20T17:36:31Z"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.dropbox.com/s/yva172qos2u15hf/2017-silver.pdf?dl=0",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/1740/eb993cc8ca81f1e46ddaadce1f917e8000b5.pdf",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07274.pdf",
                "bytes": 1380080,
                "reused": false,
                "local_path": "papers/repair/b6ffc91d59527939bdfc.pdf"
              },
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": true,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/mniha16.pdf",
                "bytes": 2455923,
                "reused": false,
                "local_path": "papers/repair/de6e461fa7ff09fc7981.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864.pdf",
                "bytes": 277340,
                "reused": false,
                "local_path": "papers/repair/d7a6ba3d9a896a29908d.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.swarthmore.edu/~meeden/cs63/s15/nature15b.pdf",
                "bytes": 4600582,
                "reused": false,
                "local_path": "papers/repair/a86f4e3a12fbcea87e0c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06581.pdf",
                "bytes": 688509,
                "reused": false,
                "local_path": "papers/repair/f1c991f0c8eda83cb980.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://mediatum.ub.tum.de/doc/1287490/file.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:36:15Z"
              },
              {
                "status": "ok",
                "url": "https://sites.ualberta.ca/~szepesva/papers/RLAlgsInMDPs.pdf",
                "bytes": 1623436,
                "reused": false,
                "local_path": "papers/repair/fbf59542cdbde527181b.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 40855,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404；invalid_file_type；playlist_discovery_failed",
            "raw_html": "attachments/9e1d58627b38/pages/source.html",
            "local_html": "attachments/9e1d58627b38/pages/article.html",
            "body_base_path": "attachments/9e1d58627b38/pages/",
            "body_markdown_path": "attachments/9e1d58627b38/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
          "status": "partial",
          "article_id": "ebc73787cbe5",
          "local_path": "series-follow/1601/repair/ffba49f79f0eef15a925.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
              "bytes": 259350,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/394ec3f8b6a6ccc3dace.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
              "bytes": 205392,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9c60abbe659d28457d7a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
              "bytes": 275060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a8004105b4a88c05a952.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
              "bytes": 581593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7bc12620d13d41e17f0a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
              "bytes": 215084,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a1617c1aadd4262ae84a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
              "bytes": 181566,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/01ca9a7ea1e7d1cd82a2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
              "bytes": 294810,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a362a645159f0dafa82d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
              "bytes": 860130,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/fafbbe0c69813ea86bf2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
              "bytes": 742699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d58e26716f1f269dae8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
              "bytes": 300409,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5e0d3d90650b6cca848e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
              "bytes": 497568,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a29af53d479214903180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
              "bytes": 332210,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0061164751ee7e193a70.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
              "bytes": 253972,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/58ac4a854eb578c151aa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
              "bytes": 567524,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6b398117113938e66d50.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Policy Gradient Algorithms",
            "keywords": "策略梯度,PG,强化学习",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "publish_date": "2018-04",
            "corpus_stage": "强化学习/对齐",
            "notes": "策略梯度算法大全（REINFORCE、PPO等）",
            "id": "ebc73787cbe5",
            "collected_at": "2026-10-02T14:13:21",
            "title": "Policy Gradient Algorithms | Lil'Log",
            "body_markdown": "[Updated on 2018-06-30: add two new policy gradient methods,\nSAC\nand\nD4PG\n.]\n[Updated on 2018-09-30: add a new policy gradient method,\nTD3\n.]\n[Updated on 2019-02-09: add\nSAC with automatically adjusted temperature\n].\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in\nKorean\n].\n[Updated on 2019-09-12: add a new policy gradient method\nSVPG\n.]\n[Updated on 2019-12-22: add a new policy gradient method\nIMPALA\n.]\n[Updated on 2020-10-15: add a new policy gradient method\nPPG\n& some new discussion in\nPPO\n.]\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in\nChinese1\n&\nChinese2\n].\nWhat is Policy Gradient\n#\nPolicy gradient is an approach to solve reinforcement learning problems. If you haven’t looked into the field of reinforcement learning, please first read the section\n“A (Long) Peek into Reinforcement Learning » Key Concepts”\nfor the problem definition and key concepts.\nNotations\n#\nHere is a list of notations to help you read through equations in the post easily.\nSymbol\nMeaning\n$s \\in \\mathcal{S}$\nStates.\n$a \\in \\mathcal{A}$\nActions.\n$r \\in \\mathcal{R}$\nRewards.\n$S_t, A_t, R_t$\nState, action, and reward at time step $t$ of one trajectory. I may occasionally use $s_t, a_t, r_t$ as well.\n$\\gamma$\nDiscount factor; penalty to uncertainty of future rewards; $0<\\gamma \\leq 1$.\n$G_t$\nReturn; or discounted future reward; $G_t = \\sum_{k=0}^{\\infty} \\gamma^k R_{t+k+1}$.\n$P(s’, r \\vert s, a)$\nTransition probability of getting to the next state $s’$ from the current state $s$ with action $a$ and reward $r$.\n$\\pi(a \\vert s)$\nStochastic policy (agent behavior strategy); $\\pi_\\theta(.)$ is a policy parameterized by $\\theta$.\n$\\mu(s)$\nDeterministic policy; we can also label this as $\\pi(s)$, but using a different letter gives better distinction so that we can easily tell when the policy is stochastic or deterministic without further explanation. Either $\\pi$ or $\\mu$ is what a reinforcement learning algorithm aims to learn.\n$V(s)$\nState-value function measures the expected return of state $s$; $V_w(.)$ is a value function parameterized by $w$.\n$V^\\pi(s)$\nThe value of state $s$ when we follow a policy $\\pi$; $V^\\pi (s) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s]$.\n$Q(s, a)$\nAction-value function is similar to $V(s)$, but it assesses the expected return of a pair of state and action $(s, a)$; $Q_w(.)$ is a action value function parameterized by $w$.\n$Q^\\pi(s, a)$\nSimilar to $V^\\pi(.)$, the value of (state, action) pair when we follow a policy $\\pi$; $Q^\\pi(s, a) = \\mathbb{E}_{a\\sim \\pi} [G_t \\vert S_t = s, A_t = a]$.\n$A(s, a)$\nAdvantage function, $A(s, a) = Q(s, a) - V(s)$; it can be considered as another version of Q-value with lower variance by taking the state-value off as the baseline.\nPolicy Gradient\n#\nThe goal of reinforcement learning is to find an optimal behavior strategy for the agent to obtain optimal rewards. The\npolicy gradient\nmethods target at modeling and optimizing the policy directly. The policy is usually modeled with a parameterized function respect to $\\theta$, $\\pi_\\theta(a \\vert s)$. The value of the reward (objective) function depends on this policy and then various algorithms can be applied to optimize $\\theta$ for the best reward.\nThe reward function is defined as:\n$$\nJ(\\theta) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) V^\\pi(s) \n= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a)\n$$\nwhere $d^\\pi(s)$ is the stationary distribution of Markov chain for $\\pi_\\theta$ (on-policy state distribution under $\\pi$). For simplicity, the parameter $\\theta$ would be omitted for the policy $\\pi_\\theta$ when the policy is present in the subscript of other functions; for example, $d^{\\pi}$ and $Q^\\pi$ should be $d^{\\pi_\\theta}$ and $Q^{\\pi_\\theta}$ if written in full.\nImagine that you can travel along the Markov chain’s states forever, and eventually, as the time progresses, the probability of you ending up with one state becomes unchanged — this is the stationary probability for $\\pi_\\theta$. $d^\\pi(s) = \\lim_{t \\to \\infty} P(s_t = s \\vert s_0, \\pi_\\theta)$ is the probability that $s_t=s$ when starting from $s_0$ and following policy $\\pi_\\theta$ for t steps. Actually, the existence of the stationary distribution of Markov chain is one main reason for why PageRank algorithm works. If you want to read more, check\nthis\n.\nIt is natural to expect policy-based methods are more useful in the continuous space. Because there is an infinite number of actions and (or) states to estimate the values for and hence value-based approaches are way too expensive computationally in the continuous space. For example, in\ngeneralized policy iteration\n, the policy improvement step $\\arg\\max_{a \\in \\mathcal{A}} Q^\\pi(s, a)$ requires a full scan of the action space, suffering from the\ncurse of dimensionality\n.\nUsing\ngradient ascent\n, we can move $\\theta$ toward the direction suggested by the gradient $\\nabla_\\theta J(\\theta)$ to find the best $\\theta$ for $\\pi_\\theta$ that produces the highest return.\nPolicy Gradient Theorem\n#\nComputing the gradient $\\nabla_\\theta J(\\theta)$ is tricky because it depends on both the action selection (directly determined by $\\pi_\\theta$) and the stationary distribution of states following the target selection behavior (indirectly determined by $\\pi_\\theta$). Given that the environment is generally unknown, it is difficult to estimate the effect on the state distribution by a policy update.\nLuckily, the\npolicy gradient theorem\ncomes to save the world! Woohoo! It provides a nice reformation of the derivative of the objective function to not involve the derivative of the state distribution $d^\\pi(.)$ and simplify the gradient computation $\\nabla_\\theta J(\\theta)$ a lot.\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\nabla_\\theta \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\\\\n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \n\\end{aligned}\n$$\nProof of Policy Gradient Theorem\n#\nThis session is pretty dense, as it is the time for us to go through the proof (\nSutton & Barto, 2017\n; Sec. 13.1) and figure out why the policy gradient theorem is correct.\nWe first start with the derivative of the state value function:\n$$\n\\begin{aligned}\n& \\nabla_\\theta V^\\pi(s) \\\\\n=& \\nabla_\\theta \\Big(\\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s)Q^\\pi(s, a) \\Big) & \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta Q^\\pi(s, a)} \\Big) & \\scriptstyle{\\text{; Derivative product rule.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\nabla_\\theta \\sum_{s', r} P(s',r \\vert s,a)(r + V^\\pi(s'))} \\Big) & \\scriptstyle{\\text{; Extend } Q^\\pi \\text{ with future state value.}} \\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s', r} P(s',r \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{P(s',r \\vert s,a) \\text{ or } r \\text{ is not a func of }\\theta}\\\\\n=& \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\color{red}{\\sum_{s'} P(s' \\vert s,a) \\nabla_\\theta V^\\pi(s')} \\Big) & \\scriptstyle{\\text{; Because }  P(s' \\vert s, a) = \\sum_r P(s', r \\vert s, a)}\n\\end{aligned}\n$$\nNow we have:\n$$\n\\color{red}{\\nabla_\\theta V^\\pi(s)} \n= \\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) + \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\Big)\n$$\nThis equation has a nice recursive form (see the red parts!) and the future state value function $V^\\pi(s’)$ can be repeated unrolled by following the same equation.\nLet’s consider the following visitation sequence and label the probability of transitioning from state s to state x with policy $\\pi_\\theta$ after k step as $\\rho^\\pi(s \\to x, k)$.\n$$\ns \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s)} s' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s')} s'' \\xrightarrow[]{a \\sim \\pi_\\theta(.\\vert s'')} \\dots\n$$\nWhen k = 0: $\\rho^\\pi(s \\to s, k=0) = 1$.\nWhen k = 1, we scan through all possible actions and sum up the transition probabilities to the target state: $\\rho^\\pi(s \\to s’, k=1) = \\sum_a \\pi_\\theta(a \\vert s) P(s’ \\vert s, a)$.\nImagine that the goal is to go from state s to x after k+1 steps while following policy $\\pi_\\theta$. We can first travel from s to a middle point s’ (any state can be a middle point, $s’ \\in \\mathcal{S}$) after k steps and then go to the final state x during the last step. In this way, we are able to update the visitation probability recursively: $\\rho^\\pi(s \\to x, k+1) = \\sum_{s’} \\rho^\\pi(s \\to s’, k) \\rho^\\pi(s’ \\to x, 1)$.\nThen we go back to unroll the recursive representation of $\\nabla_\\theta V^\\pi(s)$! Let $\\phi(s) = \\sum_{a \\in \\mathcal{A}} \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a)$ to simplify the maths. If we keep on extending $\\nabla_\\theta V^\\pi(.)$ infinitely, it is easy to find out that we can transition from the starting state s to any state after any number of steps in this unrolling process and by summing up all the visitation probabilities, we get $\\nabla_\\theta V^\\pi(s)$!\n$$\n\\begin{aligned}\n& \\color{red}{\\nabla_\\theta V^\\pi(s)} \\\\\n=& \\phi(s) + \\sum_a \\pi_\\theta(a \\vert s) \\sum_{s'} P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\sum_a \\pi_\\theta(a \\vert s) P(s' \\vert s,a) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\nabla_\\theta V^\\pi(s')} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{\\sum_{a \\in \\mathcal{A}} \\Big( \\nabla_\\theta \\pi_\\theta(a \\vert s')Q^\\pi(s', a) + \\pi_\\theta(a \\vert s') \\sum_{s'} P(s'' \\vert s',a) \\nabla_\\theta V^\\pi(s'') \\Big)} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\color{red}{[ \\phi(s') + \\sum_{s''} \\rho^\\pi(s' \\to s'', 1) \\nabla_\\theta V^\\pi(s'')]} \\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\color{red}{\\nabla_\\theta V^\\pi(s'')} \\scriptstyle{\\text{ ; Consider }s'\\text{ as the middle point for }s \\to s''}\\\\\n=& \\phi(s) + \\sum_{s'} \\rho^\\pi(s \\to s', 1) \\phi(s') + \\sum_{s''} \\rho^\\pi(s \\to s'', 2)\\phi(s'') + \\sum_{s'''} \\rho^\\pi(s \\to s''', 3)\\color{red}{\\nabla_\\theta V^\\pi(s''')} \\\\\n=& \\dots \\scriptstyle{\\text{; Repeatedly unrolling the part of }\\nabla_\\theta V^\\pi(.)} \\\\\n=& \\sum_{x\\in\\mathcal{S}}\\sum_{k=0}^\\infty \\rho^\\pi(s \\to x, k) \\phi(x)\n\\end{aligned}\n$$\nThe nice rewriting above allows us to exclude the derivative of Q-value function, $\\nabla_\\theta Q^\\pi(s, a)$. By plugging it into the objective function $J(\\theta)$, we are getting the following:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta V^\\pi(s_0) & \\scriptstyle{\\text{; Starting from a random state } s_0} \\\\\n&= \\sum_{s}\\color{blue}{\\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)} \\phi(s) &\\scriptstyle{\\text{; Let }\\color{blue}{\\eta(s) = \\sum_{k=0}^\\infty \\rho^\\pi(s_0 \\to s, k)}} \\\\\n&= \\sum_{s}\\eta(s) \\phi(s) & \\\\\n&= \\Big( {\\sum_s \\eta(s)} \\Big)\\sum_{s}\\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\text{; Normalize } \\eta(s), s\\in\\mathcal{S} \\text{ to be a probability distribution.}}\\\\\n&\\propto \\sum_s \\frac{\\eta(s)}{\\sum_s \\eta(s)} \\phi(s) & \\scriptstyle{\\sum_s \\eta(s)\\text{  is a constant}} \\\\\n&= \\sum_s d^\\pi(s) \\sum_a \\nabla_\\theta \\pi_\\theta(a \\vert s)Q^\\pi(s, a) & \\scriptstyle{d^\\pi(s) = \\frac{\\eta(s)}{\\sum_s \\eta(s)}\\text{ is stationary distribution.}}\n\\end{aligned}\n$$\nIn the episodic case, the constant of proportionality ($\\sum_s \\eta(s)$) is the average length of an episode; in the continuing case, it is 1 (\nSutton & Barto, 2017\n; Sec. 13.2). The gradient can be further written as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\propto \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s)  &\\\\\n&= \\sum_{s \\in \\mathcal{S}} d^\\pi(s) \\sum_{a \\in \\mathcal{A}} \\pi_\\theta(a \\vert s) Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} &\\\\\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\scriptstyle{\\text{; Because } (\\ln x)' = 1/x}\n\\end{aligned}\n$$\nWhere $\\mathbb{E}_\\pi$ refers to $\\mathbb{E}_{s \\sim d_\\pi, a \\sim \\pi_\\theta}$ when both state and action distributions follow the policy $\\pi_\\theta$ (on policy).\nThe policy gradient theorem lays the theoretical foundation for various policy gradient algorithms. This vanilla policy gradient update has no bias but high variance. Many following algorithms were proposed to reduce the variance while keeping the bias unchanged.\n$$\n\\nabla_\\theta J(\\theta)  = \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)]\n$$\nHere is a nice summary of a general form of policy gradient methods borrowed from the\nGAE\n(general advantage estimation) paper (\nSchulman et al., 2016\n) and this\npost\nthoroughly discussed several components in GAE , highly recommended.\nA general form of policy gradient methods. (Image source:\nSchulman et al., 2016\n)\nPolicy Gradient Algorithms\n#\nTons of policy gradient algorithms have been proposed during recent years and there is no way for me to exhaust them. I’m introducing some of them that I happened to know and read about.\nREINFORCE\n#\nREINFORCE\n(Monte-Carlo policy gradient) relies on an estimated return by\nMonte-Carlo\nmethods using episode samples to update the policy parameter $\\theta$. REINFORCE works because the expectation of the sample gradient is equal to the actual gradient:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\mathbb{E}_\\pi [Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)] & \\\\\n&= \\mathbb{E}_\\pi [G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)] & \\scriptstyle{\\text{; Because } Q^\\pi(S_t, A_t) = \\mathbb{E}_\\pi[G_t \\vert S_t, A_t]}\n\\end{aligned}\n$$\nTherefore we are able to measure $G_t$ from real sample trajectories and use that to update our policy gradient. It relies on a full trajectory and that’s why it is a Monte-Carlo method.\nThe process is pretty straightforward:\nInitialize the policy parameter $\\theta$ at random.\nGenerate one trajectory on policy $\\pi_\\theta$: $S_1, A_1, R_2, S_2, A_2, \\dots, S_T$.\nFor t=1, 2, … , T:\nEstimate the the return $G_t$;\nUpdate policy parameters: $\\theta \\leftarrow \\theta + \\alpha \\gamma^t G_t \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)$\nA widely used variation of REINFORCE is to subtract a baseline value from the return $G_t$ to\nreduce the variance of gradient estimation while keeping the bias unchanged\n(Remember we always want to do this when possible). For example, a common baseline is to subtract state-value from action-value, and if applied, we would use advantage $A(s, a) = Q(s, a) - V(s)$ in the gradient ascent update. This\npost\nnicely explained why a baseline works for reducing the variance, in addition to a set of fundamentals of policy gradient.\nActor-Critic\n#\nTwo main components in policy gradient are the policy model and the value function. It makes a lot of sense to learn the value function in addition to the policy, since knowing the value function can assist the policy update, such as by reducing gradient variance in vanilla policy gradients, and that is exactly what the\nActor-Critic\nmethod does.\nActor-critic methods consist of two models, which may optionally share parameters:\nCritic\nupdates the value function parameters w and depending on the algorithm it could be action-value $Q_w(a \\vert s)$ or state-value $V_w(s)$.\nActor\nupdates the policy parameters $\\theta$ for $\\pi_\\theta(a \\vert s)$, in the direction suggested by the critic.\nLet’s see how it works in a simple action-value actor-critic algorithm.\nInitialize $s, \\theta, w$ at random; sample $a \\sim \\pi_\\theta(a \\vert s)$.\nFor $t = 1 \\dots T$:\nSample reward $r_t \\sim R(s, a)$ and next state $s’ \\sim P(s’ \\vert s, a)$;\nThen sample the next action $a’ \\sim \\pi_\\theta(a’ \\vert s’)$;\nUpdate the policy parameters: $\\theta \\leftarrow \\theta + \\alpha_\\theta Q_w(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s)$;\nCompute the correction (TD error) for action-value at time t:\n$\\delta_t = r_t + \\gamma Q_w(s’, a’) - Q_w(s, a)$\nand use it to update the parameters of action-value function:\n$w \\leftarrow w + \\alpha_w \\delta_t \\nabla_w Q_w(s, a)$\nUpdate $a \\leftarrow a’$ and $s \\leftarrow s’$.\nTwo learning rates, $\\alpha_\\theta$ and $\\alpha_w$, are predefined for policy and value function parameter updates respectively.\nOff-Policy Policy Gradient\n#\nBoth REINFORCE and the vanilla version of actor-critic method are on-policy: training samples are collected according to the target policy — the very same policy that we try to optimize for. Off policy methods, however, result in several additional advantages:\nThe off-policy approach does not require full trajectories and can reuse any past episodes (\n“experience replay”\n) for much better sample efficiency.\nThe sample collection follows a behavior policy different from the target policy, bringing better\nexploration\n.\nNow let’s see how off-policy policy gradient is computed. The behavior policy for collecting samples is a known policy (predefined just like a hyperparameter), labelled as $\\beta(a \\vert s)$. The objective function sums up the reward over the state distribution defined by this behavior policy:\n$$\nJ(\\theta)\n= \\sum_{s \\in \\mathcal{S}} d^\\beta(s) \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)\n= \\mathbb{E}_{s \\sim d^\\beta} \\big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s) \\big]\n$$\nwhere $d^\\beta(s)$ is the stationary distribution of the behavior policy $\\beta$; recall that $d^\\beta(s) = \\lim_{t \\to \\infty} P(S_t = s \\vert S_0, \\beta)$; and $Q^\\pi$ is the action-value function estimated with regard to the target policy $\\pi$ (not the behavior policy!).\nGiven that the training observations are sampled by $a \\sim \\beta(a \\vert s)$, we can rewrite the gradient as:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta)\n&= \\nabla_\\theta \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\pi_\\theta(a \\vert s)  \\Big] & \\\\ \n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\big( Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) + \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)} \\big) \\Big] & \\scriptstyle{\\text{; Derivative product rule.}}\\\\\n&\\stackrel{(i)}{\\approx} \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} Q^\\pi(s, a) \\nabla_\\theta \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; Ignore the red part: } \\color{red}{\\pi_\\theta(a \\vert s) \\nabla_\\theta Q^\\pi(s, a)}}. \\\\\n&= \\mathbb{E}_{s \\sim d^\\beta} \\Big[ \\sum_{a \\in \\mathcal{A}} \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} Q^\\pi(s, a) \\frac{\\nabla_\\theta \\pi_\\theta(a \\vert s)}{\\pi_\\theta(a \\vert s)} \\Big] & \\\\\n&= \\mathbb{E}_\\beta \\Big[\\frac{\\color{blue}{\\pi_\\theta(a \\vert s)}}{\\color{blue}{\\beta(a \\vert s)}} Q^\\pi(s, a) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert s) \\Big] & \\scriptstyle{\\text{; The blue part is the importance weight.}}\n\\end{aligned}\n$$\nwhere $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$ is the\nimportance weight\n. Because $Q^\\pi$ is a function of the target policy and thus a function of policy parameter $\\theta$,  we should take the derivative of $\\nabla_\\theta Q^\\pi(s, a)$ as well according to the product rule. However, it is super hard to compute $\\nabla_\\theta Q^\\pi(s, a)$ in reality. Fortunately if we use an approximated gradient with the gradient of Q ignored, we still guarantee the policy improvement and eventually achieve the true local minimum. This is justified in the proof\nhere\n(Degris, White & Sutton, 2012).\nIn summary, when applying policy gradient in the off-policy setting, we can simple adjust it with a weighted sum and the weight is the ratio of the target policy to the behavior policy, $\\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)}$.\nA3C\n#\n[\npaper\n|\ncode\n]\nAsynchronous Advantage Actor-Critic\n(\nMnih et al., 2016\n), short for\nA3C\n, is a classic policy gradient method with a special focus on parallel training.\nIn A3C, the critics learn the value function while multiple actors are trained in parallel and get synced with global parameters from time to time. Hence, A3C is designed to work well for parallel training.\nLet’s use the state-value function as an example. The loss function for state value is to minimize the mean squared error, $J_v(w) = (G_t - V_w(s))^2$ and gradient descent can be applied to find the optimal w. This state-value function is used as the baseline in the policy gradient update.\nHere is the algorithm outline:\nWe have global parameters, $\\theta$ and $w$; similar thread-specific parameters, $\\theta’$ and $w’$.\nInitialize the time step $t = 1$\nWhile $T \\leq T_\\text{MAX}$:\nReset gradient: $\\mathrm{d}\\theta = 0$ and $\\mathrm{d}w = 0$.\nSynchronize thread-specific parameters with global ones: $\\theta’ = \\theta$ and $w’ = w$.\n$t_\\text{start}$ = t and sample a starting state $s_t$.\nWhile ($s_t$ != TERMINAL) and $t - t_\\text{start} \\leq t_\\text{max}$:\nPick the action $A_t \\sim \\pi_{\\theta’}(A_t \\vert S_t)$ and receive a new reward $R_t$ and a new state $s_{t+1}$.\nUpdate $t = t + 1$ and $T = T + 1$\nInitialize the variable that holds the return estimation\n$$\n R = \\begin{cases} \n 0 & \\text{if } s_t \\text{ is TERMINAL} \\\\\n V_{w'}(s_t) & \\text{otherwise}\n \\end{cases}\n $$\n6. For $i = t-1, \\dots, t\\_\\text{start}$:\n     1. $R \\leftarrow \\gamma R + R\\_i$; here R is a MC measure of $G\\_i$.\n     2. Accumulate gradients w.r.t. $\\theta'$: $d\\theta \\leftarrow d\\theta + \\nabla\\_{\\theta'} \\log \\pi\\_{\\theta'}(a\\_i \\vert s\\_i)(R - V\\_{w'}(s\\_i))$;\nAccumulate gradients w.r.t. w': $dw \\leftarrow dw + 2 (R - V\\_{w'}(s\\_i)) \\nabla\\_{w'} (R - V\\_{w'}(s\\_i))$.\nUpdate asynchronously $\\theta$ using $\\mathrm{d}\\theta$, and $w$ using $\\mathrm{d}w$.\nA3C enables the parallelism in multiple agent training. The gradient accumulation step (6.2) can be considered as a parallelized reformation of minibatch-based stochastic gradient update: the values of $w$ or $\\theta$ get corrected by a little bit in the direction of each training thread independently.\nA2C\n#\n[\npaper\n|\ncode\n]\nA2C\nis a synchronous, deterministic version of A3C; that’s why it is named as “A2C” with the first “A” (“asynchronous”) removed. In A3C each agent talks to the global parameters independently, so it is possible sometimes the thread-specific agents would be playing with policies of different versions and therefore the aggregated update would not be optimal. To resolve the inconsistency, a coordinator in A2C waits for all the parallel actors to finish their work before updating the global parameters and then in the next iteration parallel actors starts from the same policy. The synchronized gradient update keeps the training more cohesive and potentially to make convergence faster.\nA2C has been\nshown\nto be able to utilize GPUs more efficiently and work better with large batch sizes while achieving same or better performance than A3C.\nThe architecture of A3C versus A2C.\nDPG\n#\n[\npaper\n|code]\nIn methods described above, the policy function $\\pi(. \\vert s)$ is always modeled as a probability distribution over actions $\\mathcal{A}$ given the current state and thus it is\nstochastic\n.\nDeterministic policy gradient (DPG)\ninstead models the policy as a deterministic decision: $a = \\mu(s)$. It may look bizarre — how can you calculate the gradient of the action probability when it outputs a single action? Let’s look into it step by step.\nRefresh on a few notations to facilitate the discussion:\n$\\rho_0(s)$: The initial distribution over states\n$\\rho^\\mu(s \\to s’, k)$: Starting from state s, the visitation probability density at state s’ after moving k steps by policy $\\mu$.\n$\\rho^\\mu(s’)$: Discounted state distribution, defined as $\\rho^\\mu(s’) = \\int_\\mathcal{S} \\sum_{k=1}^\\infty \\gamma^{k-1} \\rho_0(s) \\rho^\\mu(s \\to s’, k) ds$.\nThe objective function to optimize for is listed as follows:\n$$\nJ(\\theta) = \\int_\\mathcal{S} \\rho^\\mu(s) Q(s, \\mu_\\theta(s)) ds\n$$\nDeterministic policy gradient theorem\n: Now it is the time to compute the gradient! According to the chain rule, we first take the gradient of Q w.r.t. the action a and then take the gradient of the deterministic policy function $\\mu$ w.r.t. $\\theta$:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&= \\int_\\mathcal{S} \\rho^\\mu(s) \\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)} ds \\\\\n&= \\mathbb{E}_{s \\sim \\rho^\\mu} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}]\n\\end{aligned}\n$$\nWe can consider the deterministic policy as a\nspecial case\nof the stochastic one, when the probability distribution contains only one extreme non-zero value over one action. Actually, in the DPG\npaper\n, the authors have shown that if the stochastic policy $\\pi_{\\mu_\\theta, \\sigma}$ is re-parameterized by a deterministic policy $\\mu_\\theta$ and a variation variable $\\sigma$, the stochastic policy is eventually equivalent to the deterministic case when $\\sigma=0$. Compared to the deterministic policy, we expect the stochastic policy to require more samples as it integrates the data over the whole state and action space.\nThe deterministic policy gradient theorem can be plugged into common policy gradient frameworks.\nLet’s consider an example of on-policy actor-critic algorithm to showcase the procedure. In each iteration of on-policy actor-critic, two actions are taken deterministically $a = \\mu_\\theta(s)$ and the\nSARSA\nupdate on policy parameters relies on the new gradient that we just computed above:\n$$\n\\begin{aligned}\n\\delta_t &= R_t + \\gamma Q_w(s_{t+1}, a_{t+1}) - Q_w(s_t, a_t) & \\small{\\text{; TD error in SARSA}}\\\\\nw_{t+1} &= w_t + \\alpha_w \\delta_t \\nabla_w Q_w(s_t, a_t) & \\\\\n\\theta_{t+1} &= \\theta_t + \\alpha_\\theta \\color{red}{\\nabla_a Q_w(s_t, a_t) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}} & \\small{\\text{; Deterministic policy gradient theorem}}\n\\end{aligned}\n$$\nHowever, unless there is sufficient noise in the environment, it is very hard to guarantee enough\nexploration\ndue to the determinacy of the policy. We can either add noise into the policy (ironically this makes it nondeterministic!) or learn it off-policy-ly by following a different stochastic behavior policy to collect samples.\nSay, in the off-policy approach, the training trajectories are generated by a stochastic policy $\\beta(a \\vert s)$ and thus the state distribution follows the corresponding discounted state density $\\rho^\\beta$:\n$$\n\\begin{aligned}\nJ_\\beta(\\theta) &= \\int_\\mathcal{S} \\rho^\\beta Q^\\mu(s, \\mu_\\theta(s)) ds \\\\\n\\nabla_\\theta J_\\beta(\\theta) &= \\mathbb{E}_{s \\sim \\rho^\\beta} [\\nabla_a Q^\\mu(s, a) \\nabla_\\theta \\mu_\\theta(s)  \\rvert_{a=\\mu_\\theta(s)} ]\n\\end{aligned}\n$$\nNote that because the policy is deterministic, we only need $Q^\\mu(s, \\mu_\\theta(s))$ rather than $\\sum_a \\pi(a \\vert s) Q^\\pi(s, a)$ as the estimated reward of a given state s.\nIn the off-policy approach with a stochastic policy, importance sampling is often used to correct the mismatch between behavior and target policies, as what we have described\nabove\n. However, because the deterministic policy gradient removes the integral over actions, we can avoid importance sampling.\nDDPG\n#\n[\npaper\n|\ncode\n]\nDDPG\n(\nLillicrap, et al., 2015\n), short for\nDeep Deterministic Policy Gradient\n, is a model-free off-policy actor-critic algorithm, combining\nDPG\nwith\nDQN\n. Recall that DQN (Deep Q-Network) stabilizes the learning of Q-function by experience replay and the frozen target network. The original DQN works in discrete space, and DDPG extends it to continuous space with the actor-critic framework while learning a deterministic policy.\nIn order to do better exploration, an exploration policy $\\mu’$ is constructed by adding noise $\\mathcal{N}$:\n$$\n\\mu'(s) = \\mu_\\theta(s) + \\mathcal{N}\n$$\nIn addition, DDPG does soft updates (“conservative policy iteration”) on the parameters of both actor and critic, with $\\tau \\ll 1$: $\\theta’ \\leftarrow \\tau \\theta + (1 - \\tau) \\theta’$. In this way, the target network values are constrained to change slowly, different from the design in DQN that the target network stays frozen for some period of time.\nOne detail in the paper that is particularly useful in robotics is on how to normalize the different physical units of low dimensional features. For example, a model is designed to learn a policy with the robot’s positions and velocities as input; these physical statistics are different by nature and even statistics of the same type may vary a lot across multiple robots.\nBatch normalization\nis applied to fix it by normalizing every dimension across samples in one minibatch.\nFig 3. DDPG Algorithm. (Image source:\nLillicrap, et al., 2015\n)\nD4PG\n#\n[\npaper\n|code (Search “github d4pg” and you will see a few.)]\nDistributed Distributional DDPG (D4PG)\napplies a set of improvements on DDPG to make it run in the distributional fashion.\n(1)\nDistributional Critic\n: The critic estimates the expected Q value as a random variable ~ a distribution $Z_w$ parameterized by $w$ and therefore $Q_w(s, a) = \\mathbb{E} Z_w(x, a)$. The loss for learning the distribution parameter is to minimize some measure of the distance between two distributions — distributional TD error: $L(w) = \\mathbb{E}[d(\\mathcal{T}_{\\mu_\\theta}, Z_{w’}(s, a), Z_w(s, a)]$, where $\\mathcal{T}_{\\mu_\\theta}$ is the Bellman operator.\nThe deterministic policy gradient update becomes:\n$$\n\\begin{aligned}\n\\nabla_\\theta J(\\theta) \n&\\approx \\mathbb{E}_{\\rho^\\mu} [\\nabla_a Q_w(s, a) \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; gradient update in DPG}} \\\\\n&= \\mathbb{E}_{\\rho^\\mu} [\\mathbb{E}[\\nabla_a Z_w(s, a)] \\nabla_\\theta \\mu_\\theta(s) \\rvert_{a=\\mu_\\theta(s)}] & \\scriptstyle{\\text{; expectation of the Q-value distribution.}}\n\\end{aligned}\n$$\n(2)\n$N$-step returns\n: When calculating the TD error, D4PG computes $N$-step TD target rather than one-step to incorporate rewards in more future steps. Thus the new TD target is:\n$$\nr(s_0, a_0) + \\mathbb{E}[\\sum_{n=1}^{N-1} r(s_n, a_n) + \\gamma^N Q(s_N, \\mu_\\theta(s_N)) \\vert s_0, a_0 ]\n$$\n(3)\nMultiple Distributed Parallel Actors\n: D4PG utilizes $K$ independent actors, gathering experience in parallel and feeding data into the same replay buffer.\n(4)\nPrioritized Experience Replay (\nPER\n)\n: The last piece of modification is to do sampling from the replay buffer of size $R$ with an non-uniform probability $p_i$. In this way, a sample $i$ has the probability $(Rp_i)^{-1}$ to be selected and thus the importance weight is $(Rp_i)^{-1}$.\nD4PG algorithm (Image source:\nBarth-Maron, et al. 2018\n); Note that in the original paper, the variable letters are chosen slightly differently from what in the post; i.e. I use $\\mu(.)$ for representing a deterministic policy instead of $\\pi(.)$.\nMADDPG\n#\n[\npaper\n|\ncode\n]\nMulti-agent DDPG\n(\nMADDPG\n) (\nLowe et al., 2017\n) extends DDPG to an environment where multiple agents are coordinating to complete tasks with only local information. In the viewpoint of one agent, the environment is non-stationary as policies of other agents are quickly upgraded and remain unknown. MADDPG is an actor-critic model redesigned particularly for handling such a changing environment and interactions between agents.\nThe problem can be formalized in the multi-agent version of MDP, also known as\nMarkov games\n. MADDPG is proposed for partially observable Markov games. Say, there are N agents in total with a set of states $\\mathcal{S}$. Each agent owns a set of possible action, $\\mathcal{A}_1, \\dots, \\mathcal{A}_N$, and a set of observation, $\\mathcal{O}_1, \\dots, \\mathcal{O}_N$. The state transition function involves all states, action and observation spaces  $\\mathcal{T}: \\mathcal{S} \\times \\mathcal{A}_1 \\times \\dots \\mathcal{A}_N \\mapsto \\mathcal{S}$. Each agent’s stochastic policy only involves its own state and action: $\\pi_{\\theta_i}: \\mathcal{O}_i \\times \\mathcal{A}_i \\mapsto [0, 1]$, a probability distribution over actions given its own observation, or a deterministic policy: $\\mu_{\\theta_i}: \\mathcal{O}_i \\mapsto \\mathcal{A}_i$.\nLet $\\vec{o} = {o_1, \\dots, o_N}$, $\\vec{\\mu} = {\\mu_1, \\dots, \\mu_N}$ and the policies are parameterized by $\\vec{\\theta} = {\\theta_1, \\dots, \\theta_N}$.\nThe critic in MADDPG learns a centralized action-value function $Q^\\vec{\\mu}_i(\\vec{o}, a_1, \\dots, a_N)$ for the i-th agent, where $a_1 \\in \\mathcal{A}_1, \\dots, a_N \\in \\mathcal{A}_N$ are actions of all agents. Each $Q^\\vec{\\mu}_i$ is learned separately for $i=1, \\dots, N$ and therefore multiple agents can have arbitrary reward structures, including conflicting rewards in a competitive setting. Meanwhile, multiple actors, one for each agent, are exploring and upgrading the policy parameters $\\theta_i$ on their own.\nActor update\n:\n$$\n\\nabla_{\\theta_i} J(\\theta_i) = \\mathbb{E}_{\\vec{o}, a \\sim \\mathcal{D}} [\\nabla_{a_i} Q^{\\vec{\\mu}}_i (\\vec{o}, a_1, \\dots, a_N) \\nabla_{\\theta_i} \\mu_{\\theta_i}(o_i) \\rvert_{a_i=\\mu_{\\theta_i}(o_i)} ]\n$$\nWhere $\\mathcal{D}$ is the memory buffer for experience replay, containing multiple episode samples $(\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}’)$ — given current observation $\\vec{o}$, agents take action $a_1, \\dots, a_N$ and get rewards $r_1, \\dots, r_N$, leading to the new observation $\\vec{o}’$.\nCritic update\n:\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta_i) &= \\mathbb{E}_{\\vec{o}, a_1, \\dots, a_N, r_1, \\dots, r_N, \\vec{o}'}[ (Q^{\\vec{\\mu}}_i(\\vec{o}, a_1, \\dots, a_N) - y)^2 ] & \\\\\n\\text{where } y &= r_i + \\gamma Q^{\\vec{\\mu}'}_i (\\vec{o}', a'_1, \\dots, a'_N) \\rvert_{a'_j = \\mu'_{\\theta_j}} & \\scriptstyle{\\text{; TD target!}}\n\\end{aligned}\n$$\nwhere $\\vec{\\mu}’$ are the target policies with delayed softly-updated parameters.\nIf the policies $\\vec{\\mu}$ are unknown during the critic update, we can ask each agent to learn and evolve its own approximation of others’ policies. Using the approximated policies, MADDPG still can learn efficiently although the inferred policies might not be accurate.\nTo mitigate the high variance triggered by the interaction between competing or collaborating agents in the environment, MADDPG proposed one more element -\npolicy ensembles\n:\nTrain K policies for one agent;\nPick a random policy for episode rollouts;\nTake an ensemble of these K policies to do gradient update.\nIn summary, MADDPG added three additional ingredients on top of DDPG to make it adapt to the multi-agent environment:\nCentralized critic + decentralized actors;\nActors are able to use estimated policies of other agents for learning;\nPolicy ensembling is good for reducing variance.\nThe architecture design of MADDPG. (Image source:\nLowe et al., 2017\n)\nTRPO\n#\n[\npaper\n|\ncode\n]\nTo improve training stability, we should avoid parameter updates that change the policy too much at one step.\nTrust region policy optimization (TRPO)\n(\nSchulman, et al., 2015\n) carries out this idea by enforcing a\nKL divergence\nconstraint on the size of policy update at each iteration.\nConsider the case when we are doing off-policy RL, the policy $\\beta$ used for collecting trajectories on rollout workers is different from the policy $\\pi$ to optimize for. The objective function in an off-policy model measures the total advantage over the state visitation distribution and actions, while the mismatch between the training data distribution and the true policy state distribution is compensated by importance sampling estimator:\n$$\n\\begin{aligned}\nJ(\\theta)\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\pi_\\theta(a \\vert s) \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\\\\n&= \\sum_{s \\in \\mathcal{S}} \\rho^{\\pi_{\\theta_\\text{old}}} \\sum_{a \\in \\mathcal{A}} \\big( \\beta(a \\vert s) \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big) & \\scriptstyle{\\text{; Importance sampling}} \\\\\n&= \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\beta} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\beta(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big] &\n\\end{aligned}\n$$\nwhere $\\theta_\\text{old}$ is the policy parameters before the update and thus known to us; $\\rho^{\\pi_{\\theta_\\text{old}}}$ is defined in the same way as\nabove\n; $\\beta(a \\vert s)$ is the behavior policy for collecting trajectories. Noted that we use an estimated advantage $\\hat{A}(.)$ rather than the true advantage function $A(.)$ because the true rewards are usually unknown.\nWhen training on policy, theoretically the policy for collecting data is same as the policy that we want to optimize. However, when rollout workers and optimizers are running in parallel asynchronously, the behavior policy can get stale. TRPO considers this subtle difference: It labels the behavior policy as $\\pi_{\\theta_\\text{old}}(a \\vert s)$ and thus the objective function becomes:\n$$\nJ(\\theta) = \\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}, a \\sim \\pi_{\\theta_\\text{old}}} \\big[ \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)} \\hat{A}_{\\theta_\\text{old}}(s, a) \\big]\n$$\nTRPO aims to maximize the objective function $J(\\theta)$ subject to,\ntrust region constraint\nwhich enforces the distance between old and new policies measured by\nKL-divergence\nto be small enough, within a parameter δ:\n$$\n\\mathbb{E}_{s \\sim \\rho^{\\pi_{\\theta_\\text{old}}}} [D_\\text{KL}(\\pi_{\\theta_\\text{old}}(.\\vert s) \\| \\pi_\\theta(.\\vert s)] \\leq \\delta\n$$\nIn this way, the old and new policies would not diverge too much when this hard constraint is met. While still, TRPO can guarantee a monotonic improvement over policy iteration (Neat, right?). Please read the proof in the\npaper\nif interested :)\nPPO\n#\n[\npaper\n|\ncode\n]\nGiven that TRPO is relatively complicated and we still want to implement a similar constraint,\nproximal policy optimization (PPO)\nsimplifies it by using a clipped surrogate objective while retaining similar performance.\nFirst, let’s denote the probability ratio between old and new policies as:\n$$\nr(\\theta) = \\frac{\\pi_\\theta(a \\vert s)}{\\pi_{\\theta_\\text{old}}(a \\vert s)}\n$$\nThen, the objective function of TRPO (on policy) becomes:\n$$\nJ^\\text{TRPO} (\\theta) = \\mathbb{E} [ r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a) ]\n$$\nWithout a limitation on the distance between $\\theta_\\text{old}$ and $\\theta$, to maximize $J^\\text{TRPO} (\\theta)$ would lead to instability with extremely large parameter updates and big policy ratios. PPO imposes the constraint by forcing $r(\\theta)$ to stay within a small interval around 1, precisely $[1-\\epsilon, 1+\\epsilon]$, where $\\epsilon$ is a hyperparameter.\n$$\nJ^\\text{CLIP} (\\theta) = \\mathbb{E} [ \\min( r(\\theta) \\hat{A}_{\\theta_\\text{old}}(s, a), \\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon) \\hat{A}_{\\theta_\\text{old}}(s, a))]\n$$\nThe function $\\text{clip}(r(\\theta), 1 - \\epsilon, 1 + \\epsilon)$ clips the ratio to be no more than $1+\\epsilon$ and no less than $1-\\epsilon$. The objective function of PPO takes the minimum one between the original value and the clipped version and therefore we lose the motivation for increasing the policy update to extremes for better rewards.\nWhen applying PPO on the network architecture with shared parameters for both policy (actor) and value (critic) functions, in addition to the clipped reward, the objective function is augmented with an error term on the value estimation (formula in red) and an entropy term (formula in blue) to encourage sufficient exploration.\n$$\nJ^\\text{CLIP'} (\\theta) = \\mathbb{E} [ J^\\text{CLIP} (\\theta) - \\color{red}{c_1 (V_\\theta(s) - V_\\text{target})^2} + \\color{blue}{c_2 H(s, \\pi_\\theta(.))} ]\n$$\nwhere Both $c_1$ and $c_2$ are two hyperparameter constants.\nPPO has been tested on a set of benchmark tasks and proved to produce awesome results with much greater simplicity.\nIn a later paper by\nHsu et al., 2020\n, two common design choices in PPO are revisited, precisely (1) clipped probability ratio for policy regularization and (2) parameterize policy action space by continuous Gaussian or discrete softmax distribution. They first identified three failure modes in PPO and proposed replacements for these two designs.\nThe failure modes are:\nOn continuous action spaces, standard PPO is unstable when rewards vanish outside bounded support.\nOn discrete action spaces with sparse high rewards, standard PPO often gets stuck at suboptimal actions.\nThe policy is sensitive to initialization when there are locally optimal actions close to initialization.\nDiscretizing the action space or use Beta distribution helps avoid failure mode 1&3 associated with Gaussian policy. Using KL regularization (same motivation as in\nTRPO\n) as an alternative surrogate model helps resolve failure mode 1&2.\nPPG\n#\n[\npaper\n|\ncode\n]\nSharing parameters between policy and value networks have pros and cons. It allows policy and value functions to share the learned features with each other, but it may cause conflicts between competing objectives and demands the same data for training two networks at the same time.\nPhasic policy gradient\n(\nPPG\n;\nCobbe, et al 2020\n) modifies the traditional on-policy\nactor-critic\npolicy gradient algorithm. precisely\nPPO\n, to have separate training phases for policy and value functions. In two alternating phases:\nThe\npolicy phase\n: updates the policy network by optimizing the PPO\nobjective\n$L^\\text{CLIP} (\\theta)$;\nThe\nauxiliary phase\n: optimizes an auxiliary objective alongside a behavioral cloning loss. In the paper, value function error is the sole auxiliary objective, but it can be quite general and includes any other additional auxiliary losses.\n$$\n\\begin{aligned}\nL^\\text{joint} &= L^\\text{aux} + \\beta_\\text{clone} \\cdot \\mathbb{E}_t[\\text{KL}[\\pi_{\\theta_\\text{old}}(\\cdot\\mid s_t), \\pi_\\theta(\\cdot\\mid s_t)]] \\\\\nL^\\text{aux} &= L^\\text{value} = \\mathbb{E}_t \\big[\\frac{1}{2}\\big( V_w(s_t) - \\hat{V}_t^\\text{targ} \\big)^2\\big]\n\\end{aligned}\n$$\nwhere $\\beta_\\text{clone}$ is a hyperparameter for controlling how much we would like to keep the policy not diverge too much from its original behavior while optimizing the auxiliary objectives.\nThe algorithm of PPG. (Image source:\nCobbe, et al 2020\n)\nwhere\n$N_\\pi$ is the number of policy update iterations in the policy phase. Note that the policy phase performs multiple iterations of updates per single auxiliary phase.\n$E_\\pi$ and $E_V$ control the sample reuse (i.e. the number of training epochs performed across data in the reply buffer) for the policy and value functions, respectively. Note that this happens within the policy phase and thus $E_V$ affects the learning of true value function not the auxiliary value function.\n$E_\\text{aux}$ defines the sample reuse in the auxiliary phrase. In PPG, value function optimization can tolerate a much higher level sample reuse; for example, in the experiments of the paper, $E_\\text{aux} = 6$ while $E_\\pi = E_V = 1$.\nPPG leads to a significant improvement on sample efficiency compared to PPO.\nThe mean normalized performance of PPG vs PPO on the\nProcgen\nbenchmark. (Image source:\nCobbe, et al 2020\n)\nACER\n#\n[\npaper\n|\ncode\n]\nACER\n, short for\nactor-critic with experience replay\n(\nWang, et al., 2017\n), is an off-policy actor-critic model with experience replay, greatly increasing the sample efficiency and decreasing the data correlation. A3C builds up the foundation for ACER, but it is on policy; ACER is A3C’s off-policy counterpart. The major obstacle to making A3C off policy is how to control the stability of the off-policy estimator. ACER proposes three designs to overcome it:\nUse Retrace Q-value estimation;\nTruncate the importance weights with bias correction;\nApply efficient TRPO.\nRetrace Q-value Estimation\nRetrace\nis an off-policy return-based Q-value estimation algorithm with a nice guarantee for convergence for any target and behavior policy pair $(\\pi, \\beta)$, plus good data efficiency.\nRecall how TD learning works for prediction:\nCompute TD error: $\\delta_t = R_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(S_{t+1}, a) - Q(S_t, A_t)$; the term $r_t + \\gamma \\mathbb{E}_{a \\sim \\pi} Q(s_{t+1}, a) $ is known as “TD target”. The expectation $\\mathbb{E}_{a \\sim \\pi}$ is used because for the future step the best estimation we can make is what the return would be if we follow the current policy $\\pi$.\nUpdate the value by correcting the error to move toward the goal: $Q(S_t, A_t) \\leftarrow Q(S_t, A_t) + \\alpha \\delta_t$. In other words, the incremental update on Q is proportional to the TD error: $\\Delta Q(S_t, A_t) = \\alpha \\delta_t$.\nWhen the rollout is off policy, we need to apply importance sampling on the Q update:\n$$\n\\Delta Q^\\text{imp}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)} \\delta_t\n$$\nThe product of importance weights looks pretty scary when we start imagining how it can cause super high variance and even explode. Retrace Q-value estimation method modifies $\\Delta Q$ to have importance weights truncated by no more than a constant $c$:\n$$\n\\Delta Q^\\text{ret}(S_t, A_t) \n= \\gamma^t \\prod_{1 \\leq \\tau \\leq t} \\min(c, \\frac{\\pi(A_\\tau \\vert S_\\tau)}{\\beta(A_\\tau \\vert S_\\tau)})  \\delta_t\n$$\nACER uses $Q^\\text{ret}$ as the target to train the critic by minimizing the L2 error term: $(Q^\\text{ret}(s, a) - Q(s, a))^2$.\nImportance weights truncation\nTo reduce the high variance of the policy gradient $\\hat{g}$, ACER truncates the importance weights by a constant c, plus a correction term. The label $\\hat{g}_t^\\text{acer}$ is the ACER policy gradient at time t.\n$$\n\\begin{aligned}\n\\hat{g}_t^\\text{acer}\n= & \\omega_t \\big( Q^\\text{ret}(S_t, A_t) - V_{\\theta_v}(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t) \n  & \\scriptstyle{\\text{; Let }\\omega_t=\\frac{\\pi(A_t \\vert S_t)}{\\beta(A_t \\vert S_t)}} \\\\\n= & \\color{blue}{\\min(c, \\omega_t) \\big( Q^\\text{ret}(S_t, A_t) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(A_t \\vert S_t)} \\\\\n  & + \\color{red}{\\mathbb{E}_{a \\sim \\pi} \\big[ \\max(0, \\frac{\\omega_t(a) - c}{\\omega_t(a)}) \\big( Q_w(S_t, a) - V_w(S_t) \\big) \\nabla_\\theta \\ln \\pi_\\theta(a \\vert S_t) \\big]}\n  & \\scriptstyle{\\text{; Let }\\omega_t (a) =\\frac{\\pi(a \\vert S_t)}{\\beta(a \\vert S_t)}}\n\\end{aligned}\n$$\nwhere $Q_w(.)$ and $V_w(.)$ are value functions predicted by the critic with parameter w. The first term (blue) contains the clipped important weight. The clipping helps reduce the variance, in addition to subtracting state value function $V_w(.)$ as a baseline. The second term (red) makes a correction to achieve unbiased estimation.\nEfficient TRPO\nFurthermore, ACER adopts the idea of TRPO but with a small adjustment to make it more computationally efficient: rather than measuring the KL divergence between policies before and after one update, ACER maintains a running average of past policies and forces the updated policy to not deviate far from this average.\nThe ACER\npaper\nis pretty dense with many equations. Hopefully, with the prior knowledge on TD learning, Q-learning, importance sampling and TRPO, you will find the\npaper\nslightly easier to follow :)\nACTKR\n#\n[\npaper\n|\ncode\n]\nACKTR (actor-critic using Kronecker-factored trust region)\n(\nYuhuai Wu, et al., 2017\n) proposed to use Kronecker-factored approximation curvature (\nK-FAC\n) to do the gradient update for both the critic and actor. K-FAC made an improvement on the computation of\nnatural gradient\n, which is quite different from our\nstandard gradient\n.\nHere\nis a nice, intuitive explanation of natural gradient. One sentence summary is probably:\n“we first consider all combinations of parameters that result in a new network a constant KL divergence away from the old network. This constant value can be viewed as the step size or learning rate. Out of all these possible combinations, we choose the one that minimizes our loss function.”\nI listed ACTKR here mainly for the completeness of this post, but I would not dive into details, as it involves a lot of theoretical knowledge on natural gradient and optimization methods. If interested, check these papers/posts, before reading the ACKTR paper:\nAmari.\nNatural Gradient Works Efficiently in Learning\n. 1998\nKakade.\nA Natural Policy Gradient\n. 2002\nA intuitive explanation of natural gradient descent\nWiki: Kronecker product\nMartens & Grosse.\nOptimizing neural networks with kronecker-factored approximate curvature.\n2015.\nHere is a high level summary from the K-FAC\npaper\n:\n“This approximation is built in two stages. In the first, the rows and columns of the Fisher are divided into groups, each of which corresponds to all the weights in a given layer, and this gives rise to a block-partitioning of the matrix. These blocks are then approximated as Kronecker products between much smaller matrices, which we show is equivalent to making certain approximating assumptions regarding the statistics of the network’s gradients.\nIn the second stage, this matrix is further approximated as having an inverse which is either block-diagonal or block-tridiagonal. We justify this approximation through a careful examination of the relationships between inverse covariances, tree-structured graphical models, and linear regression. Notably, this justification doesn’t apply to the Fisher itself, and our experiments confirm that while the inverse Fisher does indeed possess this structure (approximately), the Fisher itself does not.”\nSAC\n#\n[\npaper\n|\ncode\n]\nSoft Actor-Critic (SAC)\n(\nHaarnoja et al. 2018\n) incorporates the entropy measure of the policy into the reward to encourage exploration: we expect to learn a policy that acts as randomly as possible while it is still able to succeed at the task. It is an off-policy actor-critic model following the maximum entropy reinforcement learning framework. A precedent work is\nSoft Q-learning\n.\nThree key components in SAC:\nAn\nactor-critic\narchitecture with separate policy and value function networks;\nAn\noff-policy\nformulation that enables reuse of previously collected data for efficiency;\nEntropy maximization to enable stability and exploration.\nThe policy is trained with the objective to maximize the expected return and the entropy at the same time:\n$$\nJ(\\theta) = \\sum_{t=1}^T \\mathbb{E}_{(s_t, a_t) \\sim \\rho_{\\pi_\\theta}} [r(s_t, a_t) + \\alpha \\mathcal{H}(\\pi_\\theta(.\\vert s_t))]\n$$\nwhere $\\mathcal{H}(.)$ is the entropy measure and $\\alpha$ controls how important the entropy term is, known as\ntemperature\nparameter. The entropy maximization leads to policies that can (1) explore more and (2) capture multiple modes of near-optimal strategies (i.e., if there exist multiple options that seem to be equally good, the policy should assign each with an equal probability to be chosen).\nPrecisely, SAC aims to learn three functions:\nThe policy with parameter $\\theta$, $\\pi_\\theta$.\nSoft Q-value function parameterized by $w$, $Q_w$.\nSoft state value function parameterized by $\\psi$, $V_\\psi$; theoretically we can infer $V$ by knowing $Q$ and $\\pi$, but in practice, it helps stabilize the training.\nSoft Q-value and soft state value are defined as:\n$$\n\\begin{aligned}\nQ(s_t, a_t) &= r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_{\\pi}(s)} [V(s_{t+1})] & \\text{; according to Bellman equation.}\\\\\n\\text{where }V(s_t) &= \\mathbb{E}_{a_t \\sim \\pi} [Q(s_t, a_t) - \\alpha \\log \\pi(a_t \\vert s_t)] & \\text{; soft state value function.}\n\\end{aligned}\n$$\n$$\n\\text{Thus, } Q(s_t, a_t) = r(s_t, a_t) + \\gamma \\mathbb{E}_{(s_{t+1}, a_{t+1}) \\sim \\rho_{\\pi}} [Q(s_{t+1}, a_{t+1}) - \\alpha \\log \\pi(a_{t+1} \\vert s_{t+1})]\n$$\n$\\rho_\\pi(s)$ and $\\rho_\\pi(s, a)$ denote the state and the state-action marginals of the state distribution induced by the policy $\\pi(a \\vert s)$; see the similar definitions in\nDPG\nsection.\nThe soft state value function is trained to minimize the mean squared error:\n$$\n\\begin{aligned}\nJ_V(\\psi) &= \\mathbb{E}_{s_t \\sim \\mathcal{D}} [\\frac{1}{2} \\big(V_\\psi(s_t) - \\mathbb{E}[Q_w(s_t, a_t) - \\log \\pi_\\theta(a_t \\vert s_t)] \\big)^2] \\\\\n\\text{with gradient: }\\nabla_\\psi J_V(\\psi) &= \\nabla_\\psi V_\\psi(s_t)\\big( V_\\psi(s_t) - Q_w(s_t, a_t) + \\log \\pi_\\theta (a_t \\vert s_t) \\big)\n\\end{aligned}\n$$\nwhere $\\mathcal{D}$ is the replay buffer.\nThe soft Q function is trained to minimize the soft Bellman residual:\n$$\n\\begin{aligned}\nJ_Q(w) &= \\mathbb{E}_{(s_t, a_t) \\sim \\mathcal{D}} [\\frac{1}{2}\\big( Q_w(s_t, a_t) - (r(s_t, a_t) + \\gamma \\mathbb{E}_{s_{t+1} \\sim \\rho_\\pi(s)}[V_{\\bar{\\psi}}(s_{t+1})]) \\big)^2] \\\\\n\\text{with gradient: } \\nabla_w J_Q(w) &= \\nabla_w Q_w(s_t, a_t) \\big( Q_w(s_t, a_t) - r(s_t, a_t) - \\gamma V_{\\bar{\\psi}}(s_{t+1})\\big) \n\\end{aligned}\n$$\nwhere $\\bar{\\psi}$ is the target value function which is the exponential moving average (or only gets updated periodically in a “hard” way), just like how the parameter of the target Q network is treated in\nDQN\nto stabilize the training.\nSAC updates the policy to minimize the\nKL-divergence\n:\n$$\n\\begin{aligned}\n\\pi_\\text{new} \n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\Big( \\pi'(.\\vert s_t) \\| \\frac{\\exp(Q^{\\pi_\\text{old}}(s_t, .))}{Z^{\\pi_\\text{old}}(s_t)} \\Big) \\\\[6pt]\n&= \\arg\\min_{\\pi' \\in \\Pi} D_\\text{KL} \\big( \\pi'(.\\vert s_t) \\| \\exp(Q^{\\pi_\\text{old}}(s_t, .) - \\log Z^{\\pi_\\text{old}}(s_t)) \\big) \\\\[6pt]\n\\text{objective for update: } J_\\pi(\\theta) &= \\nabla_\\theta D_\\text{KL} \\big( \\pi_\\theta(. \\vert s_t) \\| \\exp(Q_w(s_t, .) - \\log Z_w(s_t)) \\big) \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} \\Big[ - \\log \\big( \\frac{\\exp(Q_w(s_t, a_t) - \\log Z_w(s_t))}{\\pi_\\theta(a_t \\vert s_t)} \\big) \\Big] \\\\[6pt]\n&= \\mathbb{E}_{a_t\\sim\\pi} [ \\log \\pi_\\theta(a_t \\vert s_t) - Q_w(s_t, a_t) + \\log Z_w(s_t) ]\n\\end{aligned}\n$$\nwhere $\\Pi$ is the set of potential policies that we can model our policy as to keep them tractable; for example, $\\Pi$ can be the family of Gaussian mixture distributions, expensive to model but highly expressive and still tractable. $Z^{\\pi_\\text{old}}(s_t)$ is the partition function to normalize the distribution. It is usually intractable but does not contribute to the gradient. How to minimize $J_\\pi(\\theta)$ depends our choice of $\\Pi$.\nThis update guarantees that $Q^{\\pi_\\text{new}}(s_t, a_t) \\geq Q^{\\pi_\\text{old}}(s_t, a_t)$, please check the proof on this lemma in the Appendix B.2 in the original\npaper\n.\nOnce we have defined the objective functions and gradients for soft action-state value, soft state value and the policy network, the soft actor-critic algorithm is straightforward:\nThe soft actor-critic algorithm. (Image source:\noriginal paper\n)\nSAC with Automatically Adjusted Temperature\n#\n[\npaper\n|\ncode\n]\nSAC is brittle with respect to the temperature parameter. Unfortunately it is difficult to adjust temperature, because the entropy can vary unpredictably both across tasks and during training as the policy becomes better. An improvement on SAC formulates a constrained optimization problem: while maximizing the expected return, the policy should satisfy a minimum entropy constraint:\n$$\n\\max_{\\pi_0, \\dots, \\pi_T} \\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big] \\text{s.t. } \\forall t\\text{, } \\mathcal{H}(\\pi_t) \\geq \\mathcal{H}_0\n$$\nwhere $\\mathcal{H}_0$ is a predefined minimum policy entropy threshold.\nThe expected return $\\mathbb{E} \\Big[ \\sum_{t=0}^T r(s_t, a_t)\\Big]$ can be decomposed into a sum of rewards at all the time steps. Because the policy $\\pi_t$ at time t has no effect on the policy at the earlier time step, $\\pi_{t-1}$, we can maximize the return at different steps backward in time — this is essentially\nDP\n.\n$$\n\\underbrace{\\max_{\\pi_0} \\Big( \\mathbb{E}[r(s_0, a_0)]+ \\underbrace{\\max_{\\pi_1} \\Big(\\mathbb{E}[...] + \\underbrace{\\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T)]}_\\text{1st maximization} \\Big)}_\\text{second but last maximization} \\Big)}_\\text{last maximization}\n$$\nwhere we consider $\\gamma=1$.\nSo we start the optimization from the last timestep $T$:\n$$\n\\text{maximize } \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] \\text{ s.t. } \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 \\geq 0\n$$\nFirst, let us define the following functions:\n$$\n\\begin{aligned}\nh(\\pi_T) &= \\mathcal{H}(\\pi_T) - \\mathcal{H}_0 = \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0\\\\\nf(\\pi_T) &= \\begin{cases}\n\\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ], & \\text{if }h(\\pi_T) \\geq 0 \\\\\n-\\infty, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nAnd the optimization becomes:\n$$\n\\text{maximize } f(\\pi_T) \\text{ s.t. } h(\\pi_T) \\geq 0\n$$\nTo solve the maximization optimization with inequality constraint, we can construct a\nLagrangian expression\nwith a Lagrange multiplier (also known as “dual variable”), $\\alpha_T$:\n$$\nL(\\pi_T, \\alpha_T) = f(\\pi_T) + \\alpha_T h(\\pi_T)\n$$\nConsidering the case when we try to\nminimize $L(\\pi_T, \\alpha_T)$ with respect to $\\alpha_T$\n- given a particular value $\\pi_T$,\nIf the constraint is satisfied, $h(\\pi_T) \\geq 0$, at best we can set $\\alpha_T=0$ since we have no control over the value of $f(\\pi_T)$. Thus, $L(\\pi_T, 0) = f(\\pi_T)$.\nIf the constraint is invalidated, $h(\\pi_T) < 0$, we can achieve $L(\\pi_T, \\alpha_T) \\to -\\infty$ by taking  $\\alpha_T \\to \\infty$. Thus, $L(\\pi_T, \\infty) = -\\infty = f(\\pi_T)$.\nIn either case, we can recover the following equation,\n$$\nf(\\pi_T) = \\min_{\\alpha_T \\geq 0} L(\\pi_T, \\alpha_T)\n$$\nAt the same time, we want to maximize $f(\\pi_T)$,\n$$\n\\max_{\\pi_T} f(\\pi_T) = \\min_{\\alpha_T \\geq 0} \\max_{\\pi_T} L(\\pi_T, \\alpha_T)\n$$\nTherefore, to maximize $f(\\pi_T)$, the dual problem is listed as below. Note that to make sure $\\max_{\\pi_T} f(\\pi_T)$ is properly maximized and would not become $-\\infty$, the constraint has to be satisfied.\n$$\n\\begin{aligned}\n\\max_{\\pi_T} \\mathbb{E}[ r(s_T, a_T) ]\n&= \\max_{\\pi_T} f(\\pi_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} L(\\pi_T, \\alpha_T) \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} f(\\pi_T) + \\alpha_T h(\\pi_T) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T) ] + \\alpha_T ( \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [-\\log \\pi_T(a_T\\vert s_T)] - \\mathcal{H}_0) \\\\ \n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  - \\alpha_T \\log \\pi_T(a_T\\vert s_T)] - \\alpha_T \\mathcal{H}_0 \\\\\n&= \\min_{\\alpha_T \\geq 0}  \\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ]\n\\end{aligned}\n$$\nWe could compute the optimal $\\pi_T$ and $\\alpha_T$ iteratively. First given the current $\\alpha_T$, get the best policy $\\pi_T^{*}$ that maximizes $L(\\pi_T^{*}, \\alpha_T)$. Then plug in $\\pi_T^{*}$ and compute $\\alpha_T^{*}$ that minimizes $L(\\pi_T^{*}, \\alpha_T)$. Assuming we have one neural network for policy and one network for temperature parameter, the iterative update process is more aligned with how we update network parameters during training.\n$$\n\\begin{aligned}\n\\pi^{*}_T\n&= \\arg\\max_{\\pi_T} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi}} [ r(s_T, a_T)  + \\alpha_T \\mathcal{H}(\\pi_T) - \\alpha_T \\mathcal{H}_0 ] \\\\\n\\color{blue}{\\alpha^{*}_T}\n&\\color{blue}{=} \\color{blue}{\\arg\\min_{\\alpha_T \\geq 0} \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [\\alpha_T \\mathcal{H}(\\pi^{*}_T) - \\alpha_T \\mathcal{H}_0 ]}\n\\end{aligned}\n$$\n$$\n\\text{Thus, }\\max_{\\pi_T} \\mathbb{E} [ r(s_T, a_T) ] \n= \\mathbb{E}_{(s_T, a_T) \\sim \\rho_{\\pi^{*}}} [ r(s_T, a_T)  + \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) - \\alpha^{*}_T \\mathcal{H}_0 ]\n$$\nNow let’s go back to the soft Q value function:\n$$\n\\begin{aligned}\nQ_{T-1}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [Q(s_T, a_T) - \\alpha_T \\log \\pi(a_T \\vert s_T)] \\\\\n&= r(s_{T-1}, a_{T-1}) + \\mathbb{E} [r(s_T, a_T)] + \\alpha_T \\mathcal{H}(\\pi_T) \\\\\nQ_{T-1}^{*}(s_{T-1}, a_{T-1}) \n&= r(s_{T-1}, a_{T-1}) + \\max_{\\pi_T} \\mathbb{E} [r(s_T, a_T)] +  \\alpha_T \\mathcal{H}(\\pi^{*}_T) & \\text{; plug in the optimal }\\pi_T^{*}\n\\end{aligned}\n$$\nTherefore the expected return is as follows, when we take one step further back to the time step $T-1$:\n$$\n\\begin{aligned}\n&\\max_{\\pi_{T-1}}\\Big(\\mathbb{E}[r(s_{T-1}, a_{T-1})] + \\max_{\\pi_T} \\mathbb{E}[r(s_T, a_T] \\Big) \\\\\n&= \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) \\Big) & \\text{; should s.t. } \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\geq 0 \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T) + \\alpha_{T-1} \\big( \\mathcal{H}(\\pi_{T-1}) - \\mathcal{H}_0 \\big) \\Big) & \\text{; dual problem w/ Lagrangian.} \\\\\n&= \\min_{\\alpha_{T-1} \\geq 0}  \\max_{\\pi_{T-1}} \\Big( Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 \\Big) - \\alpha^{*}_T \\mathcal{H}(\\pi^{*}_T)\n\\end{aligned}\n$$\nSimilar to the previous step,\n$$\n\\begin{aligned}\n\\pi^{*}_{T-1} &= \\arg\\max_{\\pi_{T-1}} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_\\pi} [Q^{*}_{T-1}(s_{T-1}, a_{T-1}) + \\alpha_{T-1} \\mathcal{H}(\\pi_{T-1}) - \\alpha_{T-1} \\mathcal{H}_0 ] \\\\\n\\color{green}{\\alpha^{*}_{T-1}} &\\color{green}{=} \\color{green}{\\arg\\min_{\\alpha_{T-1} \\geq 0} \\mathbb{E}_{(s_{T-1}, a_{T-1}) \\sim \\rho_{\\pi^{*}}} [ \\alpha_{T-1} \\mathcal{H}(\\pi^{*}_{T-1}) - \\alpha_{T-1}\\mathcal{H}_0 ]}\n\\end{aligned}\n$$\nThe equation for updating $\\alpha_{T-1}$ in\ngreen\nhas the same format as the equation for updating $\\alpha_{T-1}$ in\nblue\nabove. By repeating this process, we can learn the optimal temperature parameter in every step by minimizing the same objective function:\n$$\nJ(\\alpha) = \\mathbb{E}_{a_t \\sim \\pi_t} [-\\alpha \\log \\pi_t(a_t \\mid s_t) - \\alpha \\mathcal{H}_0]\n$$\nThe final algorithm is same as SAC except for learning $\\alpha$ explicitly with respect to the objective $J(\\alpha)$ (see Fig. 7):\nThe soft actor-critic algorithm with automatically adjusted temperature. (Image source:\noriginal paper\n)\nTD3\n#\n[\npaper\n|\ncode\n]\nThe Q-learning algorithm is commonly known to suffer from the overestimation of the value function. This overestimation can propagate through the training iterations and negatively affect the policy. This property directly motivated\nDouble Q-learning\nand\nDouble DQN\n: the action selection and Q-value update are decoupled by using two value networks.\nTwin Delayed Deep Deterministic\n(short for\nTD3\n;\nFujimoto et al., 2018\n) applied a couple of tricks on\nDDPG\nto prevent the overestimation of the value function:\n(1)\nClipped Double Q-learning\n: In Double Q-Learning, the action selection and Q-value estimation are made by two networks separately. In the DDPG setting, given two deterministic actors $(\\mu_{\\theta_1}, \\mu_{\\theta_2})$ with two corresponding critics $(Q_{w_1}, Q_{w_2})$, the Double Q-learning Bellman targets look like:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma Q_{w_2}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma Q_{w_1}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\nHowever, due to the slow changing policy, these two networks could be too similar to make independent decisions. The\nClipped Double Q-learning\ninstead uses the minimum estimation among two so as to favor underestimation bias which is hard to propagate through training:\n$$\n\\begin{aligned}\ny_1 &= r + \\gamma \\min_{i=1,2}Q_{w_i}(s', \\mu_{\\theta_1}(s'))\\\\\ny_2 &= r + \\gamma \\min_{i=1,2} Q_{w_i}(s', \\mu_{\\theta_2}(s'))\n\\end{aligned}\n$$\n(2)\nDelayed update of Target and Policy Networks\n:  In the\nactor-critic\nmodel, policy and value updates are deeply coupled: Value estimates diverge through overestimation when the policy is poor, and the policy will become poor if the value estimate itself is inaccurate.\nTo reduce the variance, TD3 updates the policy at a lower frequency than the Q-function. The policy network stays the same until the value error is small enough after several updates. The idea is similar to how the periodically-updated target network stay as a stable objective in\nDQN\n.\n(3)\nTarget Policy Smoothing\n: Given a concern with deterministic policies that they can overfit to narrow peaks in the value function, TD3 introduced a smoothing regularization strategy on the value function: adding a small amount of clipped random noises to the selected action and averaging over mini-batches.\n$$\n\\begin{aligned}\ny &= r + \\gamma Q_w (s', \\mu_{\\theta}(s') + \\epsilon) & \\\\\n\\epsilon &\\sim \\text{clip}(\\mathcal{N}(0, \\sigma), -c, +c) & \\scriptstyle{\\text{ ; clipped random noises.}}\n\\end{aligned}\n$$\nThis approach mimics the idea of\nSARSA\nupdate and enforces that similar actions should have similar values.\nHere is the final algorithm:\nTD3 Algorithm. (Image source:\nFujimoto et al., 2018\n)\nSVPG\n#\n[\npaper\n|\ncode\nfor SVPG]\nStein Variational Policy Gradient (\nSVPG\n;\nLiu et al, 2017\n) applies the\nStein\nvariational gradient descent (\nSVGD\n;\nLiu and Wang, 2016\n) algorithm to update the policy parameter $\\theta$.\nIn the setup of maximum entropy policy optimization, $\\theta$ is considered as a random variable $\\theta \\sim q(\\theta)$ and the model is expected to learn this distribution $q(\\theta)$. Assuming we know a prior on how $q$ might look like, $q_0$, and we would like to guide the learning process to not make $\\theta$ too far away from $q_0$ by optimizing the following objective function:\n$$\n\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0)\n$$\nwhere $\\mathbb{E}_{\\theta \\sim q} [R(\\theta)]$ is the expected reward when $\\theta \\sim q(\\theta)$ and $D_\\text{KL}$ is the KL divergence.\nIf we don’t have any prior information, we might set $q_0$ as a uniform distribution and set $q_0(\\theta)$ to a constant. Then the above objective function becomes\nSAC\n, where the entropy term encourages exploration:\n$$\n\\begin{aligned}\n\\hat{J}(\\theta) \n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha \\mathbb{E}_{\\theta \\sim q} [\\log q(\\theta) - \\log q_0(\\theta)] \\\\\n&= \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] + \\alpha H(q(\\theta))\n\\end{aligned}\n$$\nLet’s take the derivative of $\\hat{J}(\\theta) = \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q|q_0)$ w.r.t. $q$:\n$$\n\\begin{aligned}\n\\nabla_q \\hat{J}(\\theta) \n&= \\nabla_q \\big( \\mathbb{E}_{\\theta \\sim q} [J(\\theta)] - \\alpha D_\\text{KL}(q\\|q_0) \\big) \\\\\n&= \\nabla_q \\int_\\theta \\big( q(\\theta) J(\\theta) - \\alpha q(\\theta)\\log q(\\theta) + \\alpha q(\\theta) \\log q_0(\\theta) \\big) \\\\\n&= \\int_\\theta \\big( J(\\theta) - \\alpha \\log q(\\theta) -\\alpha + \\alpha \\log q_0(\\theta) \\big) \\\\\n&= 0\n\\end{aligned}\n$$\nThe optimal distribution is:\n$$\n\\log q^{*}(\\theta) = \\frac{1}{\\alpha} J(\\theta) + \\log q_0(\\theta) - 1 \\text{ thus } \\underbrace{ q^{*}(\\theta) }_\\textrm{\"posterior\"} \\propto \\underbrace{\\exp ( J(\\theta) / \\alpha )}_\\textrm{\"likelihood\"} \\underbrace{q_0(\\theta)}_\\textrm{prior}\n$$\nThe temperature $\\alpha$ decides a tradeoff between exploitation and exploration. When $\\alpha \\rightarrow 0$, $\\theta$ is updated only according to the expected return $J(\\theta)$. When $\\alpha \\rightarrow \\infty$, $\\theta$ always follows the prior belief.\nWhen using the SVGD method to estimate the target posterior distribution $q(\\theta)$, it relies on a set of particle $\\{\\theta_i\\}_{i=1}^n$ (independently trained policy agents) and each is updated:\n$$\n\\theta_i \\gets \\theta_i + \\epsilon \\phi^{*}(\\theta_i) \\text{ where } \\phi^{*} = \\max_{\\phi \\in \\mathcal{H}} \\{ - \\nabla_\\epsilon D_\\text{KL} (q'_{[\\theta + \\epsilon \\phi(\\theta)]} \\| q) \\text{ s.t. } \\|\\phi\\|_{\\mathcal{H}} \\leq 1\\} \n$$\nwhere $\\epsilon$ is a learning rate and $\\phi^{*}$ is the unit ball of a\nRKHS\n(reproducing kernel Hilbert space) $\\mathcal{H}$ of $\\theta$-shaped value vectors that maximally decreases the KL divergence between the particles and the target distribution. $q’(.)$ is the distribution of $\\theta + \\epsilon \\phi(\\theta)$.\nComparing different gradient-based update methods:\nMethod\nUpdate space\nPlain gradient\n$\\Delta \\theta$ on the parameter space\nNatural gradient\n$\\Delta \\theta$ on the search distribution space\nSVGD\n$\\Delta \\theta$ on the kernel function space (edited)\nOne\nestimation\nof $\\phi^{*}$ has the following form. A positive definite kernel $k(\\vartheta, \\theta)$, i.e. a Gaussian\nradial basis function\n, measures the similarity between particles.\n$$\n\\begin{aligned}\n\\phi^{*}(\\theta_i) \n&= \\mathbb{E}_{\\vartheta \\sim q'} [\\nabla_\\vartheta \\log q(\\vartheta) k(\\vartheta, \\theta_i) + \\nabla_\\vartheta k(\\vartheta, \\theta_i)]\\\\\n&= \\frac{1}{n} \\sum_{j=1}^n [\\color{red}{\\nabla_{\\theta_j} \\log q(\\theta_j) k(\\theta_j, \\theta_i)} + \\color{green}{\\nabla_{\\theta_j} k(\\theta_j, \\theta_i)}] & \\scriptstyle{\\text{;approximate }q'\\text{ with current particle values}}\n\\end{aligned}\n$$\nThe first term in\nred\nencourages $\\theta_i$ learning towards the high probability regions of $q$ that is shared across similar particles. => to be similar to other particles\nThe second term in\ngreen\npushes particles away from each other and therefore diversifies the policy. => to be dissimilar to other particles\nUsually the temperature $\\alpha$ follows an annealing scheme so that the training process does more exploration at the beginning but more exploitation at a later stage.\nIMPALA\n#\n[\npaper\n|\ncode\n]\nIn order to scale up RL training to achieve a very high throughput,\nIMPALA\n(“Importance Weighted Actor-Learner Architecture”) framework decouples acting from learning on top of basic actor-critic setup and learns from all experience trajectories with\nV-trace\noff-policy correction.\nMultiple actors generate experience in parallel, while the learner optimizes both policy and value function parameters using all the generated experience. Actors update their parameters with the latest policy from the learner periodically. Because acting and learning are decoupled, we can add many more actor machines to generate a lot more trajectories per time unit. As the training policy and the behavior policy are not totally synchronized, there is a\ngap\nbetween them and thus we need off-policy corrections.\nLet the value function $V_\\theta$ parameterized by $\\theta$ and the policy $\\pi_\\phi$ parameterized by $\\phi$. Also we know the trajectories in the replay buffer are collected by a slightly older policy $\\mu$.\nAt the training time $t$, given $(s_t, a_t, s_{t+1}, r_t)$, the value function parameter $\\theta$ is learned through an L2 loss between the current value and a V-trace value target. The $n$-step V-trace target is defined as:\n$$\n\\begin{aligned}\nv_t  &= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\delta_i V} \\\\\n&= V_\\theta(s_t) + \\sum_{i=t}^{t+n-1} \\gamma^{i-t} \\big(\\prod_{j=t}^{i-1} c_j\\big) \\color{red}{\\rho_i (r_i + \\gamma V_\\theta(s_{i+1}) - V_\\theta(s_i))}\n\\end{aligned}\n$$\nwhere the\nred\npart $\\delta_i V$ is a temporal difference for $V$. $\\rho_i = \\min\\big(\\bar{\\rho}, \\frac{\\pi(a_i \\vert s_i)}{\\mu(a_i \\vert s_i)}\\big)$ and $c_j = \\min\\big(\\bar{c}, \\frac{\\pi(a_j \\vert s_j)}{\\mu(a_j \\vert s_j)}\\big)$ are\ntruncated\nimportance sampling (IS)\nweights\n. The product of $c_t, \\dots, c_{i-1}$ measures how much a temporal difference $\\delta_i V$ observed at time $i$ impacts the update of the value function at a previous time $t$. In the on-policy case, we have $\\rho_i=1$ and $c_j=1$ (assuming $\\bar{c} \\geq 1$) and therefore the V-trace target becomes on-policy $n$-step Bellman target.\n$\\bar{\\rho}$ and $\\bar{c}$ are two truncation constants with $\\bar{\\rho} \\geq \\bar{c}$. $\\bar{\\rho}$ impacts the fixed-point of the value function we converge to and $\\bar{c}$ impacts the speed of convergence. When $\\bar{\\rho} =\\infty$ (untruncated), we converge to the value function of the target policy $V^\\pi$; when $\\bar{\\rho}$ is close to 0, we evaluate the value function of the behavior policy $V^\\mu$; when in-between, we evaluate a policy between $\\pi$ and $\\mu$.\nThe value function parameter is therefore updated in the direction of:\n$$\n\\Delta\\theta = (v_t - V_\\theta(s_t))\\nabla_\\theta V_\\theta(s_t)\n$$\nThe policy parameter $\\phi$ is updated through policy gradient,\n$$\n\\begin{aligned}\n\\Delta \\phi \n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) + \\nabla_\\phi H(\\pi_\\phi)\\\\\n&= \\rho_t \\nabla_\\phi \\log \\pi_\\phi(a_t \\vert s_t) \\big(r_t + \\gamma v_{t+1} - V_\\theta(s_t)\\big) - \\nabla_\\phi \\sum_a \\pi_\\phi(a\\vert s_t)\\log \\pi_\\phi(a\\vert s_t)\n\\end{aligned}\n$$\nwhere $r_t + \\gamma v_{t+1}$ is the estimated Q value, from which a state-dependent baseline $V_\\theta(s_t)$ is subtracted. $H(\\pi_\\phi)$ is an entropy bonus to encourage exploration.\nIn the experiments, IMPALA is used to train one agent over multiple tasks. Two different model architectures are involved, a shallow model (left) and a deep residual model (right).\nQuick Summary\n#\nAfter reading through all the algorithms above, I list a few building blocks or principles that seem to be common among them:\nTry to reduce the variance and keep the bias unchanged to stabilize learning.\nOff-policy gives us better exploration and helps us use data samples more efficiently.\nExperience replay (training data sampled from a replay memory buffer);\nTarget network that is either frozen periodically or updated slower than the actively learned policy network;\nBatch normalization;\nEntropy-regularized reward;\nThe critic and actor can share lower layer parameters of the network and two output heads for policy and value functions.\nIt is possible to learn with deterministic policy rather than stochastic one.\nPut constraint on the divergence between policy updates.\nNew optimization methods (such as K-FAC).\nEntropy maximization of the policy helps encourage exploration.\nTry not to overestimate the value function.\nThink twice whether the policy and value network should share parameters.\nTBA more.\nCited as:\n@article{weng2018PG,\n  title   = \"Policy Gradient Algorithms\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-04-08-policy-gradient/\"\n}\nReferences\n#\n[1] jeremykun.com\nMarkov Chain Monte Carlo Without all the Bullshit\n[2] Richard S. Sutton and Andrew G. Barto.\nReinforcement Learning: An Introduction; 2nd Edition\n. 2017.\n[3] John Schulman, et al.\n“High-dimensional continuous control using generalized advantage estimation.”\nICLR 2016.\n[4] Thomas Degris, Martha White, and Richard S. Sutton.\n“Off-policy actor-critic.”\nICML 2012.\n[5] timvieira.github.io\nImportance sampling\n[6] Mnih, Volodymyr, et al.\n“Asynchronous methods for deep reinforcement learning.”\nICML. 2016.\n[7] David Silver, et al.\n“Deterministic policy gradient algorithms.”\nICML. 2014.\n[8] Timothy P. Lillicrap, et al.\n“Continuous control with deep reinforcement learning.”\narXiv preprint arXiv:1509.02971 (2015).\n[9] Ryan Lowe, et al.\n“Multi-agent actor-critic for mixed cooperative-competitive environments.”\nNIPS. 2017.\n[10] John Schulman, et al.\n“Trust region policy optimization.”\nICML. 2015.\n[11] Ziyu Wang, et al.\n“Sample efficient actor-critic with experience replay.”\nICLR 2017.\n[12] Rémi Munos, Tom Stepleton, Anna Harutyunyan, and Marc Bellemare.\n“Safe and efficient off-policy reinforcement learning”\nNIPS. 2016.\n[13] Yuhuai Wu, et al.\n“Scalable trust-region method for deep reinforcement learning using Kronecker-factored approximation.”\nNIPS. 2017.\n[14] kvfrans.com\nA intuitive explanation of natural gradient descent\n[15] Sham Kakade.\n“A Natural Policy Gradient.”\n. NIPS. 2002.\n[16]\n“Going Deeper Into Reinforcement Learning: Fundamentals of Policy Gradients.”\n- Seita’s Place, Mar 2017.\n[17]\n“Notes on the Generalized Advantage Estimation Paper.”\n- Seita’s Place, Apr, 2017.\n[18] Gabriel Barth-Maron, et al.\n“Distributed Distributional Deterministic Policy Gradients.”\nICLR 2018 poster.\n[19] Tuomas Haarnoja, Aurick Zhou, Pieter Abbeel, and Sergey Levine.\n“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”\narXiv preprint arXiv:1801.01290 (2018).\n[20] Scott Fujimoto, Herke van Hoof, and Dave Meger.\n“Addressing Function Approximation Error in Actor-Critic Methods.”\narXiv preprint arXiv:1802.09477 (2018).\n[21] Tuomas Haarnoja, et al.\n“Soft Actor-Critic Algorithms and Applications.”\narXiv preprint arXiv:1812.05905 (2018).\n[22] David Knowles.\n“Lagrangian Duality for Dummies”\nNov 13, 2010.\n[23] Yang Liu, et al.\n“Stein variational policy gradient.”\narXiv preprint arXiv:1704.02399 (2017).\n[24] Qiang Liu and Dilin Wang.\n“Stein variational gradient descent: A general purpose bayesian inference algorithm.”\nNIPS. 2016.\n[25] Lasse Espeholt, et al.\n“IMPALA: Scalable Distributed Deep-RL with Importance Weighted Actor-Learner Architectures”\narXiv preprint 1802.01561 (2018).\n[26] Karl Cobbe, et al.\n“Phasic Policy Gradient.”\narXiv preprint arXiv:2009.04416 (2020).\n[27] Chloe Ching-Yun Hsu, et al.\n“Revisiting Design Choices in Proximal Policy Optimization.”\narXiv preprint arXiv:2009.10897 (2020).",
            "metadata": {
              "title": "Policy Gradient Algorithms | Lil'Log",
              "description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "keywords": "reinforcement-learning, long-read, math-heavy",
              "author": "Lilian Weng",
              "og:title": "Policy Gradient Algorithms",
              "og:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
              "twitter:card": "summary",
              "twitter:title": "Policy Gradient Algorithms",
              "twitter:description": "[Updated on 2018-06-30: add two new policy gradient methods, SAC and D4PG.]\n\n[Updated on 2018-09-30: add a new policy gradient method, TD3.]\n\n[Updated on 2019-02-09: add SAC with automatically adjusted temperature].\n\n[Updated on 2019-06-26: Thanks to Chanseok, we have a version of this post in Korean].\n\n[Updated on 2019-09-12: add a new policy gradient method SVPG.]\n\n[Updated on 2019-12-22: add a new policy gradient method IMPALA.]\n\n[Updated on 2020-10-15: add a new policy gradient method PPG & some new discussion in PPO.]\n\n[Updated on 2021-09-19: Thanks to Wenhao & 爱吃猫的鱼, we have this post in Chinese1 & Chinese2].",
              "article:section": "posts",
              "article:published_time": "2018-04-08T00:00:00+00:00",
              "article:modified_time": "2018-04-08T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/ebc73787cbe5/code/body-000.txt",
                "chars": 226,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "bytes": 259350,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-394ec3f8b6a6ccc3dace.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/general_form_policy_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "bytes": 205392,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-9c60abbe659d28457d7a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/A3C_vs_A2C.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "bytes": 275060,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a8004105b4a88c05a952.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/DDPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "bytes": 581593,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-7bc12620d13d41e17f0a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/D4PG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "bytes": 215084,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a1617c1aadd4262ae84a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/MADDPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "bytes": 181566,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-01ca9a7ea1e7d1cd82a2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/ppo-loss-functions.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "bytes": 294810,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a362a645159f0dafa82d.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "bytes": 860130,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-fafbbe0c69813ea86bf2.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/PPG_exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "bytes": 742699,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-d58e26716f1f269dae8a.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "bytes": 300409,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-5e0d3d90650b6cca848e.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SAC2_algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "bytes": 497568,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-a29af53d479214903180.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/TD3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "bytes": 332210,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-0061164751ee7e193a70.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/SVPG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "bytes": 253972,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-58ac4a854eb578c151aa.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "bytes": 567524,
                "reused": false,
                "local_path": "attachments/ebc73787cbe5/images/body-6b398117113938e66d50.png",
                "src": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/IMPALA-arch.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://talkingaboutme.tistory.com/entry/RL-Policy-Gradient-Algorithms",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://tomaxent.com/2019/04/14/%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6%E6%96%B9%E6%B3%95/",
                "label": "Chinese1",
                "type": "a"
              },
              {
                "href": "https://paperexplained.cn/articles/article/detail/31/",
                "label": "Chinese2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "“A (Long) Peek into Reinforcement Learning » Key Concepts”",
                "type": "a"
              },
              {
                "href": "https://jeremykun.com/2015/04/06/markov-chain-monte-carlo-without-all-the-bullshit/",
                "label": "this",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Curse_of_dimensionality",
                "label": "curse of dimensionality",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "label": "Sutton & Barto, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.02438.pdf",
                "label": "GAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/04/02/notes-on-the-generalized-advantage-estimation-paper/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://danieltakeshi.github.io/2017/03/28/going-deeper-into-reinforcement-learning-fundamentals-of-policy-gradients/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://timvieira.github.io/blog/post/2014/12/21/importance-sampling/",
                "label": "importance weight",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1205.4839.pdf",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.01783",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dennybritz/reinforcement-learning/tree/master/PolicyGradient/a3c",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/blob/master/baselines/a2c/a2c.py",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/baselines-acktr-a2c/",
                "label": "shown",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1509.02971.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "label": "Batch normalization",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=SyZipzbCb",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05952",
                "label": "PER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1706.02275.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/maddpg",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1502.05477.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/trpo_mpi",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "KL divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL-divergence",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1707.06347.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/ppo1",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.10897",
                "label": "Hsu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.04416",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/phasic-policy-gradient",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.01588",
                "label": "Procgen",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.01224.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acer",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "label": "Retrace",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1708.05144.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/baselines/tree/master/baselines/acktr",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.05671.pdf",
                "label": "K-FAC",
                "type": "a"
              },
              {
                "href": "http://kvfrans.com/a-intuitive-explanation-of-natural-gradient-descent/",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.452.7280&rep=rep1&type=pdf",
                "label": "Natural Gradient Works Efficiently in Learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "label": "A Natural Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kronecker_product",
                "label": "Wiki: Kronecker product",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/martens15.pdf",
                "label": "Optimizing neural networks with kronecker-factored approximate curvature.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.01290",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/haarnoja/sac",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.08165",
                "label": "Soft Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.05905",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rail-berkeley/softlearning",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "label": "Lagrangian expression",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.09477",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sfujim/TD3",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/3964-double-q-learning",
                "label": "Double Q-learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1509.06461",
                "label": "Double DQN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/dilinwang820/Stein-Variational-Gradient-Descent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://www.cs.dartmouth.edu/~qliu/stein.html",
                "label": "Stein",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1608.04471",
                "label": "Liu and Wang, 2016",
                "type": "a"
              },
              {
                "href": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "label": "RKHS",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "Natural gradient",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Radial_basis_function",
                "label": "radial basis function",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01561",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/deepmind/scalable_agent",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.08617.pdf",
                "label": "“Distributed Distributional Deterministic Policy Gradients.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1801.01290.pdf",
                "label": "“Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor.”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "label": "“Stein variational gradient descent: A general purpose bayesian inference algorithm.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
            "papers": [
              {
                "status": "ok",
                "url": "http://incompleteideas.net/book/bookdraft2017nov5.pdf",
                "bytes": 12613382,
                "reused": false,
                "local_path": "papers/repair/7ea9e7044b38fbe00b3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438.pdf",
                "bytes": 1798117,
                "reused": false,
                "local_path": "papers/repair/be9d8b8466e33236e35e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1205.4839.pdf",
                "bytes": 1610077,
                "reused": false,
                "local_path": "papers/repair/5ab0424e24a7205667b6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.01783",
                "bytes": 2302720,
                "reused": true,
                "local_path": "papers/repair/4ebd69e62e1319a151ba.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/938992/filename/dpg-icml2014.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:39:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.02971.pdf",
                "bytes": 663643,
                "reused": false,
                "local_path": "papers/repair/cdfdf91c078ecbc5323f.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/ioffe15.pdf",
                "bytes": 318669,
                "reused": false,
                "local_path": "papers/repair/278c974d701b74b5258e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05952",
                "bytes": 1685573,
                "reused": false,
                "local_path": "papers/repair/232c5d788b53c3e83f28.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.02275.pdf",
                "bytes": 1502182,
                "reused": false,
                "local_path": "papers/repair/472ab942fc65a818d588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.05477.pdf",
                "bytes": 1026237,
                "reused": false,
                "local_path": "papers/repair/40909aa64b5fd4aacb8a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.06347.pdf",
                "bytes": 2923532,
                "reused": false,
                "local_path": "papers/repair/9e750b40bed5bcd1df74.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.10897",
                "bytes": 2074951,
                "reused": false,
                "local_path": "papers/repair/cb042047afd4ec37247c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.04416",
                "bytes": 2019980,
                "reused": false,
                "local_path": "papers/repair/e6984c4570bddcc10cbe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.01588",
                "bytes": 5158205,
                "reused": false,
                "local_path": "papers/repair/3231a0847e3982baa0a7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01224.pdf",
                "bytes": 1856923,
                "reused": false,
                "local_path": "papers/repair/49a104905756e51b1082.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6538-safe-and-efficient-off-policy-reinforcement-learning.pdf",
                "bytes": 309421,
                "reused": false,
                "local_path": "papers/repair/a3c6ca6c0f5fa7ac392b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05144.pdf",
                "bytes": 5151566,
                "reused": false,
                "local_path": "papers/repair/17bd1711b6b1c975cd6c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.05671.pdf",
                "bytes": 1801721,
                "reused": false,
                "local_path": "papers/repair/8348cabb06fa9a77e970.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/2073-a-natural-policy-gradient.pdf",
                "bytes": 1517587,
                "reused": false,
                "local_path": "papers/repair/5e5447a001f6bb409591.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/martens15.pdf",
                "bytes": 866438,
                "reused": false,
                "local_path": "papers/repair/cf98bb852a85a8c5a9be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/27be080213df12bc727f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.08165",
                "bytes": 3634452,
                "reused": false,
                "local_path": "papers/repair/cc481afce087c678bd26.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.05905",
                "bytes": 6750542,
                "reused": false,
                "local_path": "papers/repair/eb681f8429e54c661586.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/people/davidknowles/lagrangian_duality.pdf",
                "bytes": 157901,
                "reused": false,
                "local_path": "papers/repair/6d312b63b4d7133c0639.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.09477",
                "bytes": 2744342,
                "reused": false,
                "local_path": "papers/repair/b1cc41c6920f45d34ed8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1509.06461",
                "bytes": 789062,
                "reused": false,
                "local_path": "papers/repair/1b6dc947b906b3bd9192.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": false,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1608.04471",
                "bytes": 595069,
                "reused": false,
                "local_path": "papers/repair/55aec624e4d940526da7.pdf"
              },
              {
                "status": "download_error",
                "url": "http://mlss.tuebingen.mpg.de/2015/slides/gretton/part_1.pdf",
                "reason": "ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))",
                "retried_at": "2026-10-20T22:23:38Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01561",
                "bytes": 5601159,
                "reused": false,
                "local_path": "papers/repair/14d26b190854999d5443.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.08617.pdf",
                "bytes": 7734735,
                "reused": false,
                "local_path": "papers/repair/2db1af3554211ce5fb37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.01290.pdf",
                "bytes": 4388102,
                "reused": false,
                "local_path": "papers/repair/b36e949651aa96489b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/6338-stein-variational-gradient-descent-a-general-purpose-bayesian-inference-algorithm.pdf",
                "bytes": 477157,
                "reused": false,
                "local_path": "papers/repair/bb0557ad03965422dda1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 76635,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/ebc73787cbe5/pages/source.html",
            "local_html": "attachments/ebc73787cbe5/pages/article.html",
            "body_base_path": "attachments/ebc73787cbe5/pages/",
            "body_markdown_path": "attachments/ebc73787cbe5/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
          "status": "ok",
          "article_id": "dcd5da018bf2",
          "local_path": "series-follow/1601/repair/827224e799e103f1e0f7.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9b7d412df1022e9dd836.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/25f0b2690092af605c3d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7d80cffa1089cf5d2768.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
              "bytes": 570814,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/df4282f24e52a002c1e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
              "bytes": 464230,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cab3cb57db5f98d84069.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
              "bytes": 420355,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0f97e3b0cd6e0f9d33d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
              "bytes": 128314,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ce9b993dcf304f3ee690.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
              "bytes": 49638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/aea346be74eb04186d40.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
              "bytes": 92635,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/73a84b0003e99b52aabb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
              "bytes": 244624,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dcd62d1b6219e852f4e7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/33280c015fb683b19da0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
              "bytes": 306995,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/14870bcbb3ef6e114eb5.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/86a19bc020c6f7606039.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
              "bytes": 118602,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cc3c4b64a92e45404da4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a987ca8a4f296dda91fa.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family",
            "keywords": "Transformer,自注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "publish_date": "2020-04",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer家族综述（初版）",
            "id": "dcd5da018bf2",
            "collected_at": "2026-10-02T14:13:14",
            "title": "The Transformer Family | Lil'Log",
            "body_markdown": "[Updated on\n2023-01-27\n: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here:\nThe Transformer Family Version 2.0\n. Please refer to that post on this topic.]\nIt has been almost two years since my last post on\nattention\n. Recent progress on new and enhanced versions of Transformer motivates me to write another post on this specific topic, focusing on how the vanilla Transformer can be improved for longer-term attention span, less memory and computation consumption, RL task solving and more.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of length $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in the neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\mathbf{q}_i {\\mathbf{k}_j}^\\top)}{ \\sqrt{d_k} \\sum_{r \\in S_i} \\exp(\\mathbf{q}_i {\\mathbf{k}_r}^\\top) }\n$$\nSee my old\npost\nfor other types of attention if interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttention}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nTransformer\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nEncoder-Decoder Architecture\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\n(1)\nSinusoidal positional encoding\nis defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\n(2)\nLearned positional encoding\n, as its name suggested, assigns each element with a learned column vector which encodes its\nabsolute\nposition (\nGehring, et al. 2017\n).\nQuick Follow-ups\nFollowing the vanilla Transformer,\nAl-Rfou et al. (2018)\nadded a set of auxiliary losses to enable training a deep Transformer model on character-level language modeling which outperformed LSTMs. Several types of auxiliary tasks are used:\nInstead of producing only one prediction at the sequence end, every\nimmediate position\nis also asked to make a correct prediction, forcing the model to predict given smaller contexts (e.g. first couple tokens at the beginning of a context window).\nEach intermediate Transformer layer is used for making predictions as well. Lower layers are weighted to contribute less and less to the total loss as training progresses.\nEach position in the sequence can predict multiple targets, i.e. two or more predictions of the future tokens.\nAuxiliary prediction tasks used in deep Transformer for character-level language modeling. (Image source:\nAl-Rfou et al. (2018)\n)\nAdaptive Computation Time (ACT)\n#\nAdaptive Computation Time\n(short for\nACT\n;\nGraves, 2016\n) is a mechanism for dynamically deciding how many computational steps are needed in a recurrent neural network. Here is a cool\ntutorial\non ACT from distill.pub.\nLet’s say, we have a RNN model $\\mathcal{R}$ composed of input weights $W_x$, a parametric state transition function $\\mathcal{S}(.)$, a set of output weights $W_y$ and an output bias $b_y$. Given an input sequence $(x_1, \\dots, x_L)$, the output sequence $(y_1, \\dots, y_L)$ is computed by:\n$$\ns_t = \\mathcal{S}(s_{t-1}, W_x x_t), \\quad y_t = W_y s_t + b_y\\quad\\text{for }t=1, \\dots, L\n$$\nACT enables the above RNN setup to perform a variable number of steps at each input element. Multiple computational steps lead to a sequence of intermediate states $(s_t^1, \\dots, s_t^{N(t)})$ and outputs $(y_t^1, \\dots, y_t^{N(t)})$ — they all share the same state transition function $\\mathcal{S}(.)$, as well as the same output weights $W_y$ and bias $b_y$:\n$$\n\\begin{aligned}\ns_t^0 &= s_{t-1} \\\\\ns_t^n &= \\mathcal{S}(s_{t}^{n-1}, x_t^n) = \\mathcal{S}(s_{t}^{n-1}, x_t + \\delta_{n,1}) \\text{ for } n=1, \\dots, N(t)\\\\\ny_t^n &= W_y s_t^n + b_y\n\\end{aligned}\n$$\nwhere $\\delta_{n,1}$ is a binary flag indicating whether the input step has been incremented.\nThe number of steps $N(t)$ is determined by an extra sigmoidal halting unit $h$, with associated weight matrix $W_h$ and bias $b_h$, outputting a halting probability $p_t^n$ at immediate step $n$ for $t$-th input element:\n$$\nh_t^n = \\sigma(W_h s_t^n + b_h)\n$$\nIn order to allow the computation to halt after a single step, ACT introduces a small constant $\\epsilon$ (e.g. 0.01), so that whenever the cumulative probability goes above $1-\\epsilon$, the computation stops.\n$$\n\\begin{aligned}\nN(t) &= \\min(\\min\\{n': \\sum_{n=1}^{n'} h_t^n \\geq 1 -\\epsilon\\}, M) \\\\\np_t^n &= \\begin{cases}\nh_t^n & \\text{if }n < N(t) \\\\\nR(t) = 1 - \\sum_{n=1}^{N(t)-1} h_t^n & \\text{if }n= N(t)\\\\\n\\end{cases}\n\\end{aligned}\n$$\nwhere $M$ is an upper limit for the number of immediate steps allowed.\nThe final state and output are mean-field updates:\n$$\ns_t = \\sum_{n=1}^{N(t)} p_t^n s_t^n,\\quad y_t = \\sum_{n=1}^{N(t)} p_t^n y_t^n\n$$\nThe computation graph of a RNN with ACT mechanism. (Image source:\nGraves, 2016\n)\nTo avoid unnecessary pondering over each input, ACT adds a\nponder cost\n$\\mathcal{P}(x) = \\sum_{t=1}^L N(t) + R(t) $  in the loss function to encourage a smaller number of intermediate computational steps.\nImproved Attention Span\n#\nThe goal of improving attention span is to make the context that can be used in self-attention longer, more efficient and flexible.\nLonger Attention Span (Transformer-XL)\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments.\nThis\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) solves the context segmentation problem with two main modifications:\nReusing hidden states between segments.\nAdopting a new positional encoding that is suitable for reused states.\nHidden State Reuse\nThe recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both key and value rely on the extended hidden state, while the query only consumes hidden state at current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension.\nRelative Positional Encoding\nIn order to work with this new form of attention span, Transformer-XL proposed a new type of positional encoding. If using the same approach by vanilla Transformer and encoding the absolute position, the previous and current segments will be assigned with the same encoding, which is undesired.\nTo keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar, et al., (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 7) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys at positions $j \\in S_i$, where $S_i$ defineds the $i$-th token’s context window.\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clamp}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nLocalized Attention Span (Image Transformer)\n#\nThe original, also the most popular, use case for Transformer is to do language modeling. The text sequence is one-dimensional in a clearly defined chronological order and thus the attention span grows linearly with increased context size.\nHowever, if we want to use Transformer on images, it is unclear how to define the scope of context or the order.\nImage Transformer\n(\nParmer, et al 2018\n) embraces a formulation of image generation similar to sequence modeling within the Transformer framework. Additionally, Image Transformer restricts the self-attention span to only\nlocal\nneighborhoods, so that the model can scale up to process more images in parallel and keep the likelihood loss tractable.\nThe encoder-decoder architecture remains for image-conditioned generation:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThe decoder\nautoregressively\ngenerates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n(1)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n(2)\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nLess Time and Memory Cost\n#\nThis section introduces several improvements made on Transformer to reduce the computation time and memory consumption.\nSparse Attention Matrix Factorization (Sparse Transformers)\n#\nThe compute and memory cost of the vanilla Transformer grows quadratically with sequence length and thus it is hard to be applied on very long sequences.\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn anto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\n(1)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\nA_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n\\end{aligned}\n$$\n(2)\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n\\begin{aligned}\nA_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\nA_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n\\end{aligned}\n$$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attention}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. => This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details.\nLocality-Sensitive Hashing (Reformer)\n#\nThe improvements proposed by the\nReformer\nmodel (\nKitaev, et al. 2020\n) aim to solve the following pain points in Transformer:\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nThe attention matrix on sequences of length $L$ often requires $O(L^2)$ in both memory and time.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $O(L^2)$ to $O(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 11:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nMake it Recurrent (Universal Transformer)\n#\nThe\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN.\nRather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{H}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{H}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{H}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{H}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{H}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses sinusoidal position signal but with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{H}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nStabilization for RL (GTrXL)\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Apr 2020). The transformer family. Lil’Log. https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/.\nOr\n@article{weng2020transformer,\n  title   = \"The Transformer Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Apr\",\n  url     = \"https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/\"\n}\nReference\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).",
            "metadata": {
              "title": "The Transformer Family | Lil'Log",
              "description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "keywords": "architecture, attention, transformer, foundation, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family",
              "og:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family",
              "twitter:description": "[Updated on 2023-01-27: After almost three years, I did a big refactoring update of this post to incorporate a bunch of new Transformer models since 2020. The enhanced version of this post is here: The Transformer Family Version 2.0. Please refer to that post on this topic.]",
              "article:section": "posts",
              "article:published_time": "2020-04-07T00:00:00+00:00",
              "article:modified_time": "2020-04-07T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/dcd5da018bf2/code/body-000.txt",
                "chars": 257,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-9b7d412df1022e9dd836.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-25f0b2690092af605c3d.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-7d80cffa1089cf5d2768.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "bytes": 570814,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-df4282f24e52a002c1e4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-aux-losses.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "bytes": 464230,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cab3cb57db5f98d84069.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/ACT-computation-graph.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-0f97e3b0cd6e0f9d33d1.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-ce9b993dcf304f3ee690.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-aea346be74eb04186d40.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-73a84b0003e99b52aabb.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-dcd62d1b6219e852f4e7.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-33280c015fb683b19da0.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-14870bcbb3ef6e114eb5.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-86a19bc020c6f7606039.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-cc3c4b64a92e45404da4.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/dcd5da018bf2/images/body-a987ca8a4f296dda91fa.png",
                "src": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
                "label": "The Transformer Family Version 2.0",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08983",
                "label": "Graves, 2016",
                "type": "a"
              },
              {
                "href": "https://distill.pub/2016/augmented-rnns/",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar, et al., (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": true,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": true,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08983",
                "bytes": 6582868,
                "reused": false,
                "local_path": "papers/repair/b07529fb4c15758ccb0e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": true,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": true,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": true,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": true,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": true,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": true,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": true,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": true,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": true,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": true,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 36377,
            "expected_body_images": 15,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/dcd5da018bf2/pages/source.html",
            "local_html": "attachments/dcd5da018bf2/pages/article.html",
            "body_base_path": "attachments/dcd5da018bf2/pages/",
            "body_markdown_path": "attachments/dcd5da018bf2/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
          "status": "partial",
          "article_id": "cd59f7ee3fdb",
          "local_path": "series-follow/1601/repair/8804f3f0e1a2da8b46c4.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
              "bytes": 137292,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/db59b90d279b037a97d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
              "bytes": 256981,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ab7006570b99c84db1b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
              "bytes": 26225,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1c83c8f4d8be7a5b4c49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
              "bytes": 1878475,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2e93bdc2c46162899b3f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
              "bytes": 151943,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/13d9a58c515022883c19.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
              "bytes": 482588,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ee2f9d9fbcd3aed80f31.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
              "bytes": 188866,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2351ecad009ac2895562.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
              "bytes": 274889,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/fae191e6a32c13b2540d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
              "bytes": 806890,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9610ae1d4a5d7cbb7454.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
              "bytes": 943633,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e326acd6fdf8195c78b9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
              "bytes": 594737,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/91ba8add21dff9815090.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
              "bytes": 207374,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7020e37618b19a5457cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
              "bytes": 946267,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/da329904d7433579a338.png"
            }
          ],
          "article": {
            "id": "cd59f7ee3fdb",
            "url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "source_excel_row": 1600,
            "source_url": "https://lilianweng.github.io/posts/2018-08-12-vae/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "bytes": 137292,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-db59b90d279b037a97d1.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "bytes": 256981,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ab7006570b99c84db1b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/denoising-autoencoder-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "bytes": 26225,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-1c83c8f4d8be7a5b4c49.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/kl-metric-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "bytes": 1878475,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2e93bdc2c46162899b3f.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/k-sparse-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "bytes": 151943,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-13d9a58c515022883c19.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VAE-graphical-model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "bytes": 482588,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-ee2f9d9fbcd3aed80f31.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/forward_vs_reversed_KL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "bytes": 188866,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-2351ecad009ac2895562.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/reparameterization-trick.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "bytes": 274889,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-fae191e6a32c13b2540d.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/vae-gaussian.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "bytes": 806890,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-9610ae1d4a5d7cbb7454.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "bytes": 943633,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-e326acd6fdf8195c78b9.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "bytes": 594737,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-91ba8add21dff9815090.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/VQ-VAE-2-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "bytes": 207374,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-7020e37618b19a5457cc.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE-state-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "bytes": 946267,
                "reused": true,
                "local_path": "attachments/cd59f7ee3fdb/images/body-da329904d7433579a338.png",
                "src": "https://lilianweng.github.io/posts/2018-08-12-vae/TD-VAE.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "src": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/cd59f7ee3fdb/videos/repair-9zKuYvjFFS8.mp4",
                "bytes": 119566312,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "905.001000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-07-18: add a section on\nVQ-VAE & VQ-VAE-2\n.]\n[Updated on 2019-07-26: add a section on\nTD-VAE\n.]\nAutocoder is invented to reconstruct high-dimensional data using a neural network model with a narrow bottleneck layer in the middle (oops, this is probably not true for\nVariational Autoencoder\n, and we will investigate it in details in later sections). A nice byproduct is dimension reduction: the bottleneck layer captures a compressed latent encoding. Such a low-dimensional representation can be used as en embedding vector in various applications (i.e. search), help data compression, or reveal the underlying data generative factors.\nNotation\n#\nSymbol\nMean\n$\\mathcal{D}$\nThe dataset, $\\mathcal{D} = \\{ \\mathbf{x}^{(1)}, \\mathbf{x}^{(2)}, \\dots, \\mathbf{x}^{(n)} \\}$, contains $n$ data samples; $\\vert\\mathcal{D}\\vert =n $.\n$\\mathbf{x}^{(i)}$\nEach data point is a vector of $d$ dimensions, $\\mathbf{x}^{(i)} = [x^{(i)}_1, x^{(i)}_2, \\dots, x^{(i)}_d]$.\n$\\mathbf{x}$\nOne data sample from the dataset, $\\mathbf{x} \\in \\mathcal{D}$.\n$\\mathbf{x}’$\nThe reconstructed version of $\\mathbf{x}$.\n$\\tilde{\\mathbf{x}}$\nThe corrupted version of $\\mathbf{x}$.\n$\\mathbf{z}$\nThe compressed code learned in the bottleneck layer.\n$a_j^{(l)}$\nThe activation function for the $j$-th neuron in the $l$-th hidden layer.\n$g_{\\phi}(.)$\nThe\nencoding\nfunction parameterized by $\\phi$.\n$f_{\\theta}(.)$\nThe\ndecoding\nfunction parameterized by $\\theta$.\n$q_{\\phi}(\\mathbf{z}\\vert\\mathbf{x})$\nEstimated posterior probability function, also known as\nprobabilistic encoder\n.\n$p_{\\theta}(\\mathbf{x}\\vert\\mathbf{z})$\nLikelihood of generating true data sample given the latent code, also known as\nprobabilistic decoder\n.\nAutoencoder\n#\nAutoencoder\nis a neural network designed to learn an identity function in an unsupervised way  to reconstruct the original input while compressing the data in the process so as to discover a more efficient and compressed representation. The idea was originated in\nthe 1980s\n, and later promoted by the seminal paper by\nHinton & Salakhutdinov, 2006\n.\nIt consists of two networks:\nEncoder\nnetwork: It translates the original high-dimension input into the latent low-dimensional code. The input size is larger than the output size.\nDecoder\nnetwork: The decoder network recovers the data from the code, likely with larger and larger output layers.\nIllustration of autoencoder model architecture.\nThe encoder network essentially accomplishes the\ndimensionality reduction\n, just like how we would use Principal Component Analysis (PCA) or Matrix Factorization (MF) for. In addition, the autoencoder is explicitly optimized for the data reconstruction from the code. A good intermediate representation not only can capture latent variables, but also benefits a full\ndecompression\nprocess.\nThe model contains an encoder function $g(.)$ parameterized by $\\phi$ and a decoder function $f(.)$ parameterized by $\\theta$. The low-dimensional code learned for input $\\mathbf{x}$ in the bottleneck layer is $\\mathbf{z} = g_\\phi(\\mathbf{x})$ and the reconstructed input is $\\mathbf{x}’ = f_\\theta(g_\\phi(\\mathbf{x}))$.\nThe parameters $(\\theta, \\phi)$ are learned together to output a reconstructed data sample same as the original input, $\\mathbf{x} \\approx f_\\theta(g_\\phi(\\mathbf{x}))$, or in other words, to learn an identity function. There are various metrics to quantify the difference between two vectors, such as cross entropy when the activation function is sigmoid, or as simple as MSE loss:\n$$\nL_\\text{AE}(\\theta, \\phi) = \\frac{1}{n}\\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\mathbf{x}^{(i)})))^2\n$$\nDenoising Autoencoder\n#\nSince the autoencoder learns the identity function, we are facing the risk of “overfitting” when there are more network parameters than the number of data points.\nTo avoid overfitting and improve the robustness,\nDenoising Autoencoder\n(Vincent et al. 2008) proposed a modification to the basic autoencoder. The input is partially corrupted by adding noises to or masking some values of the input vector in a stochastic manner, $\\tilde{\\mathbf{x}} \\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$. Then the model is trained to recover the original input (note: not the corrupt one).\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{x}}^{(i)} &\\sim \\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}}^{(i)} \\vert \\mathbf{x}^{(i)})\\\\\nL_\\text{DAE}(\\theta, \\phi) &= \\frac{1}{n} \\sum_{i=1}^n (\\mathbf{x}^{(i)} - f_\\theta(g_\\phi(\\tilde{\\mathbf{x}}^{(i)})))^2\n\\end{aligned}\n$$\nwhere $\\mathcal{M}_\\mathcal{D}$ defines the mapping from the true data samples to the noisy or corrupted ones.\nIllustration of denoising autoencoder model architecture.\nThis design is motivated by the fact that humans can easily recognize an object or a scene even the view is partially occluded or corrupted. To “repair” the partially destroyed input, the denoising autoencoder has to discover and capture relationship between dimensions of input in order to infer missing pieces.\nFor high dimensional input with high redundancy, like images, the model is likely to depend on evidence gathered from a combination of many input dimensions to recover the denoised version rather than to overfit one dimension. This builds up a good foundation for learning\nrobust\nlatent representation.\nThe noise is controlled by a stochastic mapping $\\mathcal{M}_\\mathcal{D}(\\tilde{\\mathbf{x}} \\vert \\mathbf{x})$, and it is not specific to a particular type of corruption process (i.e. masking noise, Gaussian noise, salt-and-pepper noise, etc.). Naturally the corruption process can be equipped with prior knowledge\nIn the experiment of the original DAE paper, the noise is applied in this way: a fixed proportion of input dimensions are selected at random and their values are forced to 0. Sounds a lot like dropout, right? Well, the denoising autoencoder was proposed in 2008, 4 years before the dropout paper (\nHinton, et al. 2012\n) ;)\nSparse Autoencoder\n#\nSparse Autoencoder\napplies a “sparse” constraint on the hidden unit activation to avoid overfitting and improve robustness. It forces the model to only have a small number of hidden units being activated at the same time, or in other words, one hidden neuron should be inactivate most of time.\nRecall that common\nactivation functions\ninclude sigmoid, tanh, relu, leaky relu, etc. A neuron is activated when the value is close to 1 and inactivate with a value close to 0.\nLet’s say there are $s_l$ neurons in the $l$-th hidden layer and the activation function for the $j$-th neuron in this layer is labelled as $a^{(l)}_j(.)$, $j=1, \\dots, s_l$. The fraction of activation of this neuron $\\hat{\\rho}_j$ is expected to be a small number $\\rho$, known as\nsparsity parameter\n; a common config is $\\rho = 0.05$.\n$$\n\\hat{\\rho}_j^{(l)} = \\frac{1}{n} \\sum_{i=1}^n [a_j^{(l)}(\\mathbf{x}^{(i)})] \\approx \\rho\n$$\nThis constraint is achieved by adding a penalty term into the loss function. The KL-divergence $D_\\text{KL}$ measures the difference between two Bernoulli distributions, one with mean $\\rho$ and the other with mean $\\hat{\\rho}_j^{(l)}$. The hyperparameter $\\beta$ controls how strong the penalty we want to apply on the sparsity loss.\n$$\n\\begin{aligned}\nL_\\text{SAE}(\\theta) \n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} D_\\text{KL}(\\rho \\| \\hat{\\rho}_j^{(l)}) \\\\\n&= L(\\theta) + \\beta \\sum_{l=1}^L \\sum_{j=1}^{s_l} \\rho\\log\\frac{\\rho}{\\hat{\\rho}_j^{(l)}} + (1-\\rho)\\log\\frac{1-\\rho}{1-\\hat{\\rho}_j^{(l)}}\n\\end{aligned}\n$$\nThe KL divergence between a Bernoulli distribution with mean $\\rho=0.25$ and a Bernoulli distribution with mean $0 \\leq \\hat{\\rho} \\leq 1$.\n$k$-Sparse Autoencoder\nIn $k$-Sparse Autoencoder (\nMakhzani and Frey, 2013\n), the sparsity is enforced by only keeping the top k highest activations in the bottleneck layer with linear activation function.\nFirst we run feedforward through the encoder network to get the compressed code: $\\mathbf{z} = g(\\mathbf{x})$.\nSort the values  in the code vector $\\mathbf{z}$. Only the k largest values are kept while other neurons are set to 0. This can be done in a ReLU layer with an adjustable threshold too. Now we have a sparsified code: $\\mathbf{z}’ = \\text{Sparsify}(\\mathbf{z})$.\nCompute the output and the loss from the sparsified code, $L = |\\mathbf{x} - f(\\mathbf{z}’) |_2^2$.\nAnd, the back-propagation only goes through the top k activated hidden units!\nFilters of the k-sparse autoencoder for different sparsity levels k, learnt from MNIST with 1000 hidden units.. (Image source:\nMakhzani and Frey, 2013\n)\nContractive Autoencoder\n#\nSimilar to sparse autoencoder,\nContractive Autoencoder\n(\nRifai, et al, 2011\n) encourages the learned representation to stay in a contractive space for better robustness.\nIt adds a term in the loss function to penalize the representation being too sensitive to the input,  and thus improve the robustness to small perturbations around the training data points. The sensitivity is measured by the Frobenius norm of the Jacobian matrix of the encoder activations with respect to the input:\n$$\n\\|J_f(\\mathbf{x})\\|_F^2 = \\sum_{ij} \\Big( \\frac{\\partial h_j(\\mathbf{x})}{\\partial x_i} \\Big)^2\n$$\nwhere $h_j$ is one unit output in the compressed code $\\mathbf{z} = f(x)$.\nThis penalty term is the sum of squares of all partial derivatives of the learned encoding with respect to input dimensions. The authors claimed that empirically this penalty was found to  carve a representation that corresponds to a lower-dimensional non-linear manifold, while staying more invariant to majority directions orthogonal to the manifold.\nVAE: Variational Autoencoder\n#\nThe idea of\nVariational Autoencoder\n(\nKingma & Welling, 2014\n), short for\nVAE\n, is actually less similar to all the autoencoder models above, but deeply rooted in the methods of variational bayesian and graphical model.\nInstead of mapping the input into a\nfixed\nvector, we want to map it into a distribution. Let’s label this distribution as $p_\\theta$, parameterized by $\\theta$.  The relationship between the data input $\\mathbf{x}$ and the latent encoding vector $\\mathbf{z}$ can be fully defined by:\nPrior $p_\\theta(\\mathbf{z})$\nLikelihood $p_\\theta(\\mathbf{x}\\vert\\mathbf{z})$\nPosterior $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$\nAssuming that we know the real parameter $\\theta^{*}$ for this distribution. In order to generate a sample that looks like a real data point $\\mathbf{x}^{(i)}$, we follow these steps:\nFirst, sample a $\\mathbf{z}^{(i)}$ from a prior distribution $p_{\\theta^*}(\\mathbf{z})$.\nThen a value $\\mathbf{x}^{(i)}$ is generated from a conditional distribution $p_{\\theta^*}(\\mathbf{x} \\vert \\mathbf{z} = \\mathbf{z}^{(i)})$.\nThe optimal parameter $\\theta^{*}$ is the one that maximizes the probability of generating real data samples:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\prod_{i=1}^n p_\\theta(\\mathbf{x}^{(i)})\n$$\nCommonly we use the log probabilities to convert the product on RHS to a sum:\n$$\n\\theta^{*} = \\arg\\max_\\theta \\sum_{i=1}^n \\log p_\\theta(\\mathbf{x}^{(i)})\n$$\nNow let’s update the equation to better demonstrate the data generation process so as to involve the encoding vector:\n$$\np_\\theta(\\mathbf{x}^{(i)}) = \\int p_\\theta(\\mathbf{x}^{(i)}\\vert\\mathbf{z}) p_\\theta(\\mathbf{z}) d\\mathbf{z} \n$$\nUnfortunately it is not easy to compute $p_\\theta(\\mathbf{x}^{(i)})$ in this way, as it is very expensive to check all the possible values of $\\mathbf{z}$ and sum them up. To narrow down the value space to facilitate faster search, we would like to introduce a new approximation function to output what is a likely code given an input $\\mathbf{x}$, $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$, parameterized by $\\phi$.\nThe graphical model involved in Variational Autoencoder.  Solid lines denote the generative distribution $p\\_\\theta(.)$ and dashed lines denote the distribution $q\\_\\phi (\\mathbf{z}\\vert\\mathbf{x})$ to approximate the intractable posterior $p\\_\\theta (\\mathbf{z}\\vert\\mathbf{x})$.\nNow the structure looks a lot like an autoencoder:\nThe conditional probability $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ defines a generative model, similar to the decoder $f_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ introduced above. $p_\\theta(\\mathbf{x} \\vert \\mathbf{z})$ is also known as\nprobabilistic decoder\n.\nThe approximation function $q_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ is the\nprobabilistic encoder\n, playing a similar role as $g_\\phi(\\mathbf{z} \\vert \\mathbf{x})$ above.\nLoss Function: ELBO\n#\nThe estimated posterior $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ should be very close to the real one $p_\\theta(\\mathbf{z}\\vert\\mathbf{x})$. We can use\nKullback-Leibler divergence\nto quantify the distance between these two distributions. KL divergence $D_\\text{KL}(X|Y)$ measures how much information is lost if the distribution Y is used to represent X.\nIn our case we want to minimize $D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) | p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )$ with respect to $\\phi$.\nBut why use $D_\\text{KL}(q_\\phi | p_\\theta)$ (reversed KL) instead of $D_\\text{KL}(p_\\theta | q_\\phi)$ (forward KL)? Eric Jang has a great explanation in his\npost\non Bayesian Variational methods. As a quick recap:\nForward and reversed KL divergence have different demands on how to match two distributions. (Image source:\nblog.evjang.com/2016/08/variational-bayes.html\n)\nForward KL divergence: $D_\\text{KL}(P|Q) = \\mathbb{E}_{z\\sim P(z)} \\log\\frac{P(z)}{Q(z)}$; we have to ensure that Q(z)>0 wherever P(z)>0. The optimized variational distribution $q(z)$ has to cover over the entire $p(z)$.\nReversed KL divergence: $D_\\text{KL}(Q|P) = \\mathbb{E}_{z\\sim Q(z)} \\log\\frac{Q(z)}{P(z)}$; minimizing the reversed KL divergence squeezes the $Q(z)$ under $P(z)$.\nLet’s now expand the equation:\n$$\n\\begin{aligned}\n& D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z} \\vert \\mathbf{x})} d\\mathbf{z} & \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})p_\\theta(\\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z \\vert x) = p(z, x) / p(x)} \\\\\n&=\\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x}) \\big( \\log p_\\theta(\\mathbf{x}) + \\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} \\big) d\\mathbf{z} & \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z}, \\mathbf{x})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }\\int q(z \\vert x) dz = 1}\\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\int q_\\phi(\\mathbf{z} \\vert \\mathbf{x})\\log\\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{x}\\vert\\mathbf{z})p_\\theta(\\mathbf{z})} d\\mathbf{z} & \\scriptstyle{\\text{; Because }p(z, x) = p(x \\vert z) p(z)} \\\\\n&=\\log p_\\theta(\\mathbf{x}) + \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}[\\log \\frac{q_\\phi(\\mathbf{z} \\vert \\mathbf{x})}{p_\\theta(\\mathbf{z})} - \\log p_\\theta(\\mathbf{x} \\vert \\mathbf{z})] &\\\\\n&=\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) &\n\\end{aligned}\n$$\nSo we have:\n$$\nD_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) =\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z})) - \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})\n$$\nOnce rearrange the left and right hand side of the equation,\n$$\n\\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) = \\mathbb{E}_{\\mathbf{z}\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})}\\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}))\n$$\nThe LHS of the equation is exactly what we want to maximize when learning the true distributions: we want to maximize the (log-)likelihood of generating real data (that is $\\log p_\\theta(\\mathbf{x})$) and also minimize the difference between the real and estimated posterior distributions (the term $D_\\text{KL}$ works like a regularizer).  Note that $p_\\theta(\\mathbf{x})$ is fixed with respect to $q_\\phi$.\nThe negation of the above defines our loss function:\n$$\n\\begin{aligned}\nL_\\text{VAE}(\\theta, \\phi) \n&= -\\log p_\\theta(\\mathbf{x}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) )\\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}) ) \\\\\n\\theta^{*}, \\phi^{*} &= \\arg\\min_{\\theta, \\phi} L_\\text{VAE}\n\\end{aligned}\n$$\nIn Variational Bayesian methods, this loss function is known as the\nvariational lower bound\n, or\nevidence lower bound\n. The “lower bound” part in the name comes from the fact that KL divergence is always non-negative and thus $-L_\\text{VAE}$ is the lower bound of $\\log p_\\theta (\\mathbf{x})$.\n$$\n-L_\\text{VAE} = \\log p_\\theta(\\mathbf{x}) - D_\\text{KL}( q_\\phi(\\mathbf{z}\\vert\\mathbf{x}) \\| p_\\theta(\\mathbf{z}\\vert\\mathbf{x}) ) \\leq \\log p_\\theta(\\mathbf{x})\n$$\nTherefore by minimizing the loss, we are maximizing the lower bound of the probability of generating real data samples.\nReparameterization Trick\n#\nThe expectation term in the loss function invokes generating samples from $\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$. Sampling is a stochastic process and therefore we cannot backpropagate the gradient. To make it trainable, the reparameterization trick is introduced: It is often possible to express the random variable $\\mathbf{z}$ as a deterministic variable $\\mathbf{z} = \\mathcal{T}_\\phi(\\mathbf{x}, \\boldsymbol{\\epsilon})$, where $\\boldsymbol{\\epsilon}$ is an auxiliary independent random variable, and the transformation function $\\mathcal{T}_\\phi$ parameterized by $\\phi$ converts $\\boldsymbol{\\epsilon}$ to $\\mathbf{z}$.\nFor example, a common choice of the form of $q_\\phi(\\mathbf{z}\\vert\\mathbf{x})$ is a multivariate Gaussian with a diagonal covariance structure:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x}^{(i)}) = \\mathcal{N}(\\mathbf{z}; \\boldsymbol{\\mu}^{(i)}, \\boldsymbol{\\sigma}^{2(i)}\\boldsymbol{I}) & \\\\\n\\mathbf{z} &= \\boldsymbol{\\mu} + \\boldsymbol{\\sigma} \\odot \\boldsymbol{\\epsilon} \\text{, where } \\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I}) & \\scriptstyle{\\text{; Reparameterization trick.}}\n\\end{aligned}\n$$\nwhere $\\odot$ refers to element-wise product.\nIllustration of how the reparameterization trick makes the $\\mathbf{z}$ sampling process trainable.(Image source: Slide 12 in Kingma’s NIPS 2015 workshop\ntalk\n)\nThe reparameterization trick works for other types of distributions too, not only Gaussian.\nIn the multivariate Gaussian case, we make the model trainable by learning the mean and variance of the distribution, $\\mu$ and $\\sigma$, explicitly using the reparameterization trick, while the stochasticity remains in the random variable $\\boldsymbol{\\epsilon} \\sim \\mathcal{N}(0, \\boldsymbol{I})$.\nIllustration of variational autoencoder model with the multivariate Gaussian assumption.\nBeta-VAE\n#\nIf each variable in the inferred latent representation $\\mathbf{z}$ is only sensitive to one single generative factor and relatively invariant to other factors, we will say this representation is disentangled or factorized. One benefit that often comes with disentangled representation is\ngood interpretability\nand easy generalization to a variety of tasks.\nFor example, a model trained on photos of human faces might capture the gentle, skin color, hair color, hair length, emotion, whether wearing a pair of glasses and many other relatively independent factors in separate dimensions. Such a disentangled representation is very beneficial to facial image generation.\nβ-VAE (\nHiggins et al., 2017\n) is a modification of Variational Autoencoder with a special emphasis to discover disentangled latent factors. Following the same incentive in VAE, we want to maximize the probability of generating real data, while keeping the distance between the real and estimated posterior distributions small (say, under a small constant $\\delta$):\n$$\n\\begin{aligned}\n&\\max_{\\phi, \\theta} \\mathbb{E}_{\\mathbf{x}\\sim\\mathcal{D}}[\\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z})]\\\\\n&\\text{subject to } D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) < \\delta\n\\end{aligned}\n$$\nWe can rewrite it as a Lagrangian with a Lagrangian multiplier $\\beta$ under the\nKKT condition\n. The above optimization problem with only one inequality constraint is equivalent to maximizing the following equation $\\mathcal{F}(\\theta, \\phi, \\beta)$:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta, \\phi, \\beta) &= \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta(D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) - \\delta) & \\\\\n& = \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) + \\beta \\delta & \\\\\n& \\geq \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) - \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z})) & \\scriptstyle{\\text{; Because }\\beta,\\delta\\geq 0}\n\\end{aligned}\n$$\nThe loss function of $\\beta$-VAE is defined as:\n$$\nL_\\text{BETA}(\\phi, \\beta) = - \\mathbb{E}_{\\mathbf{z} \\sim q_\\phi(\\mathbf{z}\\vert\\mathbf{x})} \\log p_\\theta(\\mathbf{x}\\vert\\mathbf{z}) + \\beta D_\\text{KL}(q_\\phi(\\mathbf{z}\\vert\\mathbf{x})\\|p_\\theta(\\mathbf{z}))\n$$\nwhere the Lagrangian multiplier $\\beta$ is considered as a hyperparameter.\nSince the negation of $L_\\text{BETA}(\\phi, \\beta)$ is the lower bound of the Lagrangian $\\mathcal{F}(\\theta, \\phi, \\beta)$. Minimizing the loss is equivalent to maximizing the Lagrangian and thus works for our initial optimization problem.\nWhen $\\beta=1$, it is same as VAE. When $\\beta > 1$, it applies a stronger constraint on the latent bottleneck and limits the representation capacity of $\\mathbf{z}$. For some conditionally independent generative factors, keeping them disentangled is the most efficient representation. Therefore a higher $\\beta$ encourages more efficient latent encoding and further encourages the disentanglement. Meanwhile, a higher $\\beta$ may create a trade-off between reconstruction quality and the extent of disentanglement.\nBurgess, et al. (2017)\ndiscussed the distentangling in $\\beta$-VAE in depth with an inspiration by the\ninformation bottleneck theory\nand further proposed a modification to $\\beta$-VAE to better control the encoding representation capacity.\nVQ-VAE and VQ-VAE-2\n#\nThe\nVQ-VAE\n(“Vector Quantised-Variational AutoEncoder”;\nvan den Oord, et al. 2017\n) model learns a discrete latent variable by the encoder, since discrete representations may be a more natural fit for problems like language, speech, reasoning, etc.\nVector quantisation (VQ) is a method to map $K$-dimensional vectors into a finite set of “code” vectors. The process is very much similar to\nKNN\nalgorithm. The optimal centroid code vector that a sample should be mapped to is the one with minimum euclidean distance.\nLet $\\mathbf{e} \\in \\mathbb{R}^{K \\times D}, i=1, \\dots, K$ be the latent embedding space (also known as “codebook”) in VQ-VAE, where $K$ is the number of latent variable categories and $D$ is the embedding size. An individual embedding vector is $\\mathbf{e}_i \\in \\mathbb{R}^{D}, i=1, \\dots, K$.\nThe encoder output $E(\\mathbf{x}) = \\mathbf{z}_e$ goes through a nearest-neighbor lookup to match to one of $K$ embedding vectors and then this matched code vector becomes the input for the decoder $D(.)$:\n$$\n\\mathbf{z}_q(\\mathbf{x}) = \\text{Quantize}(E(\\mathbf{x})) = \\mathbf{e}_k \\text{ where } k = \\arg\\min_i \\|E(\\mathbf{x}) - \\mathbf{e}_i \\|_2\n$$\nNote that the discrete latent variables can have different shapes in differnet applications; for example, 1D for speech, 2D for image and 3D for video.\nThe architecture of VQ-VAE (Image source:\nvan den Oord, et al. 2017\n)\nBecause argmin() is non-differentiable on a discrete space, the gradients $\\nabla_z L$ from decoder input $\\mathbf{z}_q$ is copied to the encoder output $\\mathbf{z}_e$. Other than reconstruction loss, VQ-VAE also optimizes:\nVQ loss\n: The L2 error between the embedding space and the encoder outputs.\nCommitment loss\n: A measure to encourage the encoder output to stay close to the embedding space and to prevent it from fluctuating too frequently from one code vector to another.\n$$\nL = \\underbrace{\\|\\mathbf{x} - D(\\mathbf{e}_k)\\|_2^2}_{\\textrm{reconstruction loss}} + \n\\underbrace{\\|\\text{sg}[E(\\mathbf{x})] - \\mathbf{e}_k\\|_2^2}_{\\textrm{VQ loss}} + \n\\underbrace{\\beta \\|E(\\mathbf{x}) - \\text{sg}[\\mathbf{e}_k]\\|_2^2}_{\\textrm{commitment loss}}\n$$\nwhere $\\text{sg}[.]$ is the\nstop_gradient\noperator.\nThe embedding vectors in the codebook is updated through EMA (exponential moving average). Given a code vector $\\mathbf{e}_i$, say we have $n_i$ encoder output vectors, $\\{\\mathbf{z}_{i,j}\\}_{j=1}^{n_i}$, that are quantized to $\\mathbf{e}_i$:\n$$\nN_i^{(t)} = \\gamma N_i^{(t-1)} + (1-\\gamma)n_i^{(t)}\\;\\;\\;\n\\mathbf{m}_i^{(t)} = \\gamma \\mathbf{m}_i^{(t-1)} + (1-\\gamma)\\sum_{j=1}^{n_i^{(t)}}\\mathbf{z}_{i,j}^{(t)}\\;\\;\\;\n\\mathbf{e}_i^{(t)} = \\mathbf{m}_i^{(t)} / N_i^{(t)}\n$$\nwhere $(t)$ refers to batch sequence in time. $N_i$ and $\\mathbf{m}_i$ are accumulated vector count and volume, respectively.\nVQ-VAE-2 (\nAli Razavi, et al. 2019\n) is a two-level hierarchical VQ-VAE combined with self-attention autoregressive model.\nStage 1 is to\ntrain a hierarchical VQ-VAE\n: The design of hierarchical latent variables intends to separate local patterns (i.e., texture) from global information (i.e., object shapes). The training of the larger bottom level codebook is conditioned on the smaller top level code too, so that it does not have to learn everything from scratch.\nStage 2 is to\nlearn a prior over the latent discrete codebook\nso that we sample from it and generate images. In this way, the decoder can receive input vectors sampled from a similar distribution as the one in training. A powerful autoregressive model enhanced with multi-headed self-attention layers is used to capture the prior distribution (like\nPixelSNAIL; Chen et al 2017\n).\nConsidering that VQ-VAE-2 depends on discrete latent variables configured in a simple hierarchical setting, the quality of its generated images are pretty amazing.\nArchitecture of hierarchical VQ-VAE and multi-stage image generation. (Image source:\nAli Razavi, et al. 2019\n)\nThe VQ-VAE-2 algorithm. (Image source:\nAli Razavi, et al. 2019\n)\nTD-VAE\n#\nTD-VAE\n(“Temporal Difference VAE”;\nGregor et al., 2019\n) works with sequential data. It relies on three main ideas, described below.\nState-space model as a Markov Chain model.\n1. State-Space Models\nIn (latent) state-space models, a sequence of unobserved hidden states $\\mathbf{z} = (z_1, \\dots, z_T)$ determine the observation states $\\mathbf{x} = (x_1, \\dots, x_T)$. Each time step in the Markov chain model in Fig. 13 can be trained in a similar manner as in Fig. 6, where the intractable posterior $p(z \\vert x)$ is approximated by a function $q(z \\vert x)$.\n2. Belief State\nAn agent should learn to encode all the past states to reason about the future, named as\nbelief state\n, $b_t = belief(x_1, \\dots, x_t) = belief(b_{t-1}, x_t)$. Given this, the distribution of future states conditioned on the past can be written as $p(x_{t+1}, \\dots, x_T \\vert x_1, \\dots, x_t) \\approx p(x_{t+1}, \\dots, x_T \\vert b_t)$. The hidden states in a recurrent policy are used as the agent’s belief state in TD-VAE. Thus we have $b_t = \\text{RNN}(b_{t-1}, x_t)$.\n3. Jumpy Prediction\nFurther, an agent is expected to imagine distant futures based on all the information gathered so far, suggesting the capability of making jumpy predictions, that is, predicting states several steps further into the future.\nRecall what we have learned from the variance lower bound\nabove\n:\n$$\n\\begin{aligned}\n\\log p(x) \n&\\geq \\log p(x) - D_\\text{KL}(q(z|x)\\|p(z|x)) \\\\\n&= \\mathbb{E}_{z\\sim q} \\log p(x|z) - D_\\text{KL}(q(z|x)\\|p(z)) \\\\\n&= \\mathbb{E}_{z \\sim q} \\log p(x|z) - \\mathbb{E}_{z \\sim q} \\log \\frac{q(z|x)}{p(z)} \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x|z) -\\log q(z|x) + \\log p(z)] \\\\\n&= \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)] \\\\\n\\log p(x) \n&\\geq \\mathbb{E}_{z \\sim q}[\\log p(x, z) -\\log q(z|x)]\n\\end{aligned}\n$$\nNow let’s model the distribution of the state $x_t$ as a probability function conditioned on all the past states $x_{<t}$ and two latent variables, $z_t$ and $z_{t-1}$, at current time step and one step back:\n$$\n\\log p(x_t|x_{<{t}}) \\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})]\n$$\nContinue expanding the equation:\n$$\n\\begin{aligned}\n& \\log p(x_t|x_{<{t}}) \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t, z_{t-1}, z_{t}|x_{<{t}}) -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|\\color{red}{z_{t-1}}, z_{t}, \\color{red}{x_{<{t}}}) + \\color{blue}{\\log p(z_{t-1}, z_{t}|x_{<{t}})} -\\log q(z_{t-1}, z_t|x_{\\leq t})] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\color{blue}{\\log p(z_{t-1}|x_{<{t}})} + \\color{blue}{\\log p(z_{t}|z_{t-1})} - \\color{green}{\\log q(z_{t-1}, z_t|x_{\\leq t})}] \\\\\n&\\geq \\mathbb{E}_{(z_{t-1}, z_t) \\sim q}[\\log p(x_t|z_{t}) + \\log p(z_{t-1}|x_{<{t}}) + \\log p(z_{t}|z_{t-1}) - \\color{green}{\\log q(z_t|x_{\\leq t})} - \\color{green}{\\log q(z_{t-1}|z_t, x_{\\leq t})}]\n\\end{aligned}\n$$\nNotice two things:\nThe\nred\nterms can be ignored according to Markov assumptions.\nThe\nblue\nterm is expanded according to Markov assumptions.\nThe\ngreen\nterm is expanded to include an one-step prediction back to the past as a smoothing distribution.\nPrecisely, there are four types of distributions to learn:\n$p_D(.)$ is the\ndecoder\ndistribution:\n$p(x_t \\mid z_t)$ is the encoder by the common definition;\n$p(x_t \\mid z_t) \\to p_D(x_t \\mid z_t)$;\n$p_T(.)$ is the\ntransition\ndistribution:\n$p(z_t \\mid z_{t-1})$ captures the sequential dependency between latent variables;\n$p(z_t \\mid z_{t-1}) \\to p_T(z_t \\mid z_{t-1})$;\n$p_B(.)$ is the\nbelief\ndistribution:\nBoth $p(z_{t-1} \\mid x_{<t})$ and $q(z_t \\mid x_{\\leq t})$ can use the belief states to predict the latent variables;\n$p(z_{t-1} \\mid x_{<t}) \\to p_B(z_{t-1} \\mid b_{t-1})$;\n$q(z_{t} \\mid x_{\\leq t}) \\to p_B(z_t \\mid b_t)$;\n$p_S(.)$ is the\nsmoothing\ndistribution:\nThe back-to-past smoothing term $q(z_{t-1} \\mid z_t, x_{\\leq t})$ can be rewritten to be dependent of belief states too;\n$q(z_{t-1} \\mid z_t, x_{\\leq t}) \\to  p_S(z_{t-1} \\mid z_t, b_{t-1}, b_t)$;\nTo incorporate the idea of jumpy prediction, the sequential ELBO has to not only work on $t, t+1$, but also two distant timestamp $t_1 < t_2$. Here is the final TD-VAE objective function to maximize:\n$$\nJ_{t_1, t_2} = \\mathbb{E}[\n  \\log p_D(x_{t_2}|z_{t_2}) \n  + \\log p_B(z_{t_1}|b_{t_1}) \n  + \\log p_T(z_{t_2}|z_{t_1}) \n  - \\log p_B(z_{t_2}|b_{t_2}) \n  - \\log p_S(z_{t_1}|z_{t_2}, b_{t_1}, b_{t_2})]\n$$\nA detailed overview of TD-VAE architecture, very nicely done. (Image source:\nTD-VAE paper\n)\nCited as:\n@article{weng2018VAE,\n  title   = \"From Autoencoder to Beta-VAE\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-08-12-vae/\"\n}\nReferences\n#\n[1] Geoffrey E. Hinton, and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nScience 313.5786 (2006): 504-507.\n[2] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[3] Pascal Vincent, et al.\n“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”\n. Journal of machine learning research 11.Dec (2010): 3371-3408.\n[4] Geoffrey E. Hinton, Nitish Srivastava, Alex Krizhevsky, Ilya Sutskever, and Ruslan R. Salakhutdinov. “Improving neural networks by preventing co-adaptation of feature detectors.” arXiv preprint arXiv:1207.0580 (2012).\n[5]\nSparse Autoencoder\nby Andrew Ng.\n[6] Alireza Makhzani, Brendan Frey (2013).\n“k-sparse autoencoder”\n. ICLR 2014.\n[7] Salah Rifai, et al.\n“Contractive auto-encoders: Explicit invariance during feature extraction.”\nICML, 2011.\n[8] Diederik P. Kingma, and Max Welling.\n“Auto-encoding variational bayes.”\nICLR 2014.\n[9]\nTutorial - What is a variational autoencoder?\non jaan.io\n[10] Youtube tutorial:\nVariational Autoencoders\nby Arxiv Insights\n[11]\n“A Beginner’s Guide to Variational Methods: Mean-Field Approximation”\nby Eric Jang.\n[12] Carl Doersch.\n“Tutorial on variational autoencoders.”\narXiv:1606.05908, 2016.\n[13] Irina Higgins, et al.\n\"$\\beta$-VAE: Learning basic visual concepts with a constrained variational framework.\"\nICLR 2017.\n[14] Christopher P. Burgess, et al.\n“Understanding disentangling in beta-VAE.”\nNIPS 2017.\n[15] Aaron van den Oord, et al.\n“Neural Discrete Representation Learning”\nNIPS 2017.\n[16] Ali Razavi, et al.\n“Generating Diverse High-Fidelity Images with VQ-VAE-2”\n. arXiv preprint arXiv:1906.00446 (2019).\n[17] Xi Chen, et al.\n“PixelSNAIL: An Improved Autoregressive Generative Model.”\narXiv preprint arXiv:1712.09763 (2017).\n[18] Karol Gregor, et al.\n“Temporal Difference Variational Auto-Encoder.”\nICLR 2019.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:30Z",
            "title": "From Autoencoder to Beta-VAE | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/cd59f7ee3fdb/code/body-000.txt",
                "chars": 217,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "bytes": 2880250,
                "reused": true,
                "local_path": "papers/repair/d99773f380c6f82310b0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.5663",
                "bytes": 706768,
                "reused": true,
                "local_path": "papers/repair/e1b2d4f9537bfbb215c7.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "bytes": 267801,
                "reused": true,
                "local_path": "papers/repair/6d5b1a69e0c9e22de627.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6114",
                "bytes": 3926758,
                "reused": true,
                "local_path": "papers/repair/24a95827202f9fab26f8.pdf"
              },
              {
                "status": "http_404",
                "url": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "retried_at": "2026-10-20T17:54:22Z"
              },
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "bytes": 259807,
                "reused": true,
                "local_path": "papers/repair/ae05bcdf53e441d54399.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599.pdf",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/ed1564965a62d0f95223.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "bytes": 3122746,
                "reused": true,
                "local_path": "papers/repair/dff42138c902f52546e6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00446",
                "bytes": 6893777,
                "reused": true,
                "local_path": "papers/repair/68bf92a125a336073fe6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.09763",
                "bytes": 1060212,
                "reused": true,
                "local_path": "papers/repair/19837883f1a7b093c101.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03107",
                "bytes": 1744116,
                "reused": true,
                "local_path": "papers/repair/7421e1d74410b7ee80f1.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "retried_at": "2026-10-20T17:54:23Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": true,
                "local_path": "papers/repair/ba774392059407ff35bb.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "bytes": 1392544,
                "reused": true,
                "local_path": "papers/repair/13ac6bde4ea85d886602.pdf"
              },
              {
                "status": "ok",
                "url": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "bytes": 596707,
                "reused": true,
                "local_path": "papers/repair/7c5b86e9a0f9c9cfd6a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.05908",
                "bytes": 880152,
                "reused": true,
                "local_path": "papers/repair/673de34731baf973c156.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.03599",
                "bytes": 1758455,
                "reused": true,
                "local_path": "papers/repair/cecf133ac21e33fa774b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00937",
                "bytes": 3174661,
                "reused": true,
                "local_path": "papers/repair/6daef1429a7c6c36146a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33692,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_404",
            "raw_html": "attachments/cd59f7ee3fdb/pages/source.html",
            "local_html": "attachments/cd59f7ee3fdb/pages/article.html",
            "body_base_path": "attachments/cd59f7ee3fdb/pages/",
            "body_markdown_path": "attachments/cd59f7ee3fdb/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Autoencoder",
                "label": "the 1980s",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.459.3788&rep=rep1&type=pdf",
                "label": "Hinton & Salakhutdinov, 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dimensionality_reduction",
                "label": "dimensionality reduction",
                "type": "a"
              },
              {
                "href": "https://ai.googleblog.com/2016/09/image-compression-with-neural-networks.html",
                "label": "decompression",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf",
                "label": "Hinton, et al. 2012",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/neural-networks-1/",
                "label": "activation functions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.5663",
                "label": "Makhzani and Frey, 2013",
                "type": "a"
              },
              {
                "href": "http://www.icml-2011.org/papers/455_icmlpaper.pdf",
                "label": "Rifai, et al, 2011",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1312.6114",
                "label": "Kingma & Welling, 2014",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback-Leibler divergence",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2016/08/variational-bayes.html",
                "label": "post",
                "type": "a"
              },
              {
                "href": "http://dpkingma.com/wordpress/wp-content/uploads/2015/12/talk_nips_workshop_2015.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=Sy2fzU9gl",
                "label": "Higgins et al., 2017",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~ggordon/10725-F12/slides/16-kkt.pdf",
                "label": "KKT condition",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1804.03599.pdf",
                "label": "Burgess, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "information bottleneck theory",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7210-neural-discrete-representation-learning.pdf",
                "label": "van den Oord, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "KNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00446",
                "label": "Ali Razavi, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.09763",
                "label": "PixelSNAIL; Chen et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03107",
                "label": "Gregor et al., 2019",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/c50d/ca78e97e335d362d6b991ae0e1448914e9a3.pdf",
                "label": "“Reducing the dimensionality of data with neural networks.”",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "“Extracting and composing robust features with denoising autoencoders.”",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume11/vincent10a/vincent10a.pdf",
                "label": "“Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion.”",
                "type": "a"
              },
              {
                "href": "https://web.stanford.edu/class/cs294a/sparseAutoencoder.pdf",
                "label": "Sparse Autoencoder",
                "type": "a"
              },
              {
                "href": "https://jaan.io/what-is-variational-autoencoder-vae-tutorial/",
                "label": "Tutorial - What is a variational autoencoder?",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=9zKuYvjFFS8",
                "label": "Variational Autoencoders",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.05908",
                "label": "“Tutorial on variational autoencoders.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.03599",
                "label": "“Understanding disentangling in beta-VAE.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00937",
                "label": "“Neural Discrete Representation Learning”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
          "status": "partial",
          "article_id": "878201399682",
          "local_path": "series-follow/1601/repair/9bc8cee33939058ef446.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
              "bytes": 141343,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bb6875cd3e5549abbcd1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
              "bytes": 200906,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f63f468d5b6f609fb860.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
              "bytes": 320117,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b9e6a98b0df645854fba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
              "bytes": 393303,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d993cb03136583a0420d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
              "bytes": 299867,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/fc09fee591b88b9de59b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
              "bytes": 234229,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/87d8182dba34df99768a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
              "bytes": 153051,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/39271025b647a9d7c525.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
              "bytes": 969820,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/aaa694c2f42a8a7392e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
              "bytes": 281128,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/09d9fe883beab7d0f798.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
              "bytes": 263467,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/61258136fa6d92c338e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
              "bytes": 343247,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c5d63d539267ebf9a663.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
              "bytes": 131443,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4b9f5c7d78f642b4b125.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
              "bytes": 255209,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1feaf95f38447214362b.png"
            }
          ],
          "article": {
            "id": "878201399682",
            "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "bytes": 141343,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-bb6875cd3e5549abbcd1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/EA-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "bytes": 200906,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-f63f468d5b6f609fb860.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-step-size-path.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "bytes": 320117,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-b9e6a98b0df645854fba.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "bytes": 393303,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-d993cb03136583a0420d.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "bytes": 299867,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-fc09fee591b88b9de59b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CMA-ES-coordinates.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "bytes": 234229,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-87d8182dba34df99768a.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "bytes": 153051,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-39271025b647a9d7c525.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/OpenAI-ES-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "bytes": 969820,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-aaa694c2f42a8a7392e9.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/NS-ES-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "bytes": 281128,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-09d9fe883beab7d0f798.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/CEM-RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "bytes": 263467,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-61258136fa6d92c338e1.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "bytes": 343247,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-c5d63d539267ebf9a663.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/PBT-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "bytes": 131443,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-4b9f5c7d78f642b4b125.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "bytes": 255209,
                "reused": true,
                "local_path": "attachments/878201399682/images/body-1feaf95f38447214362b.png",
                "src": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/WANN-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Stochastic gradient descent is a universal choice for optimizing deep learning models. However, it is not the only option. With black-box optimization algorithms, you can evaluate a target function $f(x): \\mathbb{R}^n \\to \\mathbb{R}$, even when you don’t know the precise analytic form of $f(x)$ and thus cannot compute gradients or the Hessian matrix. Examples of black-box optimization methods include\nSimulated Annealing\n,\nHill Climbing\nand\nNelder-Mead method\n.\nEvolution Strategies (ES)\nis one type of black-box optimization algorithms, born in the family of\nEvolutionary Algorithms (EA)\n. In this post, I would dive into a couple of classic ES methods and introduce a few applications of how ES can play a role in deep reinforcement learning.\nWhat are Evolution Strategies?\n#\nEvolution strategies (ES) belong to the big family of evolutionary algorithms. The optimization targets of ES are vectors of real numbers, $x \\in \\mathbb{R}^n$.\nEvolutionary algorithms refer to a division of population-based optimization algorithms inspired by\nnatural selection\n. Natural selection believes that individuals with traits beneficial to their survival can live through generations and pass down the good characteristics to the next generation. Evolution happens by the selection process gradually and the population grows better adapted to the environment.\nHow natural selection works. (Image source: Khan Academy:\nDarwin, evolution, & natural selection\n)\nEvolutionary algorithms can be summarized in the following\nformat\nas a general optimization solution:\nLet’s say we want to optimize a function $f(x)$ and we are not able to compute gradients directly. But we still can evaluate $f(x)$ given any $x$ and the result is deterministic. Our belief in the probability distribution over $x$ as a good solution to $f(x)$ optimization is $p_\\theta(x)$, parameterized by $\\theta$. The goal is to find an optimal configuration of $\\theta$.\nHere given a fixed format of distribution (i.e. Gaussian), the parameter $\\theta$ carries  the knowledge about the best solutions and is being iteratively updated across generations.\nStarting with an initial value of $\\theta$, we can continuously update $\\theta$ by looping three steps as follows:\nGenerate a population of samples $D = \\{(x_i, f(x_i)\\}$ where $x_i \\sim p_\\theta(x)$.\nEvaluate the “fitness” of samples in $D$.\nSelect the best subset of individuals and use them to update $\\theta$, generally based on fitness or rank.\nIn\nGenetic Algorithms (GA)\n, another popular subcategory of EA, $x$ is a sequence of binary codes, $x \\in \\{0, 1\\}^n$. While in ES, $x$ is just a vector of real numbers, $x \\in \\mathbb{R}^n$.\nSimple Gaussian Evolution Strategies\n#\nThis\nis the most basic and canonical version of evolution strategies. It models $p_\\theta(x)$ as a $n$-dimensional isotropic Gaussian distribution, in which $\\theta$ only tracks the mean $\\mu$ and standard deviation $\\sigma$.\n$$\n\\theta = (\\mu, \\sigma),\\;p_\\theta(x) \\sim \\mathcal{N}(\\mathbf{\\mu}, \\sigma^2 I) = \\mu + \\sigma \\mathcal{N}(0, I)\n$$\nThe process of Simple-Gaussian-ES, given $x \\in \\mathcal{R}^n$:\nInitialize $\\theta = \\theta^{(0)}$ and the generation counter $t=0$\nGenerate the offspring population of size $\\Lambda$ by sampling from the Gaussian distribution:\n$D^{(t+1)}=\\{ x^{(t+1)}_i \\mid x^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{ where } y^{(t+1)}_i \\sim \\mathcal{N}(x \\vert 0, \\mathbf{I}),;i = 1, \\dots, \\Lambda\\}$\n.\nSelect a top subset of $\\lambda$ samples with optimal $f(x_i)$ and this subset is called\nelite\nset. Without loss of generality, we may consider the first $k$ samples in $D^{(t+1)}$ to belong to the elite group — Let’s label them as\n$$\n  D^{(t+1)}\\_\\text{elite} = \\\\{x^{(t+1)}\\_i \\mid x^{(t+1)}\\_i \\in D^{(t+1)}, i=1,\\dots, \\lambda, \\lambda\\leq \\Lambda\\\\}\n  $$\nThen we estimate the new mean and std for the next generation using the elite set:\n$$\n  \\begin{aligned}\n  \\mu^{(t+1)} &= \\text{avg}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda x_i^{(t+1)} \\\\\n  {\\sigma^{(t+1)}}^2 &= \\text{var}(D^{(t+1)}_\\text{elite}) = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} -\\mu^{(t)})^2\n  \\end{aligned}\n  $$\nRepeat steps (2)-(4) until the result is good enough ✌️\nCovariance Matrix Adaptation Evolution Strategies (CMA-ES)\n#\nThe standard deviation $\\sigma$ accounts for the level of exploration: the larger $\\sigma$ the bigger search space we can sample our offspring population. In\nvanilla ES\n, $\\sigma^{(t+1)}$ is highly correlated with $\\sigma^{(t)}$, so the algorithm is not able to rapidly adjust the exploration space when needed (i.e. when the confidence level changes).\nCMA-ES\n, short for\n“Covariance Matrix Adaptation Evolution Strategy”\n, fixes the problem by tracking pairwise dependencies between the samples in the distribution with a covariance matrix $C$. The new distribution parameter becomes:\n$$\n\\theta = (\\mu, \\sigma, C),\\; p_\\theta(x) \\sim \\mathcal{N}(\\mu, \\sigma^2 C) \\sim \\mu + \\sigma \\mathcal{N}(0, C)\n$$\nwhere $\\sigma$ controls for the overall scale of the distribution,  often known as\nstep size\n.\nBefore we dig into how the parameters are updated in CMA-ES, it is better to review how the covariance matrix works in the multivariate Gaussian distribution first. As a real symmetric matrix, the covariance matrix $C$ has the following nice features (See\nproof\n&\nproof\n):\nIt is always diagonalizable.\nAlways positive semi-definite.\nAll of its eigenvalues are real non-negative numbers.\nAll of its eigenvectors are orthogonal.\nThere is an orthonormal basis of $\\mathbb{R}^n$ consisting of its eigenvectors.\nLet the matrix $C$ have an\northonormal\nbasis of eigenvectors $B = [b_1, \\dots, b_n]$, with corresponding eigenvalues $\\lambda_1^2, \\dots, \\lambda_n^2$. Let $D=\\text{diag}(\\lambda_1, \\dots, \\lambda_n)$.\n$$\nC = B^\\top D^2 B\n= \\begin{bmatrix} \n\\mid & \\mid &  & \\mid \\\\\nb_1 & b_2 & \\dots & b_n\\\\\n\\mid & \\mid &  & \\mid \\\\\n\\end{bmatrix}\n\\begin{bmatrix}\n\\lambda_1^2 & 0 & \\dots & 0 \\\\\n0 & \\lambda_2^2 & \\dots & 0 \\\\\n\\vdots & \\dots & \\ddots & \\vdots \\\\\n0 & \\dots & 0 & \\lambda_n^2\n\\end{bmatrix}\n\\begin{bmatrix} \n- & b_1 & - \\\\\n- & b_2 & - \\\\\n  & \\dots & \\\\\n- & b_n & - \\\\\n\\end{bmatrix}\n$$\nThe square root of $C$ is:\n$$\nC^{\\frac{1}{2}} = B^\\top D B\n$$\nSymbol\nMeaning\n$x_i^{(t)} \\in \\mathbb{R}^n$\nthe $i$-th samples at the generation (t)\n$y_i^{(t)} \\in \\mathbb{R}^n$\n$x_i^{(t)} = \\mu^{(t-1)} + \\sigma^{(t-1)} y_i^{(t)} $\n$\\mu^{(t)}$\nmean of the generation (t)\n$\\sigma^{(t)}$\nstep size\n$C^{(t)}$\ncovariance matrix\n$B^{(t)}$\na matrix of $C$’s eigenvectors as row vectors\n$D^{(t)}$\na diagonal matrix with $C$’s eigenvalues on the diagnose.\n$p_\\sigma^{(t)}$\nevaluation path for $\\sigma$ at the generation (t)\n$p_c^{(t)}$\nevaluation path for $C$ at the generation (t)\n$\\alpha_\\mu$\nlearning rate for $\\mu$’s update\n$\\alpha_\\sigma$\nlearning rate for $p_\\sigma$\n$d_\\sigma$\ndamping factor for $\\sigma$’s update\n$\\alpha_{cp}$\nlearning rate for $p_c$\n$\\alpha_{c\\lambda}$\nlearning rate for $C$’s rank-min(λ, n) update\n$\\alpha_{c1}$\nlearning rate for $C$’s rank-1 update\nUpdating the Mean\n#\n$$\n\\mu^{(t+1)} = \\mu^{(t)} + \\alpha_\\mu \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})\n$$\nCMA-ES has a learning rate $\\alpha_\\mu \\leq 1$ to control how fast the mean $\\mu$ should be updated.  Usually it is set to 1 and thus the equation becomes the same as in vanilla ES, $\\mu^{(t+1)} = \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda (x_i^{(t+1)}$.\nControlling the Step Size\n#\nThe sampling process can be decoupled from the mean and standard deviation:\n$$\nx^{(t+1)}_i = \\mu^{(t)} + \\sigma^{(t)} y^{(t+1)}_i \\text{, where } y^{(t+1)}_i = \\frac{x_i^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)\n$$\nThe parameter $\\sigma$ controls the overall scale of the distribution. It is separated from the covariance matrix so that we can change steps faster than the full covariance. A larger step size leads to faster parameter update. In order to evaluate whether the current step size is proper, CMA-ES constructs an\nevolution path\n$p_\\sigma$ by summing up a consecutive sequence of moving steps, $\\frac{1}{\\lambda}\\sum_{i}^\\lambda y_i^{(j)}, j=1, \\dots, t$. By comparing this path length with its expected length under random selection (meaning single steps are uncorrelated), we are able to adjust $\\sigma$ accordingly (See Fig. 2).\nThree scenarios of how single steps are correlated in different ways and their impacts on step size update. (Image source: additional annotations on Fig 5 in\nCMA-ES tutorial\npaper)\nEach time the evolution path is updated with the average of moving step $y_i$ in the same generation.\n$$\n\\begin{aligned}\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n= \\frac{1}{\\lambda} \\frac{\\sum_{i=1}^\\lambda x_i^{(t+1)} - \\lambda \\mu^{(t)}}{\\sigma^{(t)}}\n= \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&\\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y_i^{(t+1)} \n\\sim \\frac{1}{\\lambda}\\mathcal{N}(0, \\lambda C^{(t)}) \n\\sim \\frac{1}{\\sqrt{\\lambda}}{C^{(t)}}^{\\frac{1}{2}}\\mathcal{N}(0, I) \\\\\n&\\text{Thus } \\sqrt{\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nBy multiplying with $C^{-\\frac{1}{2}}$, the evolution path is transformed to be independent of its direction. The term ${C^{(t)}}^{-\\frac{1}{2}} = {B^{(t)}}^\\top {D^{(t)}}^{-\\frac{1}{2}} {B^{(t)}}$ transformation works as follows:\n${B^{(t)}}$ contains row vectors of $C$’s eigenvectors. It projects the original space onto the perpendicular principal axes.\nThen ${D^{(t)}}^{-\\frac{1}{2}} = \\text{diag}(\\frac{1}{\\lambda_1}, \\dots, \\frac{1}{\\lambda_n})$ scales the length of principal axes to be equal.\n${B^{(t)}}^\\top$ transforms the space back to the original coordinate system.\nIn order to assign higher weights to recent generations, we use polyak averaging to update the evolution path with learning rate $\\alpha_\\sigma$. Meanwhile, the weights are balanced so that $p_\\sigma$ is\nconjugate\n, $\\sim \\mathcal{N}(0, I)$ both before and after one update.\n$$\n\\begin{aligned}\np_\\sigma^{(t+1)} \n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{1 - (1 - \\alpha_\\sigma)^2}\\;\\sqrt{\\lambda}\\; {C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n& = (1 - \\alpha_\\sigma) p_\\sigma^{(t)} + \\sqrt{c_\\sigma (2 - \\alpha_\\sigma)\\lambda}\\;{C^{(t)}}^{-\\frac{1}{2}} \\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThe expected length of $p_\\sigma$ under random selection is $\\mathbb{E}|\\mathcal{N}(0,I)|$, that is the expectation of the L2-norm of a $\\mathcal{N}(0,I)$ random variable. Following the idea in Fig. 2, we adjust the step size according to the ratio of $|p_\\sigma^{(t+1)}| / \\mathbb{E}|\\mathcal{N}(0,I)|$:\n$$\n\\begin{aligned}\n\\ln\\sigma^{(t+1)} &= \\ln\\sigma^{(t)} + \\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big) \\\\\n\\sigma^{(t+1)} &= \\sigma^{(t)} \\exp\\Big(\\frac{\\alpha_\\sigma}{d_\\sigma} \\Big(\\frac{\\|p_\\sigma^{(t+1)}\\|}{\\mathbb{E}\\|\\mathcal{N}(0,I)\\|} - 1\\Big)\\Big)\n\\end{aligned}\n$$\nwhere $d_\\sigma \\approx 1$ is a damping parameter, scaling how fast $\\ln\\sigma$ should be changed.\nAdapting the Covariance Matrix\n#\nFor the covariance matrix, it can be estimated from scratch using $y_i$ of elite samples (recall that $y_i \\sim \\mathcal{N}(0, C)$):\n$$\nC_\\lambda^{(t+1)} \n= \\frac{1}{\\lambda}\\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n= \\frac{1}{\\lambda {\\sigma^{(t)}}^2} \\sum_{i=1}^\\lambda (x_i^{(t+1)} - \\mu^{(t)})(x_i^{(t+1)} - \\mu^{(t)})^\\top\n$$\nThe above estimation is only reliable when the selected population is large enough. However, we do want to run\nfast\niteration with a\nsmall\npopulation of samples in each generation. That’s why CMA-ES invented a more reliable but also more complicated way to update $C$. It involves two independent routes,\nRank-min(λ, n) update\n: uses the history of $\\{C_\\lambda\\}$, each estimated from scratch in one generation.\nRank-one update\n: estimates the moving steps $y_i$ and the sign information from the history.\nThe first route considers the estimation of $C$ from the entire history of $\\{C_\\lambda\\}$. For example, if we have experienced a large number of generations, $C^{(t+1)} \\approx \\text{avg}(C_\\lambda^{(i)}; i=1,\\dots,t)$ would be a good estimator. Similar to $p_\\sigma$, we also use polyak averaging with a learning rate to incorporate the history:\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} C_\\lambda^{(t+1)}\n= (1 - \\alpha_{c\\lambda}) C^{(t)} + \\alpha_{c\\lambda} \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top\n$$\nA common choice for the learning rate is $\\alpha_{c\\lambda} \\approx \\min(1, \\lambda/n^2)$.\nThe second route tries to solve the issue that $y_i{y_i}^\\top = (-y_i)(-y_i)^\\top$ loses the sign information. Similar to how we adjust the step size $\\sigma$, an evolution path $p_c$ is used to track the sign information and it is constructed in a way that $p_c$ is conjugate, $\\sim \\mathcal{N}(0, C)$ both before and after a new generation.\nWe may consider $p_c$ as another way to compute $\\text{avg}_i(y_i)$ (notice that both $\\sim \\mathcal{N}(0, C)$) while the entire history is used and the sign information is maintained. Note that we’ve known $\\sqrt{k}\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\sim \\mathcal{N}(0, C)$ in the\nlast section\n,\n$$\n\\begin{aligned}\np_c^{(t+1)} \n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{1 - (1-\\alpha_{cp})^2}\\;\\sqrt{\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}} \\\\\n&= (1-\\alpha_{cp}) p_c^{(t)} + \\sqrt{\\alpha_{cp}(2 - \\alpha_{cp})\\lambda}\\;\\frac{\\mu^{(t+1)} - \\mu^{(t)}}{\\sigma^{(t)}}\n\\end{aligned}\n$$\nThen the covariance matrix is updated according to $p_c$:\n$$\nC^{(t+1)} = (1-\\alpha_{c1}) C^{(t)} + \\alpha_{c1}\\;p_c^{(t+1)} {p_c^{(t+1)}}^\\top\n$$\nThe\nrank-one update\napproach is claimed to generate a significant improvement over the\nrank-min(λ, n)-update\nwhen $k$ is small, because the signs of moving steps and correlations between consecutive steps are all utilized and passed down through generations.\nEventually we combine two approaches together,\n$$\nC^{(t+1)} \n= (1 - \\alpha_{c\\lambda} - \\alpha_{c1}) C^{(t)}\n+ \\alpha_{c1}\\;\\underbrace{p_c^{(t+1)} {p_c^{(t+1)}}^\\top}_\\textrm{rank-one update}\n+ \\alpha_{c\\lambda} \\underbrace{\\frac{1}{\\lambda} \\sum_{i=1}^\\lambda y^{(t+1)}_i {y^{(t+1)}_i}^\\top}_\\textrm{rank-min(lambda, n) update}\n$$\nIn all my examples above, each elite sample is considered to contribute an equal amount of weights, $1/\\lambda$. The process can be easily extended to the case where selected samples are assigned with different weights, $w_1, \\dots, w_\\lambda$, according to their performances. See more detail in\ntutorial\n.\nIllustration of how CMA-ES works on a 2D optimization problem (the lighter color the better). Black dots are samples in one generation. The samples are more spread out initially but when the model has higher confidence in finding a good solution in the late stage, the samples become very concentrated over the global optimum. (Image source:\nWikipedia CMA-ES\n)\nNatural Evolution Strategies\n#\nNatural Evolution Strategies (\nNES\n;\nWierstra, et al, 2008\n) optimizes in a search distribution of parameters and moves the distribution in the direction of high fitness indicated by the\nnatural gradient\n.\nNatural Gradients\n#\nGiven an objective function $\\mathcal{J}(\\theta)$ parameterized by $\\theta$, let’s say our goal is to find the optimal $\\theta$ to maximize the objective function value. A\nplain gradient\nfinds the steepest direction within a small Euclidean distance from the current $\\theta$; the distance restriction is applied on the parameter space. In other words, we compute the plain gradient with respect to a small change of the absolute value of $\\theta$. The optimal step is:\n$$\nd^{*} = \\operatorname*{argmax}_{\\|d\\| = \\epsilon} \\mathcal{J}(\\theta + d)\\text{, where }\\epsilon \\to 0\n$$\nDifferently,\nnatural gradient\nworks with a probability\ndistribution\nspace\nparameterized by $\\theta$, $p_\\theta(x)$ (referred to as “search distribution” in NES\npaper\n). It looks for the steepest direction within a small step in the distribution space where the distance is measured by KL divergence. With this constraint we ensure that each update is moving along the distributional manifold with constant speed, without being slowed down by its curvature.\n$$\nd^{*}_\\text{N} = \\operatorname*{argmax}_{\\text{KL}[p_\\theta \\| p_{\\theta+d}] = \\epsilon} \\mathcal{J}(\\theta + d)\n$$\nEstimation using Fisher Information Matrix\n#\nBut, how to compute $\\text{KL}[p_\\theta | p_{\\theta+\\Delta\\theta}]$ precisely? By running Taylor expansion of $\\log p_{\\theta + d}$ at $\\theta$, we get:\n$$\n\\begin{aligned}\n& \\text{KL}[p_\\theta \\| p_{\\theta+d}] \\\\\n&= \\mathbb{E}_{x \\sim p_\\theta} [\\log p_\\theta(x) - \\log p_{\\theta+d}(x)] & \\\\\n&\\approx \\mathbb{E}_{x \\sim p_\\theta} [ \\log p_\\theta(x) -( \\log p_{\\theta}(x) + \\nabla_\\theta \\log p_{\\theta}(x) d + \\frac{1}{2}d^\\top \\nabla^2_\\theta \\log p_{\\theta}(x) d)] & \\scriptstyle{\\text{; Taylor expand }\\log p_{\\theta+d}} \\\\\n&\\approx - \\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}(x)] d - \\frac{1}{2}d^\\top \\mathbb{E}_x [\\nabla^2_\\theta \\log p_{\\theta}(x)] d & \n\\end{aligned}\n$$\nwhere\n$$\n\\begin{aligned}\n\\mathbb{E}_x [\\nabla_\\theta \\log p_{\\theta}] d \n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) & \\\\\n&= \\int_{x\\sim p_\\theta} p_\\theta(x) \\frac{1}{p_\\theta(x)} \\nabla_\\theta p_\\theta(x) & \\\\\n&= \\nabla_\\theta \\Big( \\int_{x} p_\\theta(x) \\Big) & \\scriptstyle{\\textrm{; note that }p_\\theta(x)\\textrm{ is probability distribution.}} \\\\\n&= \\nabla_\\theta (1) = 0\n\\end{aligned}\n$$\nFinally we have,\n$$\n\\text{KL}[p_\\theta \\| p_{\\theta+d}] = - \\frac{1}{2}d^\\top \\mathbf{F}_\\theta d \n\\text{, where }\\mathbf{F}_\\theta = \\mathbb{E}_x [(\\nabla_\\theta \\log p_{\\theta}) (\\nabla_\\theta \\log p_{\\theta})^\\top]\n$$\nwhere $\\mathbf{F}_\\theta$ is called the\nFisher Information Matrix\nand\nit is\nthe covariance matrix of $\\nabla_\\theta \\log p_\\theta$ since $\\mathbb{E}[\\nabla_\\theta \\log p_\\theta] = 0$.\nThe solution to the following optimization problem:\n$$\n\\max \\mathcal{J}(\\theta + d) \\approx \\max \\big( \\mathcal{J}(\\theta) + {\\nabla_\\theta\\mathcal{J}(\\theta)}^\\top d \\big)\\;\\text{ s.t. }\\text{KL}[p_\\theta \\| p_{\\theta+d}] - \\epsilon = 0\n$$\ncan be found using a Lagrangian multiplier,\n$$\n\\begin{aligned}\n\\mathcal{L}(\\theta, d, \\beta) &= \\mathcal{J}(\\theta) + \\nabla_\\theta\\mathcal{J}(\\theta)^\\top d - \\beta (\\frac{1}{2}d^\\top \\mathbf{F}_\\theta d + \\epsilon) = 0 \\text{ s.t. } \\beta > 0 \\\\\n\\nabla_d \\mathcal{L}(\\theta, d, \\beta) &= \\nabla_\\theta\\mathcal{J}(\\theta) - \\beta\\mathbf{F}_\\theta d = 0 \\\\\n\\text{Thus } d_\\text{N}^* &= \\nabla_\\theta^\\text{N} \\mathcal{J}(\\theta) = \\mathbf{F}_\\theta^{-1} \\nabla_\\theta\\mathcal{J}(\\theta) \n\\end{aligned}\n$$\nwhere $d_\\text{N}^*$ only extracts the direction of the optimal moving step on $\\theta$, ignoring the scalar $\\beta^{-1}$.\nThe natural gradient samples (black solid arrows) in the right are the plain gradient samples (black solid arrows)  in the left multiplied by the inverse of their covariance. In this way, a gradient direction with high uncertainty (indicated by high covariance with other samples) are penalized with a small weight. The aggregated natural gradient (red dash arrow) is therefore more trustworthy than the natural gradient (green solid arrow). (Image source: additional annotations on Fig 2 in\nNES\npaper)\nNES Algorithm\n#\nThe fitness associated with one sample is labeled as $f(x)$ and the search distribution over $x$ is parameterized by $\\theta$. NES is expected to optimize the parameter $\\theta$ to achieve maximum expected fitness:\n$$\n\\mathcal{J}(\\theta) = \\mathbb{E}_{x\\sim p_\\theta(x)} [f(x)] = \\int_x f(x) p_\\theta(x) dx\n$$\nUsing the same log-likelihood\ntrick\nin\nREINFORCE\n:\n$$\n\\begin{aligned}\n\\nabla_\\theta\\mathcal{J}(\\theta) \n&= \\nabla_\\theta \\int_x f(x) p_\\theta(x) dx \\\\\n&= \\int_x f(x) \\frac{p_\\theta(x)}{p_\\theta(x)}\\nabla_\\theta p_\\theta(x) dx \\\\\n& = \\int_x f(x) p_\\theta(x) \\nabla_\\theta \\log p_\\theta(x) dx \\\\\n& = \\mathbb{E}_{x \\sim p_\\theta} [f(x) \\nabla_\\theta \\log p_\\theta(x)]\n\\end{aligned}\n$$\nBesides natural gradients, NES adopts a couple of important heuristics to make the algorithm performance more robust.\nNES applies\nrank-based fitness shaping\n, that is to use the\nrank\nunder monotonically increasing fitness values instead of using $f(x)$ directly. Or it can be a function of the rank (“utility function”), which is considered as a free parameter of NES.\nNES adopts\nadaptation sampling\nto adjust hyperparameters at run time. When changing $\\theta \\to \\theta’$, samples drawn from $p_\\theta$ are compared with samples from $p_{\\theta’}$ using [Mann-Whitney U-test(https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test)]; if there shows a positive or negative sign, the target hyperparameter decreases or increases by a multiplication constant. Note the score of a sample $x’_i \\sim p_{\\theta’}(x)$ has importance sampling weights applied $w_i’ = p_\\theta(x) / p_{\\theta’}(x)$.\nApplications: ES in Deep Reinforcement Learning\n#\nOpenAI ES for RL\n#\nThe concept of using evolutionary algorithms in reinforcement learning can be traced back\nlong ago\n, but only constrained to tabular RL due to computational limitations.\nInspired by\nNES\n, researchers at OpenAI (\nSalimans, et al. 2017\n) proposed to use NES as a gradient-free black-box optimizer to find optimal policy parameters $\\theta$ that maximizes the return function $F(\\theta)$. The key is to add Gaussian noise $\\epsilon$ on the model parameter $\\theta$ and then use the log-likelihood trick to write it as the gradient of the Gaussian pdf. Eventually only the noise term is left as a weighting scalar for measured performance.\nLet’s say the current parameter value is $\\hat{\\theta}$ (the added hat is to distinguish the value from the random variable $\\theta$). The search distribution of $\\theta$ is designed to be an isotropic multivariate Gaussian with a mean $\\hat{\\theta}$ and a fixed covariance matrix $\\sigma^2 I$,\n$$\n\\theta \\sim \\mathcal{N}(\\hat{\\theta}, \\sigma^2 I) \\text{ equivalent to } \\theta = \\hat{\\theta} + \\sigma\\epsilon, \\epsilon \\sim \\mathcal{N}(0, I)\n$$\nThe gradient for $\\theta$ update is:\n$$\n\\begin{aligned}\n& \\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} F(\\theta) \\\\\n&= \\nabla_\\theta \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} F(\\hat{\\theta} + \\sigma\\epsilon) \\\\\n&= \\nabla_\\theta \\int_{\\epsilon} p(\\epsilon) F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; Gaussian }p(\\epsilon)=(2\\pi)^{-\\frac{n}{2}} \\exp(-\\frac{1}{2}\\epsilon^\\top\\epsilon)} \\\\\n&= \\int_{\\epsilon} p(\\epsilon) \\nabla_\\epsilon \\log p(\\epsilon) \\nabla_\\theta \\epsilon\\;F(\\hat{\\theta} + \\sigma\\epsilon) d\\epsilon & \\scriptstyle{\\text{; log-likelihood trick}}\\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\nabla_\\epsilon \\big(-\\frac{1}{2}\\epsilon^\\top\\epsilon\\big) \\nabla_\\theta \\big(\\frac{\\theta - \\hat{\\theta}}{\\sigma}\\big) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ (-\\epsilon) (\\frac{1}{\\sigma}) F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\\\\n&= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon F(\\hat{\\theta} + \\sigma\\epsilon) ] & \\scriptstyle{\\text{; negative sign can be absorbed.}}\n\\end{aligned}\n$$\nIn one generation, we can sample many $epsilon_i, i=1,\\dots,n$ and evaluate the fitness\nin parallel\n. One beautiful design is that no large model parameter needs to be shared. By only communicating the random seeds between workers, it is enough for the master node to do parameter update. This approach is later extended to adaptively learn a loss function; see my previous post on\nEvolved Policy Gradient\n.\nThe algorithm for training a RL policy using evolution strategies. (Image source:\nES-for-RL\npaper)\nTo make the performance more robust, OpenAI ES adopts virtual batch normalization (BN with mini-batch used for calculating statistics fixed), mirror sampling (sampling a pair of $(-\\epsilon, \\epsilon)$ for evaluation), and\nfitness shaping\n.\nExploration with ES\n#\nExploration (\nvs exploitation\n) is an important topic in RL. The optimization direction in the ES algorithm\nabove\nis only extracted from the cumulative return $F(\\theta)$. Without explicit exploration, the agent might get trapped in a local optimum.\nNovelty-Search ES (\nNS-ES\n;\nConti et al, 2018\n) encourages exploration by updating the parameter in the direction to maximize the\nnovelty\nscore. The novelty score depends on a domain-specific behavior characterization function $b(\\pi_\\theta)$. The choice of $b(\\pi_\\theta)$ is specific to the task and seems to be a bit arbitrary; for example, in the Humanoid locomotion task in the paper, $b(\\pi_\\theta)$ is the final $(x,y)$ location of the agent.\nEvery policy’s $b(\\pi_\\theta)$ is pushed to an archive set $\\mathcal{A}$.\nNovelty of a policy $\\pi_\\theta$ is measured as the k-nearest neighbor score between $b(\\pi_\\theta)$ and all other entries in $\\mathcal{A}$.\n(The use case of the archive set sounds quite similar to\nepisodic memory\n.)\n$$\nN(\\theta, \\mathcal{A}) = \\frac{1}{\\lambda} \\sum_{i=1}^\\lambda \\| b(\\pi_\\theta), b^\\text{knn}_i \\|_2\n\\text{, where }b^\\text{knn}_i \\in \\text{kNN}(b(\\pi_\\theta), \\mathcal{A})\n$$\nThe ES optimization step relies on the novelty score instead of fitness:\n$$\n\\nabla_\\theta \\mathbb{E}_{\\theta\\sim\\mathcal{N}(\\hat{\\theta}, \\sigma^2 I)} N(\\theta, \\mathcal{A})\n= \\frac{1}{\\sigma}\\mathbb{E}_{\\epsilon\\sim\\mathcal{N}(0, I)} [ \\epsilon N(\\hat{\\theta} + \\sigma\\epsilon, \\mathcal{A}) ]\n$$\nNS-ES maintains a group of $M$ independently trained agents (“meta-population”), $\\mathcal{M} = \\{\\theta_1, \\dots, \\theta_M \\}$ and picks one to advance proportional to the novelty score. Eventually we select the best policy. This process is equivalent to ensembling; also see the same idea in\nSVPG\n.\n$$\n\\begin{aligned}\nm &\\leftarrow \\text{pick } i=1,\\dots,M\\text{ according to probability}\\frac{N(\\theta_i, \\mathcal{A})}{\\sum_{j=1}^M N(\\theta_j, \\mathcal{A})} \\\\\n\\theta_m^{(t+1)} &\\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) \\text{ where }\\epsilon_i \\sim \\mathcal{N}(0, I)\n\\end{aligned}\n$$\nwhere $N$ is the number of Gaussian perturbation noise vectors and $\\alpha$ is the learning rate.\nNS-ES completely discards the reward function and only optimizes for novelty to avoid deceptive local optima. To incorporate the fitness back into the formula, another two variations are proposed.\nNSR-ES\n:\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\frac{N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + F(\\theta^{(t)}_m + \\epsilon_i)}{2}\n$$\nNSRAdapt-ES (NSRA-ES)\n: the adaptive weighting parameter $w = 1.0$ initially. We start decreasing $w$ if performance stays flat for a number of generations. Then when the performance starts to increase, we stop decreasing $w$ but increase it instead. In this way, fitness is preferred when the performance stops growing but novelty is preferred otherwise.\n$$\n\\theta_m^{(t+1)} \\leftarrow \\theta_m^{(t)} + \\alpha \\frac{1}{\\sigma}\\sum_{i=1}^N \\epsilon_i \\big((1-w) N(\\theta^{(t)}_m + \\epsilon_i, \\mathcal{A}) + w F(\\theta^{(t)}_m + \\epsilon_i)\\big)\n$$\n(Left) The environment is Humanoid locomotion with a three-sided wall which plays a role as a deceptive trap to create local optimum. (Right) Experiments compare ES baseline and other variations that encourage exploration. (Image source:\nNS-ES\npaper)\nCEM-RL\n#\nArchitectures of the (a) CEM-RL and (b)\nERL\nalgorithms (Image source:\nCEM-RL\npaper)\nThe CEM-RL method (\nPourchot & Sigaud, 2019\n) combines Cross Entropy Method (CEM) with either\nDDPG\nor\nTD3\n. CEM here works pretty much the same as the simple Gaussian ES described\nabove\nand therefore the same function can be replaced using CMA-ES. CEM-RL is built on the framework of\nEvolutionary Reinforcement Learning\n(\nERL\n;\nKhadka & Tumer, 2018\n) in which the standard EA algorithm selects and evolves a population of actors and the rollout experience generated in the process is then added into reply buffer for training both RL-actor and RL-critic networks.\nWorkflow:\nThe mean actor of the CEM population is $\\pi_\\mu$ is initialized with a random actor network.\nThe critic network $Q$ is initialized too, which will be updated by DDPG/TD3.\nRepeat until happy:\na. Sample a population of actors $\\sim \\mathcal{N}(\\pi_\\mu, \\Sigma)$.\nb. Half of the population is evaluated. Their fitness scores are used as the cumulative reward $R$ and added into replay buffer.\nc. The other half are updated together with the critic.\nd. The new $\\pi_mu$ and $\\Sigma$ is computed using top performing elite samples.\nCMA-ES\ncan be used for parameter update too.\nExtension: EA in Deep Learning\n#\n(This section is not on evolution strategies, but still an interesting and relevant reading.)\nThe\nEvolutionary Algorithms\nhave been applied on many deep learning problems. POET (\nWang et al, 2019\n) is a framework based on EA and attempts to generate a variety of different tasks while the problems themselves are being solved. POET has been introduced in my\nlast post\non meta-RL. Evolutionary Reinforcement Learning (ERL) is another example; See Fig. 7 (b).\nBelow I would like to introduce two applications in more detail,\nPopulation-Based Training (PBT)\nand\nWeight-Agnostic Neural Networks (WANN)\n.\nHyperparameter Tuning: PBT\n#\nParadigms of comparing different ways of hyperparameter tuning. (Image source:\nPBT\npaper)\nPopulation-Based Training (\nJaderberg, et al, 2017\n), short for\nPBT\napplies EA on the problem of hyperparameter tuning. It jointly trains a population of models and corresponding hyperparameters for optimal performance.\nPBT starts with a set of random candidates, each containing a pair of model weights initialization and hyperparameters, $\\{(\\theta_i, h_i)\\mid i=1, \\dots, N\\}$. Every sample is trained in parallel and asynchronously evaluates its own performance periodically. Whenever a member deems ready (i.e. after taking enough gradient update steps, or when the performance is good enough), it has a chance to be updated by comparing with the whole population:\nexploit()\n: When this model is under-performing, the weights could be replaced with a better performing model.\nexplore()\n: If the model weights are overwritten,\nexplore\nstep perturbs the hyperparameters with random noise.\nIn this process, only promising model and hyperparameter pairs can survive and keep on evolving, achieving better utilization of computational resources.\nThe algorithm of population-based training. (Image source:\nPBT\npaper)\nNetwork Topology Optimization: WANN\n#\nWeight Agnostic Neural\nNetworks (short for\nWANN\n;\nGaier & Ha 2019\n) experiments with searching for the smallest network topologies that can achieve the optimal performance without training the network weights. By not considering the best configuration of network weights, WANN puts much more emphasis on the architecture itself, making the focus different from\nNAS\n. WANN is heavily inspired by a classic genetic algorithm to evolve network topologies, called\nNEAT\n(“Neuroevolution of Augmenting Topologies”;\nStanley & Miikkulainen 2002\n).\nThe workflow of WANN looks pretty much the same as standard GA:\nInitialize: Create a population of minimal networks.\nEvaluation: Test with a range of\nshared\nweight values.\nRank and Selection: Rank by performance and complexity.\nMutation: Create new population by varying best networks.\nmutation operations for searching for new network topologies in WANN (Image source:\nWANN\npaper)\nAt the “evaluation” stage, all the network weights are set to be the same. In this way, WANN is actually searching for network that can be described with a minimal description length. In the “selection” stage, both the network connection and the model performance are considered.\nPerformance of WANN found network topologies on different RL tasks are compared with baseline FF networks commonly used in the literature. \"Tuned Shared Weight\" only requires adjusting one weight value. (Image source:\nWANN\npaper)\nAs shown in Fig. 11, WANN results are evaluated with both random weights and shared weights (single weight). It is interesting that even when enforcing weight-sharing on all weights and tuning this single parameter, WANN can discover topologies that achieve non-trivial good performance.\nCited as:\n@article{weng2019ES,\n  title   = \"Evolution Strategies\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/\"\n}\nReferences\n#\n[1] Nikolaus Hansen.\n“The CMA Evolution Strategy: A Tutorial”\narXiv preprint arXiv:1604.00772 (2016).\n[2] Marc Toussaint.\nSlides: “Introduction to Optimization”\n[3] David Ha.\n“A Visual Guide to Evolution Strategies”\nblog.otoro.net. Oct 2017.\n[4] Daan Wierstra, et al.\n“Natural evolution strategies.”\nIEEE World Congress on Computational Intelligence, 2008.\n[5] Agustinus Kristiadi.\n“Natural Gradient Descent”\nMar 2018.\n[6] Razvan Pascanu & Yoshua Bengio.\n“Revisiting Natural Gradient for Deep Networks.”\narXiv preprint arXiv:1301.3584 (2013).\n[7] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[8] Edoardo Conti, et al.\n“Improving exploration in evolution strategies for deep reinforcement learning via a population of novelty-seeking agents.”\nNIPS. 2018.\n[9] Aloïs Pourchot & Olivier Sigaud.\n“CEM-RL: Combining evolutionary and gradient-based methods for policy search.”\nICLR 2019.\n[10] Shauharda Khadka & Kagan Tumer.\n“Evolution-guided policy gradient in reinforcement learning.”\nNIPS 2018.\n[11] Max Jaderberg, et al.\n“Population based training of neural networks.”\narXiv preprint arXiv:1711.09846 (2017).\n[12] Adam Gaier & David Ha.\n“Weight Agnostic Neural Networks.”\narXiv preprint arXiv:1906.04358 (2019).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:55Z",
            "title": "Evolution Strategies | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/878201399682/code/body-000.txt",
                "chars": 225,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "retried_at": "2026-10-20T17:50:44Z"
              },
              {
                "status": "ok",
                "url": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "bytes": 88049,
                "reused": true,
                "local_path": "papers/repair/917cd856fd35314537c1.pdf"
              },
              {
                "status": "download_error",
                "url": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='control.ucsd.edu', port=80): Max retries exceeded with url: /mauricio/courses/mae280a/lecture11.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='co",
                "retried_at": "2026-10-20T22:24:26Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.00772",
                "bytes": 857878,
                "reused": true,
                "local_path": "papers/repair/71af15dab8222eb475d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.4487",
                "bytes": 1171979,
                "reused": true,
                "local_path": "papers/repair/37f18f0d7acadb4282f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3584v7",
                "bytes": 685629,
                "reused": true,
                "local_path": "papers/repair/bdf05dc4032d4acb3572.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1106.0221",
                "bytes": 331057,
                "reused": true,
                "local_path": "papers/repair/4e0bbca4680770f0c883.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.06560",
                "bytes": 4261567,
                "reused": true,
                "local_path": "papers/repair/129e1e6853a3d4d7a64a.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "bytes": 921414,
                "reused": true,
                "local_path": "papers/repair/c7818bfa100e7982cf3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.01222",
                "bytes": 2570801,
                "reused": true,
                "local_path": "papers/repair/17fc5b1b00f236706451.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.04358",
                "bytes": 2337427,
                "reused": true,
                "local_path": "papers/repair/8b93d140fe096a835c1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "bytes": 6284388,
                "reused": true,
                "local_path": "papers/repair/338cf06e2122caa8db06.pdf"
              },
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "bytes": 334309,
                "reused": true,
                "local_path": "papers/repair/4b425dc99075992bc98a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 33765,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/878201399682/pages/source.html",
            "local_html": "attachments/878201399682/pages/article.html",
            "body_base_path": "attachments/878201399682/pages/",
            "body_markdown_path": "attachments/878201399682/pages/article.md",
            "links": [
              {
                "href": "https://en.wikipedia.org/wiki/Simulated_annealing",
                "label": "Simulated Annealing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hill_climbing",
                "label": "Hill Climbing",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method",
                "label": "Nelder-Mead method",
                "type": "a"
              },
              {
                "href": "https://www.khanacademy.org/science/biology/her/evolution-and-natural-selection/a/darwin-evolution-natural-selection",
                "label": "Darwin, evolution, & natural selection",
                "type": "a"
              },
              {
                "href": "https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/06-blackBoxOpt.pdf",
                "label": "format",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "This",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "http://s3.amazonaws.com/mitsloan-php/wp-faculty/sites/30/2016/12/15032137/Symmetric-Matrices-and-Eigendecomposition.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "http://control.ucsd.edu/mauricio/courses/mae280a/lecture11.pdf",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.00772",
                "label": "CMA-ES tutorial",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Conjugate_prior",
                "label": "conjugate",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.4487",
                "label": "Wierstra, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1301.3584v7",
                "label": "distribution",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/14/natural-gradient/",
                "label": "space",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/FisherInformationMatrix.html",
                "label": "Fisher Information Matrix",
                "type": "a"
              },
              {
                "href": "https://wiseodd.github.io/techblog/2018/03/11/fisher-information/",
                "label": "it is",
                "type": "a"
              },
              {
                "href": "http://blog.shakirm.com/2015/11/machine-learning-trick-of-the-day-5-log-derivative-trick/",
                "label": "trick",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1106.0221",
                "label": "long ago",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "Evolved Policy Gradient",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "vs exploitation",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/TBA",
                "label": "above",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.06560",
                "label": "Conti et al, 2018",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7395-evolution-guided-policy-gradient-in-reinforcement-learning.pdf",
                "label": "ERL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.01222",
                "label": "CEM-RL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "PBT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.04358",
                "label": "Gaier & Ha 2019",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers/Zoph_Learning_Transferable_Architectures_CVPR_2018_paper.pdf",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.gecco02_1.pdf",
                "label": "Stanley & Miikkulainen 2002",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
          "status": "partial",
          "article_id": "a8dc6bf17c71",
          "local_path": "series-follow/1601/repair/3d08c3e2cf07a50c284b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
              "bytes": 1548239,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/23d602a28b9d9dda6fe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
              "bytes": 665187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/11419d5ec12fba3fb7f9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
              "bytes": 730525,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/34f37f1d8bf391fe9f42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
              "bytes": 808103,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/851555a6cfa04864e872.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
              "bytes": 184486,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1195100b0c6841a237dd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
              "bytes": 194344,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c47eeb17ebb22f866942.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
              "bytes": 273207,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9ae2425c1e62b530a443.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
              "bytes": 174582,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cb826c25071414ad89e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
              "bytes": 405772,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0167fe1ca07386abf1d2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
              "bytes": 1245251,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ae1778af670dfaca75e8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
              "bytes": 397702,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9baa7ed8723c2cae889a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
              "bytes": 102014,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f1b0701dad5bcf83ef5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
              "bytes": 195622,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7f2ae4aa3936d2a466d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
              "bytes": 286187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d947284bd0373951e25d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
              "bytes": 124913,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/830017a377b95ff33b98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
              "bytes": 1295521,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d0137fe96ca3220fcf1f.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Meta-Learning: Learning to Learn Fast",
            "keywords": "元学习,小样本,MAML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "publish_date": "2018-11",
            "corpus_stage": "预训练/SFT",
            "notes": "元学习综述",
            "id": "a8dc6bf17c71",
            "collected_at": "2026-10-02T14:13:37",
            "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
            "body_markdown": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in\nChinese\n!]\nA good machine learning model often requires training with a large number of samples. Humans, in contrast, learn new concepts and skills much faster and more efficiently. Kids who have seen cats and birds only a few times can quickly tell them apart. People who know how to ride a bike are likely to discover the way to ride a motorcycle fast with little or even no demonstration. Is it possible to design a machine learning model with similar properties — learning new concepts and skills fast with a few training examples? That’s essentially what\nmeta-learning\naims to solve.\nWe expect a good meta-learning model capable of well adapting or generalizing to new tasks and new environments that have never been encountered during training time. The adaptation process, essentially a mini learning session, happens during test but with a limited exposure to the new task configurations. Eventually, the adapted model can complete new tasks. This is why meta-learning is also known as\nlearning to learn\n.\nThe tasks can be any well-defined family of machine learning problems: supervised learning, reinforcement learning, etc. For example, here are a couple concrete meta-learning tasks:\nA classifier trained on non-cat images can tell whether a given image contains a cat after seeing a handful of cat pictures.\nA game bot is able to quickly master a new game.\nA mini robot completes the desired task on an uphill surface during test even through it was only trained in a flat surface environment.\nDefine the Meta-Learning Problem\n#\nIn this post, we focus on the case when each desired task is a supervised learning problem like image classification. There is a lot of interesting literature on meta-learning with reinforcement learning problems (aka “Meta Reinforcement Learning”), but we would not cover them here.\nA Simple View\n#\nA good meta-learning model should be trained over a variety of learning tasks and optimized for the best performance on a distribution of tasks, including potentially unseen tasks. Each task is associated with a dataset $\\mathcal{D}$, containing both feature vectors and true labels. The optimal model parameters are:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\mathcal{D}\\sim p(\\mathcal{D})} [\\mathcal{L}_\\theta(\\mathcal{D})]\n$$\nIt looks very similar to a normal learning task, but\none dataset\nis considered as\none data sample\n.\nFew-shot classification\nis an instantiation of meta-learning in the field of supervised learning. The dataset $\\mathcal{D}$ is often split into two parts, a support set $S$ for learning and a prediction set $B$ for training or testing, $\\mathcal{D}=\\langle S, B\\rangle$. Often we consider a\nK-shot N-class classification\ntask: the support set contains K labelled examples for each of N classes.\nAn example of 4-shot 2-class image classification. (Image thumbnails are from\nPinterest\n)\nTraining in the Same Way as Testing\n#\nA dataset $\\mathcal{D}$ contains pairs of feature vectors and labels, $\\mathcal{D} = \\{(\\mathbf{x}_i, y_i)\\}$ and each label belongs to a known label set $\\mathcal{L}^\\text{label}$.  Let’s say, our classifier $f_\\theta$ with parameter $\\theta$ outputs a probability of a data point belonging to the class $y$ given the feature vector $\\mathbf{x}$, $P_\\theta(y\\vert\\mathbf{x})$.\nThe optimal parameters should maximize the probability of true labels across multiple training batches $B \\subset \\mathcal{D}$:\n$$\n\\begin{aligned}\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{(\\mathbf{x}, y)\\in \\mathcal{D}}[P_\\theta(y \\vert \\mathbf{x})] &\\\\\n\\theta^* &= {\\arg\\max}_{\\theta} \\mathbb{E}_{B\\subset \\mathcal{D}}[\\sum_{(\\mathbf{x}, y)\\in B}P_\\theta(y \\vert \\mathbf{x})] & \\scriptstyle{\\text{; trained with mini-batches.}}\n\\end{aligned}\n$$\nIn few-shot classification, the goal is to reduce the prediction error on data samples with unknown labels given a small support set for “fast learning” (think of how “fine-tuning” works). To make the training process mimics what happens during inference, we would like to “fake” datasets with a subset of labels to avoid exposing all the labels to the model and modify the optimization procedure accordingly to encourage fast learning:\nSample a subset of labels, $L\\subset\\mathcal{L}^\\text{label}$.\nSample a support set $S^L \\subset \\mathcal{D}$ and a training batch $B^L \\subset \\mathcal{D}$. Both of them only contain data points with labels belonging to the sampled label set $L$, $y \\in L, \\forall (x, y) \\in S^L, B^L$.\nThe support set is part of the model input.\nThe final optimization uses the mini-batch $B^L$ to compute the loss and update the model parameters through backpropagation, in the same way as how we use it in the supervised learning.\nYou may consider each pair of sampled dataset $(S^L, B^L)$ as one data point. The model is trained such that it can generalize to other datasets.  Symbols in red are added for meta-learning in addition to the supervised learning objective.\n$$\n\\theta = \\arg\\max_\\theta \\color{red}{E_{L\\subset\\mathcal{L}}[} E_{\\color{red}{S^L \\subset\\mathcal{D}, }B^L \\subset\\mathcal{D}} [\\sum_{(x, y)\\in B^L} P_\\theta(x, y\\color{red}{, S^L})] \\color{red}{]}\n$$\nThe idea is to some extent similar to using a pre-trained model in image classification (ImageNet) or language modeling (big text corpora) when only a limited set of task-specific data samples are available. Meta-learning takes this idea one step further, rather than fine-tuning according to one down-steam task, it optimizes the model to be good at many, if not all.\nLearner and Meta-Learner\n#\nAnother popular view of meta-learning decomposes the model update into two stages:\nA classifier $f_\\theta$ is the “learner” model, trained for operating a given task;\nIn the meantime, a optimizer $g_\\phi$ learns how to update the learner model’s parameters via the support set $S$, $\\theta’ = g_\\phi(\\theta, S)$.\nThen in final optimization step, we need to update both $\\theta$ and $\\phi$ to maximize:\n$$\n\\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})]]\n$$\nCommon Approaches\n#\nThere are three common approaches to meta-learning: metric-based, model-based, and optimization-based. Oriol Vinyals has a nice summary in his\ntalk\nat meta-learning symposium @ NIPS 2018:\n| ————- | ————- | ————- | ————- |\nModel-based\nMetric-based\nOptimization-based\nKey idea\nRNN; memory\nMetric learning\nGradient descent\nHow $P_\\theta(y \\vert \\mathbf{x})$ is modeled?\n$f_\\theta(\\mathbf{x}, S)$\n$\\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i$ (*)\n$P_{g_\\phi(\\theta, S^L)}(y \\vert \\mathbf{x})$\n(*) $k_\\theta$ is a kernel function measuring the similarity between $\\mathbf{x}_i$ and $\\mathbf{x}$.\nNext we are gonna review classic models in each approach.\nMetric-Based\n#\nThe core idea in metric-based meta-learning is similar to nearest neighbors algorithms (i.e.,\nk-NN\nclassificer and\nk-means\nclustering) and\nkernel density estimation\n. The predicted probability over a set of known labels $y$ is a weighted sum of labels of support set samples. The weight is generated by a kernel function $k_\\theta$, measuring the similarity between two data samples.\n$$\nP_\\theta(y \\vert \\mathbf{x}, S) = \\sum_{(\\mathbf{x}_i, y_i) \\in S} k_\\theta(\\mathbf{x}, \\mathbf{x}_i)y_i \n$$\nTo learn a good kernel is crucial to the success of a metric-based meta-learning model.\nMetric learning\nis well aligned with this intention, as it aims to learn a metric or distance function over objects. The notion of a good metric is problem-dependent. It should represent the relationship between inputs in the task space and facilitate problem solving.\nAll the models introduced below learn embedding vectors of input data explicitly and use them to design proper kernel functions.\nConvolutional Siamese Neural Network\n#\nThe\nSiamese Neural Network\nis composed of two twin networks and their outputs are jointly trained on top with a function to learn the relationship between pairs of input data samples. The twin networks are identical, sharing the same weights and network parameters. In other words, both refer to the same embedding network that learns an efficient embedding to reveal relationship between pairs of data points.\nKoch, Zemel & Salakhutdinov (2015)\nproposed a method to use the siamese neural network to do one-shot image classification. First, the siamese network is trained for a verification task for telling whether two input images are in the same class. It outputs the probability of two images belonging to the same class. Then, during test time, the siamese network processes all the image pairs between a test image and every image in the support set. The final prediction is the class of the support image with the highest probability.\nThe architecture of convolutional siamese neural network for few-show image classification.\nFirst, convolutional siamese network learns to encode two images into feature vectors via a embedding function $f_\\theta$ which contains a couple of convolutional layers.\nThe L1-distance between two embeddings is $\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert$.\nThe distance is converted to a probability $p$ by a linear feedforward layer and sigmoid. It is the probability of whether two images are drawn from the same class.\nIntuitively the loss is cross entropy because the label is binary.\n$$\n\\begin{aligned}\np(\\mathbf{x}_i, \\mathbf{x}_j) &= \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_i) - f_\\theta(\\mathbf{x}_j) \\vert) \\\\\n\\mathcal{L}(B) &= \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} \\mathbf{1}_{y_i=y_j}\\log p(\\mathbf{x}_i, \\mathbf{x}_j) + (1-\\mathbf{1}_{y_i=y_j})\\log (1-p(\\mathbf{x}_i, \\mathbf{x}_j))\n\\end{aligned}\n$$\nImages in the training batch $B$ can be augmented with distortion. Of course, you can replace the L1 distance with other distance metric, L2, cosine, etc. Just make sure they are differential and then everything else works the same.\nGiven a support set $S$ and a test image $\\mathbf{x}$, the final predicted class is:\n$$\n\\hat{c}_S(\\mathbf{x}) = c(\\arg\\max_{\\mathbf{x}_i \\in S} P(\\mathbf{x}, \\mathbf{x}_i))\n$$\nwhere $c(\\mathbf{x})$ is the class label of an image $\\mathbf{x}$ and $\\hat{c}(.)$ is the predicted label.\nThe assumption is that the learned embedding can be generalized to be useful for measuring the distance between images of unknown categories. This is the same assumption behind transfer learning via the adoption of a pre-trained model; for example, the convolutional features learned in the model pre-trained with ImageNet are expected to help other image tasks. However, the benefit of a pre-trained model decreases when the new task diverges from the original task that the model was trained on.\nMatching Networks\n#\nThe task of\nMatching Networks\n(\nVinyals et al., 2016\n) is to learn a classifier $c_S$ for any given (small) support set $S=\\{x_i, y_i\\}_{i=1}^k$ (\nk-shot\nclassification). This classifier defines a probability distribution over output labels $y$ given a test example $\\mathbf{x}$. Similar to other metric-based models, the classifier output is defined as a sum of labels of support samples weighted by attention kernel $a(\\mathbf{x}, \\mathbf{x}_i)$ - which should be proportional to the similarity between $\\mathbf{x}$ and $\\mathbf{x}_i$.\nThe architecture of Matching Networks. (Image source:\noriginal paper\n)\n$$\nc_S(\\mathbf{x}) = P(y \\vert \\mathbf{x}, S) = \\sum_{i=1}^k a(\\mathbf{x}, \\mathbf{x}_i) y_i\n\\text{, where }S=\\{(\\mathbf{x}_i, y_i)\\}_{i=1}^k\n$$\nThe attention kernel depends on two embedding functions, $f$ and $g$, for encoding the test sample and the support set samples respectively. The attention weight between two data points is the cosine similarity, $\\text{cosine}(.)$, between their embedding vectors, normalized by softmax:\n$$\na(\\mathbf{x}, \\mathbf{x}_i) = \\frac{\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_i))}{\\sum_{j=1}^k\\exp(\\text{cosine}(f(\\mathbf{x}), g(\\mathbf{x}_j))}\n$$\nSimple Embedding\n#\nIn the simple version, an embedding function is a neural network with a single data sample as input. Potentially we can set $f=g$.\nFull Context Embeddings\n#\nThe embedding vectors are critical inputs for building a good classifier. Taking a single data point as input might not be enough to efficiently gauge the entire feature space. Therefore, the Matching Network model further proposed to enhance the embedding functions by taking as input the whole support set $S$ in addition to the original input, so that the learned embedding can be adjusted based on the relationship with other support samples.\n$g_\\theta(\\mathbf{x}_i, S)$ uses a bidirectional LSTM to encode $\\mathbf{x}_i$ in the context of the entire support set $S$.\n$f_\\theta(\\mathbf{x}, S)$ encodes the test sample $\\mathbf{x}$ visa an LSTM with read attention over the support set $S$.\nFirst the test sample goes through a simple neural network, such as a CNN, to extract basic features, $f’(\\mathbf{x})$.\nThen an LSTM is trained with a read attention vector over the support set as part of the hidden state:\n$$\n  \\begin{aligned}\n  \\hat{\\mathbf{h}}_t, \\mathbf{c}_t &= \\text{LSTM}(f'(\\mathbf{x}), [\\mathbf{h}_{t-1}, \\mathbf{r}_{t-1}], \\mathbf{c}_{t-1}) \\\\\n  \\mathbf{h}_t &= \\hat{\\mathbf{h}}_t + f'(\\mathbf{x}) \\\\\n  \\mathbf{r}_{t-1} &= \\sum_{i=1}^k a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) g(\\mathbf{x}_i) \\\\\n  a(\\mathbf{h}_{t-1}, g(\\mathbf{x}_i)) &= \\text{softmax}(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i)) = \\frac{\\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_i))}{\\sum_{j=1}^k \\exp(\\mathbf{h}_{t-1}^\\top g(\\mathbf{x}_j))}\n  \\end{aligned}\n  $$\nEventually $f(\\mathbf{x}, S)=\\mathbf{h}_K$ if we do K steps of “read”.\nThis embedding method is called “Full Contextual Embeddings (FCE)”. Interestingly it does help improve the performance on a hard task (few-shot classification on mini ImageNet), but makes no difference on a simple task (Omniglot).\nThe training process in Matching Networks is designed to match inference at test time, see the details in the earlier\nsection\n. It is worthy of mentioning that the Matching Networks paper refined the idea that training and testing conditions should match.\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{L\\subset\\mathcal{L}}[ \\mathbb{E}_{S^L \\subset\\mathcal{D}, B^L \\subset\\mathcal{D}} [\\sum_{(\\mathbf{x}, y)\\in B^L} P_\\theta(y\\vert\\mathbf{x}, S^L)]]\n$$\nRelation Network\n#\nRelation Network (RN)\n(\nSung et al., 2018\n) is similar to\nsiamese network\nbut with a few differences:\nThe relationship is not captured by a simple L1 distance in the feature space, but predicted by a CNN classifier $g_\\phi$. The relation score between a pair of inputs, $\\mathbf{x}_i$ and $\\mathbf{x}_j$, is $r_{ij} = g_\\phi([\\mathbf{x}_i, \\mathbf{x}_j])$ where $[.,.]$ is concatenation.\nThe objective function is MSE loss instead of cross-entropy, because conceptually RN focuses more on predicting relation scores which is more like regression, rather than binary classification, $\\mathcal{L}(B) = \\sum_{(\\mathbf{x}_i, \\mathbf{x}_j, y_i, y_j)\\in B} (r_{ij} - \\mathbf{1}_{y_i=y_j})^2$.\nRelation Network architecture for a 5-way 1-shot problem with one query example. (Image source:\noriginal paper\n)\n(Note: There is another\nRelation Network\nfor relational reasoning, proposed by DeepMind. Don’t get confused.)\nPrototypical Networks\n#\nPrototypical Networks\n(\nSnell, Swersky & Zemel, 2017\n) use an embedding function $f_\\theta$ to encode each input into a $M$-dimensional feature vector. A\nprototype\nfeature vector is defined for every class $c \\in \\mathcal{C}$, as the mean vector of the embedded support data samples in this class.\n$$\n\\mathbf{v}_c = \\frac{1}{|S_c|} \\sum_{(\\mathbf{x}_i, y_i) \\in S_c} f_\\theta(\\mathbf{x}_i)\n$$\nPrototypical networks in the few-shot and zero-shot scenarios. (Image source:\noriginal paper\n)\nThe distribution over classes for a given test input $\\mathbf{x}$ is a softmax over the inverse of distances between the test data embedding and prototype vectors.\n$$\nP(y=c\\vert\\mathbf{x})=\\text{softmax}(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c)) = \\frac{\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_c))}{\\sum_{c' \\in \\mathcal{C}}\\exp(-d_\\varphi(f_\\theta(\\mathbf{x}), \\mathbf{v}_{c'}))}\n$$\nwhere $d_\\varphi$ can be any distance function as long as $\\varphi$ is differentiable. In the paper, they used the squared euclidean distance.\nThe loss function is the negative log-likelihood: $\\mathcal{L}(\\theta) = -\\log P_\\theta(y=c\\vert\\mathbf{x})$.\nModel-Based\n#\nModel-based meta-learning models make no assumption on the form of $P_\\theta(y\\vert\\mathbf{x})$. Rather it depends on a model designed specifically for fast learning — a model that updates its parameters rapidly with a few training steps. This rapid parameter update can be achieved by its internal architecture or controlled by another meta-learner model.\nMemory-Augmented Neural Networks\n#\nA family of model architectures use external memory storage to facilitate the learning process of neural networks, including\nNeural Turing Machines\nand\nMemory Networks\n. With an explicit storage buffer, it is easier for the network to rapidly incorporate new information and not to forget in the future. Such a model is known as\nMANN\n, short for “\nMemory-Augmented Neural Network\n”.  Note that recurrent neural networks with only\ninternal memory\nsuch as vanilla RNN or LSTM are not MANNs.\nBecause MANN is expected to encode new information fast and thus to adapt to new tasks after only a few samples, it fits well for meta-learning. Taking the Neural Turing Machine (NTM) as the base model,\nSantoro et al. (2016)\nproposed a set of modifications on the training setup and the memory retrieval mechanisms (or “addressing mechanisms”, deciding how to assign attention weights to memory vectors). Please go through\nthe NTM section\nin my other post first if you are not familiar with this matter before reading forward.\nAs a quick recap, NTM couples a controller neural network with external memory storage. The controller learns to read and write memory rows by soft attention, while the memory serves as a knowledge repository. The attention weights are generated by its addressing mechanism: content-based + location based.\nThe architecture of Neural Turing Machine (NTM). The memory at time t, $\\mathbf{M}\\_t$ is a matrix of size $N \\times M$, containing N vector rows and each has M dimensions.\nMANN for Meta-Learning\n#\nTo use MANN for meta-learning tasks, we need to train it in a way that the memory can encode and capture information of new tasks fast and, in the meantime, any stored representation is easily and stably accessible.\nThe training described in\nSantoro et al., 2016\nhappens in an interesting way so that the memory is forced to hold information for longer until the appropriate labels are presented later. In each training episode, the truth label $y_t$ is presented with\none step offset\n, $(\\mathbf{x}_{t+1}, y_t)$: it is the true label for the input at the previous time step t, but presented as part of the input at time step t+1.\nTask setup in MANN for meta-learning (Image source:\noriginal paper\n).\nIn this way, MANN is motivated to memorize the information of a new dataset, because the memory has to hold the current input until the label is present later and then retrieve the old information to make a prediction accordingly.\nNext let us see how the memory is updated for efficient information retrieval and storage.\nAddressing Mechanism for Meta-Learning\n#\nAside from the training process, a new pure content-based addressing mechanism is utilized to make the model better suitable for meta-learning.\n» How to read from memory?\nThe read attention is constructed purely based on the content similarity.\nFirst, a key feature vector $\\mathbf{k}_t$ is produced at the time step t by the controller as a function of the input $\\mathbf{x}$. Similar to NTM, a read weighting vector $\\mathbf{w}_t^r$ of N elements is computed as the cosine similarity between the key vector and every memory vector row, normalized by softmax. The read vector $\\mathbf{r}_t$ is a sum of memory records weighted by such weightings:\n$$\n\\mathbf{r}_i = \\sum_{i=1}^N w_t^r(i)\\mathbf{M}_t(i)\n\\text{, where } w_t^r(i) = \\text{softmax}(\\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})\n$$\nwhere $M_t$ is the memory matrix at time t and $M_t(i)$ is the i-th row in this matrix.\n» How to write into memory?\nThe addressing mechanism for writing newly received information into memory operates a lot like the\ncache replacement\npolicy. The\nLeast Recently Used Access (LRUA)\nwriter is designed for MANN to better work in the scenario of meta-learning. A LRUA write head prefers to write new content to either the\nleast used\nmemory location or the\nmost recently used\nmemory location.\nRarely used locations: so that we can preserve frequently used information (see\nLFU\n);\nThe last used location: the motivation is that once a piece of information is retrieved once, it probably won’t be called again for a while (see\nMRU\n).\nThere are many cache replacement algorithms and each of them could potentially replace the design here with better performance in different use cases. Furthermore, it would be a good idea to learn the memory usage pattern and addressing strategies rather than arbitrarily set it.\nThe preference of LRUA is carried out in a way that everything is differentiable:\nThe usage weight $\\mathbf{w}^u_t$ at time t is a sum of current read and write vectors, in addition to the decayed last usage weight, $\\gamma \\mathbf{w}^u_{t-1}$, where $\\gamma$ is a decay factor.\nThe write vector is an interpolation between the previous read weight (prefer “the last used location”) and the previous least-used weight (prefer “rarely used location”). The interpolation parameter is the sigmoid of a hyperparameter $\\alpha$.\nThe least-used weight $\\mathbf{w}^{lu}$ is scaled according to usage weights $\\mathbf{w}_t^u$, in which any dimension remains at 1 if smaller than the n-th smallest element in the vector and 0 otherwise.\n$$\n\\begin{aligned}\n\\mathbf{w}_t^u &= \\gamma \\mathbf{w}_{t-1}^u + \\mathbf{w}_t^r + \\mathbf{w}_t^w \\\\\n\\mathbf{w}_t^r &= \\text{softmax}(\\text{cosine}(\\mathbf{k}_t, \\mathbf{M}_t(i))) \\\\\n\\mathbf{w}_t^w &= \\sigma(\\alpha)\\mathbf{w}_{t-1}^r + (1-\\sigma(\\alpha))\\mathbf{w}^{lu}_{t-1}\\\\\n\\mathbf{w}_t^{lu} &= \\mathbf{1}_{w_t^u(i) \\leq m(\\mathbf{w}_t^u, n)}\n\\text{, where }m(\\mathbf{w}_t^u, n)\\text{ is the }n\\text{-th smallest element in vector }\\mathbf{w}_t^u\\text{.}\n\\end{aligned}\n$$\nFinally, after the least used memory location, indicated by $\\mathbf{w}_t^{lu}$, is set to zero, every memory row is updated:\n$$\n\\mathbf{M}_t(i) = \\mathbf{M}_{t-1}(i) + w_t^w(i)\\mathbf{k}_t, \\forall i\n$$\nMeta Networks\n#\nMeta Networks\n(\nMunkhdalai & Yu, 2017\n), short for\nMetaNet\n, is a meta-learning model with architecture and training process designed for\nrapid\ngeneralization across tasks.\nFast Weights\n#\nThe rapid generalization of MetaNet relies on “fast weights”. There are a handful of papers on this topic, but I haven’t read all of them in detail and I failed to find a very concrete definition, only a vague agreement on the concept. Normally weights in the neural networks are updated by stochastic gradient descent in an objective function and this process is known to be slow. One faster way to learn is to utilize one neural network to predict the parameters of another neural network and the generated weights are called\nfast weights\n. In comparison, the ordinary SGD-based weights are named\nslow weights\n.\nIn MetaNet, loss gradients are used as\nmeta information\nto populate models that learn fast weights. Slow and fast weights are combined to make predictions in neural networks.\nCombining slow and fast weights in a MLP. $\\bigoplus$ is element-wise sum. (Image source:\noriginal paper\n).\nModel Components\n#\nDisclaimer: Below you will find my annotations are different from those in the paper. imo, the paper is poorly written, but the idea is still interesting. So I’m presenting the idea in my own language.\nKey components of MetaNet are:\nAn embedding function $f_\\theta$, parameterized by $\\theta$, encodes raw inputs into feature vectors. Similar to\nSiamese Neural Network\n, these embeddings are trained to be useful for telling whether two inputs are of the same class (verification task).\nA base learner model $g_\\phi$, parameterized by weights $\\phi$, completes the actual learning task.\nIf we stop here, it looks just like\nRelation Network\n. MetaNet, in addition, explicitly models the fast weights of both functions and then aggregates them back into the model (See Fig. 8).\nTherefore we need additional two functions to output fast weights for $f$ and $g$ respectively.\n$F_w$: a LSTM parameterized by $w$ for learning fast weights $\\theta^+$ of the embedding function $f$. It takes as input gradients of $f$’s embedding loss for verification task.\n$G_v$: a neural network parameterized by $v$ learning fast weights $\\phi^+$ for the base learner $g$ from its loss gradients. In MetaNet, the learner’s loss gradients are viewed as the\nmeta information\nof the task.\nOk, now let’s see how meta networks are trained. The training data contains multiple pairs of datasets: a support set $S=\\{\\mathbf{x}’_i, y’_i\\}_{i=1}^K$ and a test set  $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$. Recall that we have four networks and four sets of model parameters to learn, $(\\theta, \\phi, w, v)$.\nFig.9. The MetaNet architecture.\nTraining Process\n#\nSample a random pair of inputs at each time step t from the support set $S$, $(\\mathbf{x}’_i, y’_i)$ and $(\\mathbf{x}’_j, y_j)$. Let $\\mathbf{x}_{(t,1)}=\\mathbf{x}’_i$ and $\\mathbf{x}_{(t,2)}=\\mathbf{x}’_j$.\nfor $t = 1, \\dots, K$:\na. Compute a loss for representation learning; i.e., cross entropy for the verification task:\n$\\mathcal{L}^\\text{emb}_t = \\mathbf{1}_{y’_i=y’_j} \\log P_t + (1 - \\mathbf{1}_{y’_i=y’_j})\\log(1 - P_t)\\text{, where }P_t = \\sigma(\\mathbf{W}\\vert f_\\theta(\\mathbf{x}_{(t,1)}) - f_\\theta(\\mathbf{x}_{(t,2)})\\vert)$\nCompute the task-level fast weights:\n$\\theta^+ = F_w(\\nabla_\\theta \\mathcal{L}^\\text{emb}_1, \\dots, \\mathcal{L}^\\text{emb}_T)$\nNext go through examples in the support set $S$ and compute the example-level fast weights. Meanwhile, update the memory with learned representations.\nfor $i=1, \\dots, K$:\na. The base learner outputs a probability distribution: $P(\\hat{y}_i \\vert \\mathbf{x}_i) = g_\\phi(\\mathbf{x}_i)$ and the loss can be cross-entropy or MSE: $\\mathcal{L}^\\text{task}_i = y’_i \\log g_\\phi(\\mathbf{x}’_i) + (1- y’_i) \\log (1 - g_\\phi(\\mathbf{x}’_i))$\nb. Extract meta information (loss gradients) of the task and compute the example-level fast weights:\n$\\phi_i^+ = G_v(\\nabla_\\phi\\mathcal{L}^\\text{task}_i)$\nThen store $\\phi^+_i$ into $i$-th location of the “value” memory $\\mathbf{M}$.\nd. Encode the support sample into a task-specific input representation using both slow and fast weights: $r’_i = f_{\\theta, \\theta^+}(\\mathbf{x}’_i)$\nThen store $r’_i$ into $i$-th location of the “key” memory $\\mathbf{R}$.\nFinally it is the time to construct the training loss using the test set $U=\\{\\mathbf{x}_i, y_i\\}_{i=1}^L$.\nStarts with $\\mathcal{L}_\\text{train}=0$:\nfor $j=1, \\dots, L$:\na. Encode the test sample into a task-specific input representation:\n$r_j = f_{\\theta, \\theta^+}(\\mathbf{x}_j)$\nb. The fast weights are computed by attending to representations of support set samples in memory $\\mathbf{R}$. The attention function is of your choice. Here MetaNet uses cosine similarity:\n$$\n \\begin{aligned}\n a_j &= \\text{cosine}(\\mathbf{R}, r_j) = [\\frac{r'_1\\cdot r_j}{\\|r'_1\\|\\cdot\\|r_j\\|}, \\dots, \\frac{r'_N\\cdot r_j}{\\|r'_N\\|\\cdot\\|r_j\\|}]\\\\\n \\phi^+_j &= \\text{softmax}(a_j)^\\top \\mathbf{M}\n \\end{aligned}\n $$\nc. Update the training loss: $\\mathcal{L}_\\text{train} \\leftarrow \\mathcal{L}_\\text{train} + \\mathcal{L}^\\text{task}(g_{\\phi, \\phi^+}(\\mathbf{x}_i), y_i) $\nUpdate all the parameters $(\\theta, \\phi, w, v)$ using $\\mathcal{L}_\\text{train}$.\nOptimization-Based\n#\nDeep learning models learn through backpropagation of gradients. However, the gradient-based optimization is neither designed to cope with a small number of training samples, nor to converge within a small number of optimization steps. Is there a way to adjust the optimization algorithm so that the model can be good at learning with a few examples? This is what optimization-based approach meta-learning algorithms intend for.\nLSTM Meta-Learner\n#\nThe optimization algorithm can be explicitly modeled.\nRavi & Larochelle (2017)\ndid so and named it “meta-learner”, while the original model for handling the task is called “learner”. The goal of the meta-learner is to efficiently update the learner’s parameters using a small support set so that the learner can adapt to the new task quickly.\nLet’s denote the learner model as $M_\\theta$ parameterized by $\\theta$, the meta-learner as $R_\\Theta$ with parameters $\\Theta$, and the loss function $\\mathcal{L}$.\nWhy LSTM?\n#\nThe meta-learner is modeled as a LSTM, because:\nThere is similarity between the gradient-based update in backpropagation and the cell-state update in LSTM.\nKnowing a history of gradients benefits the gradient update; think about how\nmomentum\nworks.\nThe update for the learner’s parameters at time step t with a learning rate $\\alpha_t$ is:\n$$\n\\theta_t = \\theta_{t-1} - \\alpha_t \\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n$$\nIt has the same form as the cell state update in LSTM, if we set forget gate $f_t=1$, input gate $i_t = \\alpha_t$, cell state $c_t = \\theta_t$, and new cell state $\\tilde{c}_t = -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t$:\n$$\n\\begin{aligned}\nc_t &= f_t \\odot c_{t-1} + i_t \\odot \\tilde{c}_t\\\\\n    &= \\theta_{t-1} - \\alpha_t\\nabla_{\\theta_{t-1}}\\mathcal{L}_t\n\\end{aligned}\n$$\nWhile fixing $f_t=1$ and $i_t=\\alpha_t$ might not be the optimal, both of them can be learnable and adaptable to different datasets.\n$$\n\\begin{aligned}\nf_t &= \\sigma(\\mathbf{W}_f \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, f_{t-1}] + \\mathbf{b}_f) & \\scriptstyle{\\text{; how much to forget the old value of parameters.}}\\\\\ni_t &= \\sigma(\\mathbf{W}_i \\cdot [\\nabla_{\\theta_{t-1}}\\mathcal{L}_t, \\mathcal{L}_t, \\theta_{t-1}, i_{t-1}] + \\mathbf{b}_i) & \\scriptstyle{\\text{; corresponding to the learning rate at time step t.}}\\\\\n\\tilde{\\theta}_t &= -\\nabla_{\\theta_{t-1}}\\mathcal{L}_t &\\\\\n\\theta_t &= f_t \\odot \\theta_{t-1} + i_t \\odot \\tilde{\\theta}_t &\\\\\n\\end{aligned}\n$$\nModel Setup\n#\nHow the learner $M\\_\\theta$ and the meta-learner $R\\_\\Theta$ are trained. (Image source:\noriginal paper\nwith more annotations)\nThe training process mimics what happens during test, since it has been proved to be beneficial in\nMatching Networks\n. During each training epoch, we first sample a dataset $\\mathcal{D} = (\\mathcal{D}_\\text{train}, \\mathcal{D}_\\text{test}) \\in \\hat{\\mathcal{D}}_\\text{meta-train}$ and then sample mini-batches out of $\\mathcal{D}_\\text{train}$ to update $\\theta$ for $T$ rounds. The final state of the learner parameter $\\theta_T$ is used to train the meta-learner on the test data $\\mathcal{D}_\\text{test}$.\nTwo implementation details to pay extra attention to:\nHow to compress the parameter space in LSTM meta-learner? As the meta-learner is modeling parameters of another neural network, it would have hundreds of thousands of variables to learn. Following the\nidea\nof sharing parameters across coordinates,\nTo simplify the training process, the meta-learner assumes that the loss $\\mathcal{L}_t$ and the gradient $\\nabla_{\\theta_{t-1}} \\mathcal{L}_t$ are independent.\nMAML\n#\nMAML\n, short for\nModel-Agnostic Meta-Learning\n(\nFinn, et al. 2017\n) is a fairly general optimization algorithm, compatible with any model that learns through gradient descent.\nLet’s say our model is $f_\\theta$ with parameters $\\theta$. Given a task $\\tau_i$ and its associated dataset $(\\mathcal{D}^{(i)}_\\text{train}, \\mathcal{D}^{(i)}_\\text{test})$, we can update the model parameters by one or more gradient descent steps (the following example only contains one step):\n$$\n\\theta'_i = \\theta - \\alpha \\nabla_\\theta\\mathcal{L}^{(0)}_{\\tau_i}(f_\\theta)\n$$\nwhere $\\mathcal{L}^{(0)}$ is the loss computed using the mini data batch with id (0).\nDiagram of MAML. (Image source:\noriginal paper\n)\nWell, the above formula only optimizes for one task. To achieve a good generalization across a variety of tasks, we would like to find the optimal $\\theta^*$ so that the task-specific fine-tuning is more efficient. Now, we sample a new data batch with id (1) for updating the meta-objective. The loss, denoted as $\\mathcal{L}^{(1)}$, depends on the mini batch (1). The superscripts in $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ only indicate different data batches, and they refer to the same loss objective for the same task.\n$$\n\\begin{aligned}\n\\theta^* \n&= \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta'_i}) = \\arg\\min_\\theta \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\\\\n\\theta &\\leftarrow \\theta - \\beta \\nabla_{\\theta} \\sum_{\\tau_i \\sim p(\\tau)} \\mathcal{L}_{\\tau_i}^{(1)} (f_{\\theta - \\alpha\\nabla_\\theta \\mathcal{L}_{\\tau_i}^{(0)}(f_\\theta)}) & \\scriptstyle{\\text{; updating rule}}\n\\end{aligned}\n$$\nThe general form of MAML algorithm. (Image source:\noriginal paper\n)\nFirst-Order MAML\n#\nThe meta-optimization step above relies on second derivatives. To make the computation less expensive, a modified version of MAML omits second derivatives, resulting in a simplified and cheaper implementation, known as\nFirst-Order MAML (FOMAML)\n.\nLet’s consider the case of performing $k$ inner gradient steps, $k\\geq1$. Starting with the initial model parameter $\\theta_\\text{meta}$:\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)\\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_1)\\\\\n&\\dots\\\\\n\\theta_k &= \\theta_{k-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{k-1})\n\\end{aligned}\n$$\nThen in the outer loop, we sample a new data batch for updating the meta-objective.\n$$\n\\begin{aligned}\n\\theta_\\text{meta} &\\leftarrow \\theta_\\text{meta} - \\beta g_\\text{MAML} & \\scriptstyle{\\text{; update for meta-objective}} \\\\[2mm]\n\\text{where } g_\\text{MAML}\n&= \\nabla_{\\theta} \\mathcal{L}^{(1)}(\\theta_k) &\\\\[2mm]\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot (\\nabla_{\\theta_{k-1}} \\theta_k) \\dots (\\nabla_{\\theta_0} \\theta_1) \\cdot (\\nabla_{\\theta} \\theta_0) & \\scriptstyle{\\text{; following the chain rule}} \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\Big( \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} \\theta_i \\Big) \\cdot I &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k \\nabla_{\\theta_{i-1}} (\\theta_{i-1} - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1})) &  \\\\\n&= \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))) &\n\\end{aligned}\n$$\nThe MAML gradient is:\n$$\ng_\\text{MAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k) \\cdot \\prod_{i=1}^k (I - \\alpha \\color{red}{\\nabla_{\\theta_{i-1}}(\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_{i-1}))})\n$$\nThe First-Order MAML ignores the second derivative part in red. It is simplified as follows, equivalent to the derivative of the last inner gradient update result.\n$$\ng_\\text{FOMAML} = \\nabla_{\\theta_k} \\mathcal{L}^{(1)}(\\theta_k)\n$$\nReptile\n#\nReptile\n(\nNichol, Achiam & Schulman, 2018\n) is a remarkably simple meta-learning optimization algorithm. It is similar to MAML in many ways, given that both rely on meta-optimization through gradient descent and both are model-agnostic.\nThe Reptile works by repeatedly:\nsampling a task,\ntraining on it by multiple gradient descent steps,\nand then moving the model weights towards the new parameters.\nSee the algorithm below:\n$\\text{SGD}(\\mathcal{L}_{\\tau_i}, \\theta, k)$ performs stochastic gradient update for k steps on the loss $\\mathcal{L}_{\\tau_i}$ starting with initial parameter $\\theta$ and returns the final parameter vector. The batch version samples multiple tasks instead of one within each iteration. The reptile gradient is defined as $(\\theta - W)/\\alpha$, where $\\alpha$ is the stepsize used by the SGD operation.\nThe batched version of Reptile algorithm. (Image source:\noriginal paper\n)\nAt a glance, the algorithm looks a lot like an ordinary SGD. However, because the task-specific optimization can take more than one step. it eventually makes $\\text{SGD}(\\mathbb{E}\n_\\tau[\\mathcal{L}_{\\tau}], \\theta, k)$ diverge from $\\mathbb{E}_\\tau [\\text{SGD}(\\mathcal{L}_{\\tau}, \\theta, k)]$ when k > 1.\nThe Optimization Assumption\n#\nAssuming that a task $\\tau \\sim p(\\tau)$ has a manifold of optimal network configuration, $\\mathcal{W}_{\\tau}^*$. The model $f_\\theta$ achieves the best performance for task $\\tau$ when $\\theta$ lays on the surface of $\\mathcal{W}_{\\tau}^*$. To find a solution that is good across tasks, we would like to find a parameter close to all the optimal manifolds of all tasks:\n$$\n\\theta^* = \\arg\\min_\\theta \\mathbb{E}_{\\tau \\sim p(\\tau)} [\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_\\tau^*)^2]\n$$\nThe Reptile algorithm updates the parameter alternatively to be closer to the optimal manifolds of different tasks. (Image source:\noriginal paper\n)\nLet’s use the L2 distance as $\\text{dist}(.)$ and the distance between a point $\\theta$ and a set $\\mathcal{W}_\\tau^*$ equals to the distance between $\\theta$ and a point $W_{\\tau}^*(\\theta)$ on the manifold that is closest to $\\theta$:\n$$\n\\text{dist}(\\theta, \\mathcal{W}_{\\tau}^*) = \\text{dist}(\\theta, W_{\\tau}^*(\\theta)) \\text{, where }W_{\\tau}^*(\\theta) = \\arg\\min_{W\\in\\mathcal{W}_{\\tau}^*} \\text{dist}(\\theta, W)\n$$\nThe gradient of the squared euclidean distance is:\n$$\n\\begin{aligned}\n\\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2]\n&= \\nabla_\\theta[\\frac{1}{2}\\text{dist}(\\theta, W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\nabla_\\theta[\\frac{1}{2}(\\theta - W_{\\tau_i}^*(\\theta))^2] & \\\\\n&= \\theta - W_{\\tau_i}^*(\\theta) & \\scriptstyle{\\text{; See notes.}}\n\\end{aligned}\n$$\nNotes: According to the Reptile paper,\n“the gradient of the squared euclidean distance between a point $\\Theta$ and a set $S$ is the vector $2(\\Theta − p)$, where p is the closest point in $S$ to $\\Theta$”\n. Technically the closest point in $S$ is also a function of $\\Theta$, but I’m not sure why the gradient does not need to worry about the derivative of $p$. (Please feel free to leave me a comment or send me an email about this if you have ideas.)\nThus the update rule for one stochastic gradient step is:\n$$\n\\theta = \\theta - \\alpha \\nabla_\\theta[\\frac{1}{2} \\text{dist}(\\theta, \\mathcal{W}_{\\tau_i}^*)^2] = \\theta - \\alpha(\\theta - W_{\\tau_i}^*(\\theta)) = (1-\\alpha)\\theta + \\alpha W_{\\tau_i}^*(\\theta)\n$$\nThe closest point on the optimal task manifold $W_{\\tau_i}^*(\\theta)$ cannot be computed exactly, but Reptile approximates it using $\\text{SGD}(\\mathcal{L}_\\tau, \\theta, k)$.\nReptile vs FOMAML\n#\nTo demonstrate the deeper connection between Reptile and MAML, let’s expand the update formula with an example performing two gradient steps, k=2 in $\\text{SGD}(.)$. Same as defined\nabove\n, $\\mathcal{L}^{(0)}$ and $\\mathcal{L}^{(1)}$ are losses using different mini-batches of data. For ease of reading, we adopt two simplified annotations: $g^{(i)}_j = \\nabla_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$ and $H^{(i)}_j = \\nabla^2_{\\theta} \\mathcal{L}^{(i)}(\\theta_j)$.\n$$\n\\begin{aligned}\n\\theta_0 &= \\theta_\\text{meta}\\\\\n\\theta_1 &= \\theta_0 - \\alpha\\nabla_\\theta\\mathcal{L}^{(0)}(\\theta_0)= \\theta_0 - \\alpha g^{(0)}_0 \\\\\n\\theta_2 &= \\theta_1 - \\alpha\\nabla_\\theta\\mathcal{L}^{(1)}(\\theta_1) = \\theta_0 - \\alpha g^{(0)}_0 - \\alpha g^{(1)}_1\n\\end{aligned}\n$$\nAccording to the\nearly section\n, the gradient of FOMAML is the last inner gradient update result. Therefore, when k=1:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) = g^{(1)}_1 \\\\\ng_\\text{MAML} &= \\nabla_{\\theta_1} \\mathcal{L}^{(1)}(\\theta_1) \\cdot (I - \\alpha\\nabla^2_{\\theta} \\mathcal{L}^{(0)}(\\theta_0)) = g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1\n\\end{aligned}\n$$\nThe Reptile gradient is defined as:\n$$\ng_\\text{Reptile} = (\\theta_0 - \\theta_2) / \\alpha = g^{(0)}_0 + g^{(1)}_1\n$$\nUp to now we have:\nReptile versus FOMAML in one loop of meta-optimization. (Image source:\nslides\non Reptile by Yoonho Lee.)\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 \\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\ng_\\text{Reptile} &= g^{(0)}_0 + g^{(1)}_1\n\\end{aligned}\n$$\nNext let’s try further expand $g^{(1)}_1$ using\nTaylor expansion\n. Recall that Taylor expansion of a function $f(x)$ that is differentiable at a number $a$ is:\n$$\nf(x) = f(a) + \\frac{f'(a)}{1!}(x-a) + \\frac{f''(a)}{2!}(x-a)^2 + \\dots = \\sum_{i=0}^\\infty \\frac{f^{(i)}(a)}{i!}(x-a)^i\n$$\nWe can consider $\\nabla_{\\theta}\\mathcal{L}^{(1)}(.)$ as a function and $\\theta_0$ as a value point. The Taylor expansion of $g_1^{(1)}$ at the value point $\\theta_0$ is:\n$$\n\\begin{aligned}\ng_1^{(1)} &= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_1) \\\\\n&= \\nabla_{\\theta}\\mathcal{L}^{(1)}(\\theta_0) + \\nabla^2_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0) + \\frac{1}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0)(\\theta_1 - \\theta_0)^2 + \\dots & \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + \\frac{\\alpha^2}{2}\\nabla^3_\\theta\\mathcal{L}^{(1)}(\\theta_0) (g_0^{(0)})^2 + \\dots & \\scriptstyle{\\text{; because }\\theta_1-\\theta_0=-\\alpha g_0^{(0)}} \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nPlug in the expanded form of $g_1^{(1)}$ into the MAML gradients with one step inner gradient update:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g^{(1)}_1 = g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g^{(1)}_1 - \\alpha H^{(0)}_0 g^{(1)}_1 \\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2) - \\alpha H^{(0)}_0 (g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2))\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + \\alpha^2 \\alpha H^{(0)}_0 H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\n&= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\n\\end{aligned}\n$$\nThe Reptile gradient becomes:\n$$\n\\begin{aligned}\ng_\\text{Reptile} \n&= g^{(0)}_0 + g^{(1)}_1 \\\\\n&= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nSo far we have the formula of three types of gradients:\n$$\n\\begin{aligned}\ng_\\text{FOMAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\\\\\ng_\\text{MAML} &= g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} - \\alpha H^{(0)}_0 g_0^{(1)} + O(\\alpha^2)\\\\\ng_\\text{Reptile}  &= g^{(0)}_0 + g_0^{(1)} - \\alpha H^{(1)}_0 g_0^{(0)} + O(\\alpha^2)\n\\end{aligned}\n$$\nDuring training, we often average over multiple data batches. In our example, the mini batches (0) and (1) are interchangeable since both are drawn at random. The expectation $\\mathbb{E}_{\\tau,0,1}$ is averaged over two data batches, ids (0) and (1), for task $\\tau$.\nLet,\n$A = \\mathbb{E}_{\\tau,0,1} [g_0^{(0)}] = \\mathbb{E}_{\\tau,0,1} [g_0^{(1)}]$; it is the average gradient of task loss. We expect to improve the model parameter to achieve better task performance by following this direction pointed by $A$.\n$B = \\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [H^{(1)}_0 g_0^{(0)} + H^{(0)}_0 g_0^{(1)}] = \\frac{1}{2}\\mathbb{E}_{\\tau,0,1} [\\nabla_\\theta(g^{(0)}_0 g_0^{(1)})]$; it is the direction (gradient) that increases the inner product of gradients of two different mini batches for the same task. We expect to improve the model parameter to achieve better generalization over different data by following this direction pointed by $B$.\nTo conclude, both MAML and Reptile aim to optimize for the same goal, better task performance (guided by A) and better generalization (guided by B), when the gradient update is approximated by first three leading terms.\n$$\n\\begin{aligned}\n\\mathbb{E}_{\\tau,1,2}[g_\\text{FOMAML}] &= A - \\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{MAML}] &= A - 2\\alpha B + O(\\alpha^2)\\\\\n\\mathbb{E}_{\\tau,1,2}[g_\\text{Reptile}]  &= 2A - \\alpha B + O(\\alpha^2)\n\\end{aligned}\n$$\nIt is not clear to me whether the ignored term $O(\\alpha^2)$ might play a big impact on the parameter learning. But given that FOMAML is able to obtain a similar performance as the full version of MAML, it might be safe to say higher-level derivatives would not be critical during gradient descent update.\nCited as:\n@article{weng2018metalearning,\n  title   = \"Meta-Learning: Learning to Learn Fast\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-11-30-meta-learning/\"\n}\nReference\n#\n[1] Brenden M. Lake, Ruslan Salakhutdinov, and Joshua B. Tenenbaum.\n“Human-level concept learning through probabilistic program induction.”\nScience 350.6266 (2015): 1332-1338.\n[2] Oriol Vinyals’ talk on\n“Model vs Optimization Meta Learning”\n[3] Gregory Koch, Richard Zemel, and Ruslan Salakhutdinov.\n“Siamese neural networks for one-shot image recognition.”\nICML Deep Learning Workshop. 2015.\n[4] Oriol Vinyals, et al.\n“Matching networks for one shot learning.”\nNIPS. 2016.\n[5] Flood Sung, et al.\n“Learning to compare: Relation network for few-shot learning.”\nCVPR. 2018.\n[6] Jake Snell, Kevin Swersky, and Richard Zemel.\n“Prototypical Networks for Few-shot Learning.”\nCVPR. 2018.\n[7] Adam Santoro, et al.\n“Meta-learning with memory-augmented neural networks.”\nICML. 2016.\n[8] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).\n[9] Tsendsuren Munkhdalai and Hong Yu.\n“Meta Networks.”\nICML. 2017.\n[10] Sachin Ravi and Hugo Larochelle.\n“Optimization as a Model for Few-Shot Learning.”\nICLR. 2017.\n[11] Chelsea Finn’s BAIR blog on\n“Learning to Learn”\n.\n[12] Chelsea Finn, Pieter Abbeel, and Sergey Levine.\n“Model-agnostic meta-learning for fast adaptation of deep networks.”\nICML 2017.\n[13] Alex Nichol, Joshua Achiam, John Schulman.\n“On First-Order Meta-Learning Algorithms.”\narXiv preprint arXiv:1803.02999 (2018).\n[14]\nSlides on Reptile\nby Yoonho Lee.",
            "metadata": {
              "title": "Meta-Learning: Learning to Learn Fast | Lil'Log",
              "description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "keywords": "meta-learning, long-read",
              "author": "Lilian Weng",
              "og:title": "Meta-Learning: Learning to Learn Fast",
              "og:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
              "twitter:card": "summary",
              "twitter:title": "Meta-Learning: Learning to Learn Fast",
              "twitter:description": "[Updated on 2019-10-01: thanks to Tianhao, we have this post translated in Chinese!]",
              "article:section": "posts",
              "article:published_time": "2018-11-30T00:00:00+00:00",
              "article:modified_time": "2018-11-30T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/a8dc6bf17c71/code/body-000.txt",
                "chars": 245,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "bytes": 1548239,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-23d602a28b9d9dda6fe1.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/few-shot-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "bytes": 665187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-11419d5ec12fba3fb7f9.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/siamese-conv-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "bytes": 730525,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-34f37f1d8bf391fe9f42.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/matching-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "bytes": 808103,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-851555a6cfa04864e872.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/relation-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "bytes": 184486,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-1195100b0c6841a237dd.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/prototypical-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-c47eeb17ebb22f866942.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "bytes": 273207,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9ae2425c1e62b530a443.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/mann-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "bytes": 174582,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-cb826c25071414ad89e4.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/combine-slow-fast-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "bytes": 405772,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-0167fe1ca07386abf1d2.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/meta-network.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "bytes": 1245251,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-ae1778af670dfaca75e8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/lstm-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "bytes": 397702,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-9baa7ed8723c2cae889a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/train-meta-learner.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "bytes": 102014,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-f1b0701dad5bcf83ef5a.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "bytes": 195622,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-7f2ae4aa3936d2a466d8.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/maml-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "bytes": 286187,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d947284bd0373951e25d.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "bytes": 124913,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-830017a377b95ff33b98.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile-optim.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "bytes": 1295521,
                "reused": false,
                "local_path": "attachments/a8dc6bf17c71/images/body-d0137fe96ca3220fcf1f.png",
                "src": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/reptile_vs_FOMAML.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://wei-tianhao.github.io/blog/2019/09/17/meta-learning.html",
                "label": "Chinese",
                "type": "a"
              },
              {
                "href": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "label": "learning to learn",
                "type": "a"
              },
              {
                "href": "https://www.pinterest.com/",
                "label": "Pinterest",
                "type": "a"
              },
              {
                "href": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "label": "talk",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm",
                "label": "k-NN",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/K-means_clustering",
                "label": "k-means",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_density_estimation",
                "label": "kernel density estimation",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Similarity_learning",
                "label": "Metric learning",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "label": "Siamese Neural Network",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "label": "Koch, Zemel & Salakhutdinov (2015)",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "label": "Sung et al., 2018",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/neural-approach-relational-reasoning/",
                "label": "Relation Network",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "label": "Snell, Swersky & Zemel, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "Neural Turing Machines",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.3916",
                "label": "Memory Networks",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "label": "Santoro et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cache_replacement_policies",
                "label": "cache replacement",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Least_frequently_used",
                "label": "LFU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.00837",
                "label": "Munkhdalai & Yu, 2017",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll",
                "label": "Ravi & Larochelle (2017)",
                "type": "a"
              },
              {
                "href": "http://ruder.io/optimizing-gradient-descent/index.html",
                "label": "momentum",
                "type": "a"
              },
              {
                "href": "https://openreview.net/pdf?id=rJY0-Kcll)",
                "label": "original paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04474",
                "label": "idea",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol, Achiam & Schulman, 2018",
                "type": "a"
              },
              {
                "href": "https://www.slideshare.net/YoonhoLee4/on-firstorder-metalearning-algorithms",
                "label": "slides",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Taylor_series",
                "label": "Taylor expansion",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "“Neural turing machines.”",
                "type": "a"
              },
              {
                "href": "https://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "“Learning to Learn”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:39Z",
            "source_url": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cs.cmu.edu/~rsalakhu/papers/LakeEtAl2015Science.pdf",
                "bytes": 1826353,
                "reused": false,
                "local_path": "papers/repair/da4e56c26698557aa61c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://metalearning-symposium.ml/files/vinyals.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='metalearning-symposium.ml', port=80): Max retries exceeded with url: /files/vinyals.pdf (Caused by NameResolutionError(\"HTTPConnection(host='metalearning-s",
                "retried_at": "2026-10-20T22:24:44Z"
              },
              {
                "status": "http_404",
                "url": "https://papers.nips.cc/paper/769-signature-verification-using-a-siamese-time-delay-neural-network.pdf",
                "retried_at": "2026-10-20T18:04:05Z"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~rsalakhu/papers/oneshot1.pdf",
                "bytes": 766340,
                "reused": false,
                "local_path": "papers/repair/fde088adb2e69f52cd16.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": false,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2018/papers_backup/Sung_Learning_to_Compare_CVPR_2018_paper.pdf",
                "bytes": 798122,
                "reused": false,
                "local_path": "papers/repair/1dce78ce43bce934d7c8.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf",
                "bytes": 536399,
                "reused": false,
                "local_path": "papers/repair/33350b7fc96a8da3fa63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.3916",
                "bytes": 215900,
                "reused": false,
                "local_path": "papers/repair/e6bb14affb9d1f13f660.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v48/santoro16.pdf",
                "bytes": 1648270,
                "reused": false,
                "local_path": "papers/repair/b9ba58828decfbd2ad1e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00837",
                "bytes": 455366,
                "reused": false,
                "local_path": "papers/repair/b15e9ef4f202cbfada2c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04474",
                "bytes": 2702892,
                "reused": false,
                "local_path": "papers/repair/76aa0aeb7717cd2e1f8f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": false,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": true,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46235,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404",
            "raw_html": "attachments/a8dc6bf17c71/pages/source.html",
            "local_html": "attachments/a8dc6bf17c71/pages/article.html",
            "body_base_path": "attachments/a8dc6bf17c71/pages/",
            "body_markdown_path": "attachments/a8dc6bf17c71/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
          "status": "partial",
          "article_id": "b003e8b2488e",
          "local_path": "series-follow/1601/repair/e770cc6a0f63aaa24286.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
              "bytes": 231787,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b57d68f7092bb1833c8c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
              "bytes": 277510,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c910fbb94e9497077e67.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
              "bytes": 70545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/28c7d5f3966b58d0995d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
              "bytes": 146618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3d90f7e1924950ee061d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
              "bytes": 737321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3c5ddbb346561ac954f4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
              "bytes": 291684,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d4e8da7e08714c6e544e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
              "bytes": 109328,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c514078611120f181162.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
              "bytes": 334060,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ce2407eb4ff860e95cdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
              "bytes": 291512,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/772893bb018752b899d9.png"
            }
          ],
          "article": {
            "id": "b003e8b2488e",
            "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "bytes": 231787,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-b57d68f7092bb1833c8c.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/Hochreiter-meta-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "bytes": 277510,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c910fbb94e9497077e67.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/meta-RL-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "bytes": 70545,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-28c7d5f3966b58d0995d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/L2RL.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "bytes": 146618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3d90f7e1924950ee061d.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/RL_2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "bytes": 737321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-3c5ddbb346561ac954f4.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/MAESN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "bytes": 291684,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-d4e8da7e08714c6e544e.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/neural-episodic-control.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "bytes": 109328,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-c514078611120f181162.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/episodic-LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "bytes": 334060,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-ce2407eb4ff860e95cdd.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/POET.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "bytes": 291512,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/b003e8b2488e/images/body-772893bb018752b899d9.png",
                "src": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/DIAYN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In my earlier post on\nmeta-learning\n, the problem is mainly defined in the context of few-shot classification. Here I would like to explore more into cases when we try to “meta-learn”\nReinforcement Learning (RL)\ntasks by developing an agent that can solve unseen tasks fast and efficiently.\nTo recap, a good meta-learning model is expected to generalize to new tasks or new environments that have never been encountered during training. The adaptation process, essentially a\nmini learning session\n, happens at test with limited exposure to the new configurations. Even without any explicit fine-tuning (no gradient backpropagation on trainable variables), the meta-learning model autonomously adjusts internal hidden states to learn.\nTraining RL algorithms can be notoriously difficult sometimes. If the meta-learning agent could become so smart that the distribution of solvable unseen tasks grows extremely broad, we are on track towards\ngeneral purpose methods\n— essentially building a “brain” which would solve all kinds of RL problems without much human interference or manual feature engineering. Sounds amazing, right? 💖\nOn the Origin of Meta-RL\n#\nBack in 2001\n#\nI encountered a paper  written in 2001 by\nHochreiter et al.\nwhen reading\nWang et al., 2016\n. Although the idea was proposed for supervised learning, there are so many resemblances to the current approach to meta-RL.\nThe meta-learning system consists of the supervisory and the subordinate systems. The subordinate system is a recurrent neural network that takes as input both the observation at the current time step, $x\\_t$ and the label at the last time step, $y\\_{t-1}$. (Image source:\nHochreiter et al., 2001\n)\nHochreiter’s meta-learning model is a recurrent network with LSTM cell. LSTM is a good choice because it can internalize a history of inputs and tune its own weights effectively through\nBPTT\n. The training data contains $K$ sequences and each sequence is consist of $N$ samples generated by a target function $f_k(.), k=1, \\dots, K$,\n$$\n\\{\\text{input: }(\\mathbf{x}^k_i, \\mathbf{y}^k_{i-1}) \\to \\text{label: }\\mathbf{y}^k_i\\}_{i=1}^N\n\\text{ where }\\mathbf{y}^k_i = f_k(\\mathbf{x}^k_i)\n$$\nNoted that\nthe last label\n$\\mathbf{y}^k_{i-1}$ is also provided as an auxiliary input so that the function can learn the presented mapping.\nIn the experiment of decoding two-dimensional quadratic functions, $a x_1^2 + b x_2^2 + c x_1 x_2 + d x_1 + e x_2 + f$, with coefficients $a$-$f$ are randomly sampled from [-1, 1], this meta-learning system was able to approximate the function after seeing only ~35 examples.\nProposal in 2016\n#\nIn the modern days of DL,\nWang et al.\n(2016) and\nDuan et al.\n(2017) simultaneously proposed the very similar idea of\nMeta-RL\n(it is called\nRL^2\nin the second paper). A meta-RL model is trained over a distribution of MDPs, and at test time, it is able to learn to solve a new task quickly. The goal of meta-RL is ambitious, taking one step further towards general algorithms.\nDefine Meta-RL\n#\nMeta Reinforcement Learning\n, in short, is to do\nmeta-learning\nin the field of\nreinforcement learning\n. Usually the train and test tasks are different but drawn from the same family of problems; i.e., experiments in the papers included multi-armed bandit with different reward probabilities, mazes with different layouts, same robots but with different physical parameters in simulator, and many others.\nFormulation\n#\nLet’s say we have a distribution of tasks, each formularized as an\nMDP\n(Markov Decision Process), $M_i \\in \\mathcal{M}$. An MDP is determined by a 4-tuple, $M_i= \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle$:\nSymbol\nMeaning\n$\\mathcal{S}$\nA set of states.\n$\\mathcal{A}$\nA set of actions.\n$P_i: \\mathcal{S} \\times \\mathcal{A} \\times \\mathcal{S} \\to \\mathbb{R}_{+}$\nTransition probability function.\n$R_i: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}$\nReward function.\n(RL^2 paper adds an extra parameter, horizon $T$, into the MDP tuple to emphasize that each MDP should have a finite horizon.)\nNote that common state $\\mathcal{S}$ and action space $\\mathcal{A}$ are used above, so that a (stochastic) policy: $\\pi_\\theta: \\mathcal{S} \\times \\mathcal{A} \\to \\mathbb{R}_{+}$ would get inputs compatible across different tasks. The test tasks are sampled from the same distribution $\\mathcal{M}$ or slightly modified version.\nIllustration of meta-RL, containing two optimization loops. The outer loop samples a new environment in every iteration and adjusts parameters that determine the agent's behavior. In the inner loop, the agent interacts with the environment and optimizes for the maximal reward. (Image source:\nBotvinick, et al. 2019\n)\nMain Differences from RL\n#\nThe overall configure of meta-RL is very similar to an ordinary RL algorithm, except that\nthe last reward\n$r_{t-1}$ and\nthe last action\n$a_{t-1}$ are also incorporated into the policy observation in addition to the current state $s_t$.\nIn RL: $\\pi_\\theta(s_t) \\to$  a distribution over $\\mathcal{A}$\nIn meta-RL: $\\pi_\\theta(a_{t-1}, r_{t-1}, s_t) \\to$  a distribution over $\\mathcal{A}$\nThe intention of this design is to feed a history into the model so that the policy can internalize the dynamics between states, rewards, and actions in the current MDP and adjust its strategy accordingly. This is well aligned with the setup in\nHochreiter’s system\n. Both meta-RL and RL^2 implemented an LSTM policy and the LSTM’s hidden states serve as a\nmemory\nfor tracking characteristics of the trajectories. Because the policy is recurrent, there is no need to feed the last state as inputs explicitly.\nThe training procedure works as follows:\nSample a new MDP, $M_i \\sim \\mathcal{M}$;\nReset the hidden state\nof the model;\nCollect multiple trajectories and update the model weights;\nRepeat from step 1.\nIn the meta-RL paper, different actor-critic architectures all use a recurrent model. Last reward and last action are additional inputs. The observation is fed into the LSTM either as a one-hot vector or as an embedding vector after passed through an encoder model. (Image source:\nWang et al., 2016\n)\nAs described in the RL^2 paper, illustration of the procedure of the model interacting with a series of MDPs in training time . (Image source:\nDuan et al., 2017\n)\nKey Components\n#\nThere are three key components in Meta-RL:\n⭐\nA Model with Memory\nA recurrent neural network maintains a hidden state. Thus, it could acquire and memorize the knowledge about the current task by updating the hidden state during rollouts. Without memory, meta-RL would not work.\n⭐\nMeta-learning Algorithm\nA meta-learning algorithm refers to how we can update the model weights to optimize for the purpose of solving an unseen task fast at test time. In both Meta-RL and RL^2 papers, the meta-learning algorithm is the ordinary gradient descent update of LSTM with hidden state reset between a switch of MDPs.\n⭐\nA Distribution of MDPs\nWhile the agent is exposed to a variety of environments and tasks during training, it has to learn how to adapt to different MDPs.\nAccording to\nBotvinick et al.\n(2019), one source of slowness in RL training is\nweak\ninductive bias\n( = “a set of assumptions that the learner uses to predict outputs given inputs that it has not encountered”). As a general ML rule, a learning algorithm with weak inductive bias will be able to master a wider range of variance, but usually, will be less sample-efficient. Therefore, to narrow down the hypotheses with stronger inductive biases help improve the learning speed.\nIn meta-RL, we impose certain types of inductive biases from the\ntask distribution\nand store them in\nmemory\n. Which inductive bias to adopt at test time depends on the\nalgorithm\n. Together, these three key components depict a compelling view of meta-RL: Adjusting the weights of a recurrent network is slow but it allows the model to work out a new task fast with its own RL algorithm implemented in its internal activity dynamics.\nMeta-RL interestingly and not very surprisingly matches the ideas in the\nAI-GAs\n(“AI-Generating Algorithms”) paper by Jeff Clune (2019). He proposed that one efficient way towards building general AI is to make learning as automatic as possible. The AI-GAs approach involves three pillars: (1) meta-learning architectures, (2) meta-learning algorithms, and (3) automatically generated environments for effective learning.\nThe topic of designing good recurrent network architectures is a bit too broad to be discussed here, so I will skip it. Next, let’s look further into another two components: meta-learning algorithms in the context of meta-RL and how to acquire a variety of training MDPs.\nMeta-Learning Algorithms for Meta-RL\n#\nMy previous\npost\non meta-learning has covered several classic meta-learning algorithms. Here I’m gonna include more related to RL.\nOptimizing Model Weights for Meta-learning\n#\nBoth MAML (\nFinn, et al. 2017\n) and Reptile (\nNichol et al., 2018\n) are methods on updating model parameters in order to achieve good generalization performance on new tasks. See an earlier post\nsection\non MAML and Reptile.\nMeta-learning Hyperparameters\n#\nThe\nreturn\nfunction in an RL problem, $G_t^{(n)}$ or $G_t^\\lambda$, involves a few hyperparameters that are often set heuristically, like the discount factor\n$\\gamma$\nand the bootstrapping parameter\n$\\lambda$\n.\nMeta-gradient RL (\nXu et al., 2018\n) considers them as\nmeta-parameters\n, $\\eta=\\{\\gamma, \\lambda \\}$, that can be tuned and learned\nonline\nwhile an agent is interacting with the environment. Therefore, the return becomes a function of $\\eta$ and dynamically adapts itself to a specific task over time.\n$$\n\\begin{aligned}\nG_\\eta^{(n)}(\\tau_t) &= R_{t+1} + \\gamma R_{t+2} + \\dots + \\gamma^{n-1}R_{t+n} + \\gamma^n v_\\theta(s_{t+n}) & \\scriptstyle{\\text{; n-step return}} \\\\\nG_\\eta^{\\lambda}(\\tau_t) &= (1-\\lambda) \\sum_{n=1}^\\infty \\lambda^{n-1} G_\\eta^{(n)} & \\scriptstyle{\\text{; λ-return, mixture of n-step returns}}\n\\end{aligned}\n$$\nDuring training, we would like to update the policy parameters with gradients as a function of all the information in hand, $\\theta’ = \\theta + f(\\tau, \\theta, \\eta)$, where $\\theta$ are the current model weights, $\\tau$ is a sequence of trajectories, and $\\eta$ are the meta-parameters.\nMeanwhile, let’s say we have a meta-objective function $J(\\tau, \\theta, \\eta)$ as a performance measure. The training process follows the principle of online cross-validation, using a sequence of consecutive experiences:\nStarting with parameter $\\theta$, the policy $\\pi_\\theta$ is updated on the first batch of samples $\\tau$, resulting in $\\theta’$.\nThen we continue running the policy $\\pi_{\\theta’}$ to collect a new set of experiences $\\tau’$, just following $\\tau$ consecutively in time. The performance is measured as $J(\\tau’, \\theta’, \\bar{\\eta})$ with a fixed meta-parameter $\\bar{\\eta}$.\nThe gradient of meta-objective $J(\\tau’, \\theta’, \\bar{\\eta})$ w.r.t. $\\eta$ is used to update $\\eta$:\n$$\n\\begin{aligned}\n\\Delta \\eta\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\eta} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{d\\theta'}{d\\eta} & \\scriptstyle{\\text{ ; single variable chain rule.}} \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial (\\theta + f(\\tau, \\theta, \\eta))}{\\partial\\eta}  \\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big(\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\frac{d\\eta}{d\\eta} \\Big) & \\scriptstyle{\\text{; multivariable chain rule.}}\\\\\n&= -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\Big( \\color{red}{\\big(\\mathbf{I} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\theta}\\big)}\\frac{d\\theta}{d\\eta} + \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\\Big) & \\scriptstyle{\\text{; secondary gradient term in red.}}\n\\end{aligned}\n$$\nwhere $\\beta$ is the learning rate for $\\eta$.\nThe meta-gradient RL algorithm simplifies the computation by setting the secondary gradient term to zero, $\\mathbf{I} + \\partial g(\\tau, \\theta, \\eta)/\\partial\\theta = 0$ — this choice prefers the immediate effect of the meta-parameters $\\eta$ on the parameters $\\theta$. Eventually we get:\n$$\n\\Delta \\eta = -\\beta \\frac{\\partial J(\\tau', \\theta', \\bar{\\eta})}{\\partial \\theta'} \\frac{\\partial f(\\tau, \\theta, \\eta)}{\\partial\\eta}\n$$\nExperiments in the paper adopted the meta-objective function same as $TD(\\lambda)$ algorithm, minimizing the error between the approximated value function $v_\\theta(s)$ and the $\\lambda$-return:\n$$\n\\begin{aligned}\nJ(\\tau, \\theta, \\eta) &= (G^\\lambda_\\eta(\\tau) - v_\\theta(s))^2 \\\\\nJ(\\tau', \\theta', \\bar{\\eta}) &= (G^\\lambda_{\\bar{\\eta}}(\\tau') - v_{\\theta'}(s'))^2\n\\end{aligned}\n$$\nMeta-learning the Loss Function\n#\nIn policy gradient algorithms, the expected total reward is maximized by updating the policy parameters $\\theta$ in the direction of estimated gradient (\nSchulman et al., 2016\n),\n$$\ng = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\nabla_\\theta \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nwhere the candidates for $\\Psi_t$ include the trajectory return $G_t$, the Q value $Q(s_t, a_t)$, or the advantage value $A(s_t, a_t)$. The corresponding surrogate loss function for the policy gradient can be reverse-engineered:\n$$\nL_\\text{pg} = \\mathbb{E}[\\sum_{t=0}^\\infty \\Psi_t \\log \\pi_\\theta (a_t \\mid s_t)]\n$$\nThis loss function is a measure over a history of trajectories, $(s_0, a_0, r_0, \\dots, s_t, a_t, r_t, \\dots)$.\nEvolved Policy Gradient\n(\nEPG\n;\nHouthooft, et al, 2018\n) takes a step further by defining the policy gradient loss function as a temporal convolution (1-D convolution) over the agent’s past experience, $L_\\phi$. The parameters $\\phi$ of the loss function network are evolved in a way that an agent can achieve higher returns.\nSimilar to many meta-learning algorithms, EPG has two optimization loops:\nIn the internal loop, an agent learns to improve its policy $\\pi_\\theta$.\nIn the outer loop, the model updates the parameters $\\phi$ of the loss function $L_\\phi$. Because there is no explicit way to write down a differentiable equation between the return and the loss, EPG turned to\nEvolutionary Strategies\n(ES).\nA general idea is to train a population of $N$ agents, each of them is trained with the loss function $L_{\\phi + \\sigma \\epsilon_i}$ parameterized with $\\phi$ added with a small Gaussian noise $\\epsilon_i \\sim \\mathcal{N}(0, \\mathbf{I})$ of standard deviation $\\sigma$. During the inner loop’s training, EPG tracks a history of experience and updates the policy parameters according to the loss function $L_{\\phi + \\sigma\\epsilon_i}$ for each agent:\n$$\n\\theta_i \\leftarrow \\theta - \\alpha_\\text{in} \\nabla_\\theta L_{\\phi + \\sigma \\epsilon_i} (\\pi_\\theta, \\tau_{t-K, \\dots, t})\n$$\nwhere $\\alpha_\\text{in}$ is the learning rate of the inner loop and $\\tau_{t-K, \\dots, t}$ is a sequence of $M$ transitions up to the current time step $t$.\nOnce the inner loop policy is mature enough, the policy is evaluated by the mean return $\\bar{G}_{\\phi+\\sigma\\epsilon_i}$ over multiple randomly sampled trajectories. Eventually, we are able to estimate the gradient of $\\phi$ according to\nNES\nnumerically (\nSalimans et al, 2017\n). While repeating this process, both the policy parameters $\\theta$ and the loss function weights $\\phi$ are being updated simultaneously to achieve higher returns.\n$$\n\\phi \\leftarrow \\phi + \\alpha_\\text{out} \\frac{1}{\\sigma N} \\sum_{i=1}^N \\epsilon_i G_{\\phi+\\sigma\\epsilon_i}\n$$\nwhere $\\alpha_\\text{out}$ is the learning rate of the outer loop.\nIn practice, the loss $L_\\phi$ is bootstrapped with an ordinary policy gradient (such as REINFORCE or PPO) surrogate loss $L_\\text{pg}$, $\\hat{L} = (1-\\alpha) L_\\phi + \\alpha L_\\text{pg}$. The weight $\\alpha$ is annealing from 1 to 0 gradually during training. At test time, the loss function parameter $\\phi$ stays fixed and the loss value is computed over a history of experience to update the policy parameters $\\theta$.\nMeta-learning the Exploration Strategies\n#\nThe\nexploitation vs exploration\ndilemma is a critical problem in RL. Common ways to do exploration include $\\epsilon$-greedy, random noise on actions, or stochastic policy with built-in randomness on the action space.\nMAESN\n(\nGupta et al, 2018\n) is an algorithm to learn structured action noise from prior experience for better and more effective exploration. Simply adding random noise on actions cannot capture task-dependent or time-correlated exploration strategies. MAESN changes the policy to condition on a per-task random variable $z_i \\sim \\mathcal{N}(\\mu_i, \\sigma_i)$, for $i$-th task $M_i$, so we would have a policy $a \\sim \\pi_\\theta(a\\mid s, z_i)$.\nThe latent variable $z_i$ is sampled once and fixed during one episode. Intuitively, the latent variable determines one type of behavior (or skills) that should be explored more at the beginning of a rollout and the agent would adjust its actions accordingly. Both the policy parameters and latent space are optimized to maximize the total task rewards. In the meantime, the policy learns to make use of the latent variables for exploration.\nIn addition,  the loss function includes a KL divergence between the learned latent variable and a unit Gaussian prior, $D_\\text{KL}(\\mathcal{N}(\\mu_i, \\sigma_i)|\\mathcal{N}(0, \\mathbf{I}))$. On one hand, it restricts the learned latent space not too far from a common prior. On the other hand, it creates the variational evidence lower bound (\nELBO\n) for the reward function. Interestingly the paper found that $(\\mu_i, \\sigma_i)$ for each task are usually close to the prior at convergence.\nThe policy is conditioned on a latent variable variable $z\\_i \\sim \\mathcal{N}(\\mu, \\sigma)$ that is sampled once every episode. Each task has different hyperparameters for the latent variable distribution, $(\\mu\\_i, \\sigma\\_i)$ and they are optimized in the outer loop. (Image source:\nGupta et al, 2018\n)\nEpisodic Control\n#\nA major criticism of RL is on its sample inefficiency. A large number of samples and small learning steps are required for incremental parameter adjustment in RL in order to maximize generalization and avoid catastrophic forgetting of earlier learning (\nBotvinick et al., 2019\n).\nEpisodic control\n(\nLengyel & Dayan, 2008\n) is proposed as a solution to avoid forgetting and improve generalization while training at a faster speed. It is partially inspired by hypotheses on instance-based\nhippocampal\nlearning.\nAn\nepisodic memory\nkeeps explicit records of past events and uses these records directly as point of reference for making new decisions (i.e. just like\nmetric-based\nmeta-learning). In\nMFEC\n(Model-Free Episodic Control;\nBlundell et al., 2016\n), the memory is modeled as a big table, storing the state-action pair $(s, a)$ as key and the corresponding Q-value $Q_\\text{EC}(s, a)$ as value. When receiving a new observation $s$, the Q value is estimated in an non-parametric way as the average Q-value of top $k$ most similar samples:\n$$\n\\hat{Q}_\\text{EC}(s, a) = \n\\begin{cases}\nQ_\\text{EC}(s, a)                      & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\n\\frac{1}{k} \\sum_{i=1}^k Q(s^{(i)}, a) & \\text{otherwise}\n\\end{cases}\n$$\nwhere $s^{(i)}, i=1, \\dots, k$ are top $k$ states with smallest distances to the state $s$. Then the action that yields the highest estimated Q value is selected. Then the memory table is updated according to the return received at $s_t$:\n$$\nQ_\\text{EC}(s, a) \\leftarrow\n\\begin{cases}\n\\max\\{Q_\\text{EC}(s_t, a_t), G_t\\}  & \\text{if } (s,a) \\in Q_\\text{EC}, \\\\\nG_t                                 & \\text{otherwise}\n\\end{cases}\n$$\nAs a tabular RL method, MFEC suffers from large memory consumption and a lack of ways to generalize among similar states. The first one can be fixed with an LRU cache. Inspired by\nmetric-based\nmeta-learning, especially Matching Networks (\nVinyals et al., 2016\n), the generalization problem is improved in a follow-up algorithm,\nNEC\n(Neural Episodic Control;\nPritzel et al., 2016\n).\nThe episodic memory in NEC is a Differentiable Neural Dictionary (\nDND\n), where the key is a convolutional embedding vector of input image pixels and the value stores estimated Q value. Given an inquiry key, the output is a weighted sum of values of top similar keys, where the weight is a normalized kernel measure between the query key and the selected key in the dictionary. This sounds like a hard\nattention\nmachanism.\nFig. 6 Illustrations of episodic memory module in NEC and two operations on a differentiable neural dictionary. (Image source:\nPritzel et al., 2016\n)\nFurther,\nEpisodic LSTM\n(\nRitter et al., 2018\n) enhances the basic LSTM architecture with a DND episodic memory, which stores task context embeddings as keys and the LSTM cell states as values. The stored hidden states are retrieved and added directly to the current cell state through the same gating mechanism within LSTM:\nIllustration of the episodic LSTM architecture. The additional structure of episodic memory is in bold. (Image source:\nRitter et al., 2018\n)\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\mathbf{i}_t \\circ \\mathbf{c}_\\text{in} + \\mathbf{f}_t \\circ \\mathbf{c}_{t-1} + \\color{green}{\\mathbf{r}_t \\circ \\mathbf{c}_\\text{ep}} &\\\\\n\\mathbf{i}_t &= \\sigma(\\mathbf{W}_{i} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_i) & \\scriptstyle{\\text{; input gate}} \\\\\n\\mathbf{f}_t &= \\sigma(\\mathbf{W}_{f} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_f) & \\scriptstyle{\\text{; forget gate}} \\\\\n\\color{green}{\\mathbf{r}_t} & \\color{green}{=} \\color{green}{\\sigma(\\mathbf{W}_{r} \\cdot [\\mathbf{h}_{t-1}, \\mathbf{x}_t] + \\mathbf{b}_r)} & \\scriptstyle{\\text{; reinstatement gate}}\n\\end{aligned}\n$$\nwhere $\\mathbf{c}_t$ and $\\mathbf{h}_t$ are hidden and cell state at time $t$; $\\mathbf{i}_t$, $\\mathbf{f}_t$ and $\\mathbf{r}_t$ are input, forget and reinstatement gates, respectively; $\\mathbf{c}_\\text{ep}$ is the retrieved cell state from episodic memory. The newly added episodic memory components are marked in green.\nThis architecture provides a shortcut to the prior experience through context-based retrieval. Meanwhile, explicitly saving the task-dependent experience in an external memory avoids forgetting. In the paper, all the experiments have manually designed context vectors. How to construct an effective and efficient format of task context embeddings for more free-formed tasks would be an interesting topic.\nOverall the capacity of episodic control is limited by the complexity of the environment. It is very rare for an agent to repeatedly visit exactly the same states in a real-world task, so properly encoding the states is critical. The learned embedding space compresses the observation data into a lower dimension space and, in the meantime, two states being close in this space are expected to demand similar strategies.\nTraining Task Acquisition\n#\nAmong three key components, how to design a proper distribution of tasks is the less studied and probably the most specific one to meta-RL itself. As described\nabove\n, each task is a MDP: $M_i = \\langle \\mathcal{S}, \\mathcal{A}, P_i, R_i \\rangle \\in \\mathcal{M}$. We can build a distribution of MDPs by modifying:\nThe\nreward configuration\n: Among different tasks, same behavior might get rewarded differently according to $R_i$.\nOr, the\nenvironment\n: The transition function $P_i$ can be reshaped by initializing the environment with varying shifts between states.\nTask Generation by Domain Randomization\n#\nRandomizing parameters in a simulator is an easy way to obtain tasks with modified transition functions. If interested in learning further, check my last\npost\non\ndomain randomization\n.\nEvolutionary Algorithm on Environment Generation\n#\nEvolutionary algorithm\nis a gradient-free heuristic-based optimization method, inspired by natural selection. A population of solutions follows a loop of evaluation, selection, reproduction, and mutation. Eventually, good solutions survive and thus get selected.\nPOET\n(\nWang et al, 2019\n), a framework based on the evolutionary algorithm, attempts to generate tasks while the problems themselves are being solved. The implementation of POET is only specifically designed for a simple 2D\nbipedal walker\nenvironment but points out an interesting direction. It is noteworthy that the evolutionary algorithm has had some compelling applications in Deep Learning like\nEPG\nand PBT (Population-Based Training;\nJaderberg et al, 2017\n).\nAn example bipedal walking environment (top) and an overview of POET (bottom). (Image source:\nPOET blog post\n)\nThe 2D bipedal walking environment is evolving: from a simple flat surface to a much more difficult trail with potential gaps, stumps, and rough terrains. POET pairs the generation of environmental challenges and the optimization of agents together so as to (a) select agents that can resolve current challenges and (b) evolve environments to be solvable. The algorithm maintains a list of\nenvironment-agent pairs\nand repeats the following:\nMutation\n: Generate new environments from currently active environments. Note that here types of mutation operations are created just for bipedal walker and a new environment would demand a new set of configurations.\nOptimization\n: Train paired agents within their respective environments.\nSelection\n: Periodically attempt to transfer current agents from one environment to another. Copy and update the best performing agent for every environment. The intuition is that skills learned in one environment might be helpful for a different environment.\nThe procedure above is quite similar to\nPBT\n, but PBT mutates and evolves hyperparameters instead. To some extent, POET is doing\ndomain randomization\n, as all the gaps, stumps and terrain roughness are controlled by some randomization probability parameters. Different from DR, the agents are not exposed to a fully randomized difficult environment all at once, but instead they are learning gradually with a curriculum configured by the evolutionary algorithm.\nLearning with Random Rewards\n#\nAn MDP without a reward function $R$ is known as a\nControlled Markov process\n(CMP). Given a predefined CMP, $\\langle \\mathcal{S}, \\mathcal{A}, P\\rangle$, we can acquire a variety of tasks by generating a collection of reward functions $\\mathcal{R}$ that encourage the training of an effective meta-learning policy.\nGupta et al. (2018)\nproposed two unsupervised approaches  for growing the task distribution in the context of CMP. Assuming there is an underlying latent variable $z \\sim p(z)$ associated with every task, it parameterizes/determines a reward function: $r_z(s) = \\log D(z|s)$, where a “discriminator” function $D(.)$ is used to extract the latent variable from the state. The paper described two ways to construct a discriminator function:\nSample random weights $\\phi_\\text{rand}$ of the discriminator, $D_{\\phi_\\text{rand}}(z \\mid s)$.\nLearn a discriminator function to encourage diversity-driven exploration. This method is introduced in more details in another sister paper “DIAYN” (\nEysenbach et al., 2018\n).\nDIAYN, short for “Diversity is all you need”, is a framework to encourage a policy to learn useful skills without a reward function. It explicitly models the latent variable $z$ as a\nskill\nembedding and makes the policy conditioned on $z$ in addition to state $s$, $\\pi_\\theta(a \\mid s, z)$. (Ok, this part is same as\nMAESN\nunsurprisingly, as the papers are from the same group.) The design of DIAYN is motivated by a few hypotheses:\nSkills should be diverse and lead to visitations of different states. → maximize the mutual information between states and skills, $I(S; Z)$\nSkills should be distinguishable by states, not actions. → minimize the mutual information between actions and skills, conditioned on states $I(A; Z \\mid S)$\nThe objective function to maximize is as follows, where the policy entropy is also added to encourage diversity:\n$$\n\\begin{aligned}\n\\mathcal{F}(\\theta) \n&= I(S; Z) + H[A \\mid S] - I(A; Z \\mid S) &  \\\\\n&= (H(Z) - H(Z \\mid S)) + H[A \\mid S] - (H[A\\mid S] - H[A\\mid S, Z]) & \\\\\n&= H[A\\mid S, Z] \\color{green}{- H(Z \\mid S) + H(Z)} & \\\\\n&= H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\log p(z \\mid s)] - \\mathbb{E}_{z\\sim p(z)}[\\log p(z)] & \\scriptstyle{\\text{; can infer skills from states & p(z) is diverse.}} \\\\\n&\\ge H[A\\mid S, Z] + \\mathbb{E}_{z\\sim p(z), s\\sim\\rho(s)}[\\color{red}{\\log D_\\phi(z \\mid s) - \\log p(z)}] & \\scriptstyle{\\text{; according to Jensen's inequality; \"pseudo-reward\" in red.}}\n\\end{aligned}\n$$\nwhere $I(.)$ is mutual information and $H[.]$ is entropy measure. We cannot integrate all states to compute $p(z \\mid s)$, so approximate it with $D_\\phi(z \\mid s)$ — that is the diversity-driven discriminator function.\nDIAYN Algorithm. (Image source:\nEysenbach et al., 2019\n)\nOnce the discriminator function is learned, sampling a new MDP for training is strainght-forward: First, sample a latent variable, $z \\sim p(z)$ and construct a reward function $r_z(s) = \\log(D(z \\vert s))$. Pairing the reward function with a predefined CMP creates a new MDP.\nCited as:\n@article{weng2019metaRL,\n  title   = \"Meta Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-06-23-meta-rl/\"\n}\nReferences\n#\n[1] Richard S. Sutton.\n“The Bitter Lesson.”\nMarch 13, 2019.\n[2] Sepp Hochreiter, A. Steven Younger, and Peter R. Conwell.\n“Learning to learn using gradient descent.”\nIntl. Conf. on Artificial Neural Networks. 2001.\n[3] Jane X Wang, et al.\n“Learning to reinforcement learn.”\narXiv preprint arXiv:1611.05763 (2016).\n[4] Yan Duan, et al.\n“RL $^ 2$: Fast Reinforcement Learning via Slow Reinforcement Learning.”\nICLR 2017.\n[5] Matthew Botvinick, et al.\n“Reinforcement Learning, Fast and Slow”\nCell Review, Volume 23, Issue 5, P408-422, May 01, 2019.\n[6] Jeff Clune.\n“AI-GAs: AI-generating algorithms, an alternate paradigm for producing general artificial intelligence”\narXiv preprint arXiv:1905.10985 (2019).\n[7] Zhongwen Xu, et al.\n“Meta-Gradient Reinforcement Learning”\nNIPS 2018.\n[8] Rein Houthooft, et al.\n“Evolved Policy Gradients.”\nNIPS 2018.\n[9] Tim Salimans, et al.\n“Evolution strategies as a scalable alternative to reinforcement learning.”\narXiv preprint arXiv:1703.03864 (2017).\n[10] Abhishek Gupta, et al.\n“Meta-Reinforcement Learning of Structured Exploration Strategies.”\nNIPS 2018.\n[11] Alexander Pritzel, et al.\n“Neural episodic control.”\nProc. Intl. Conf. on Machine Learning, Volume 70, 2017.\n[12] Charles Blundell, et al.\n“Model-free episodic control.”\narXiv preprint arXiv:1606.04460 (2016).\n[13] Samuel Ritter, et al.\n“Been there, done that: Meta-learning with episodic recall.”\nICML, 2018.\n[14] Rui Wang et al.\n“Paired Open-Ended Trailblazer (POET): Endlessly Generating Increasingly Complex and Diverse Learning Environments and Their Solutions”\narXiv preprint arXiv:1901.01753 (2019).\n[15] Uber Engineering Blog:\n“POET: Endlessly Generating Increasingly Complex and Diverse Learning Environments and their Solutions through the Paired Open-Ended Trailblazer.”\nJan 8, 2019.\n[16] Abhishek Gupta, et al.\n“Unsupervised meta-learning for Reinforcement Learning”\narXiv preprint arXiv:1806.04640 (2018).\n[17] Eysenbach, Benjamin, et al.\n“Diversity is all you need: Learning skills without a reward function.”\nICLR 2019.\n[18] Max Jaderberg, et al.\n“Population Based Training of Neural Networks.”\narXiv preprint arXiv:1711.09846 (2017).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:27Z",
            "title": "Meta Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/b003e8b2488e/code/body-000.txt",
                "chars": 223,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_404",
                "url": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763.pdf",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d07e19c65fe402fbcd87.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.05763",
                "bytes": 3098326,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ef36a4fe103ce19e63ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02779",
                "bytes": 1730325,
                "reused": true,
                "local_path": "papers/repair/29d9036eedf2ce0e8bad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.10985",
                "bytes": 421434,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0e39e620cbcdc3c0e38c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03400",
                "bytes": 4064212,
                "reused": true,
                "local_path": "papers/repair/745c6af0eff74ad13278.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02999",
                "bytes": 1145571,
                "reused": true,
                "local_path": "papers/repair/7f84fa715e690339a4bf.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "bytes": 1111580,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bb993313e45a20ad529a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.02438",
                "bytes": 1798117,
                "reused": true,
                "local_path": "papers/repair/0e1163be1a9e279df56e.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "bytes": 1779803,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/85a9a7621c9e0663fa1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03864",
                "bytes": 277340,
                "reused": true,
                "local_path": "papers/repair/688c0e9989126a6eee1b.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "bytes": 2498781,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ddef5bb7adf90b31a4e2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "retried_at": "2026-10-20T17:37:17Z"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "bytes": 227616,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1c0ac870da375a0164dc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04460",
                "bytes": 915060,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c6d8db7782bea674b000.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "bytes": 2890623,
                "reused": true,
                "local_path": "papers/repair/66a471c52cb43cdc0b56.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.01988",
                "bytes": 2536595,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e1d79161cd219f80796c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09692",
                "bytes": 1441925,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b25973c32f2180b33c22.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": true,
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.09846",
                "bytes": 2370925,
                "reused": true,
                "local_path": "papers/repair/3bbdbf9c8931b9ea9ea0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.04640",
                "bytes": 2305556,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/022e9be73e69c1bb6162.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.06070",
                "bytes": 10804715,
                "reused": true,
                "local_path": "papers/repair/682027046f87efa4a50a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31542,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b003e8b2488e/pages/source.html",
            "local_html": "attachments/b003e8b2488e/pages/article.html",
            "body_base_path": "attachments/b003e8b2488e/pages/",
            "body_markdown_path": "attachments/b003e8b2488e/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Reinforcement Learning (RL)",
                "type": "a"
              },
              {
                "href": "http://incompleteideas.net/IncIdeas/BitterLesson.html",
                "label": "general purpose methods",
                "type": "a"
              },
              {
                "href": "http://snowedin.net/tmp/Hochreiter2001.pdf",
                "label": "Hochreiter et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.05763.pdf",
                "label": "Wang et al., 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Backpropagation_through_time",
                "label": "BPTT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.05763",
                "label": "Wang et al.",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02779",
                "label": "Duan et al.",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/action/showPdf?pii=S1364-6613%2819%2930061-0",
                "label": "Botvinick, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Inductive_bias",
                "label": "inductive bias",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.10985",
                "label": "AI-GAs",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03400",
                "label": "Finn, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02999",
                "label": "Nichol et al., 2018",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7507-meta-gradient-reinforcement-learning.pdf",
                "label": "Xu et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.02438",
                "label": "Schulman et al., 2016",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7785-evolved-policy-gradients.pdf",
                "label": "Houthooft, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolution_strategy",
                "label": "Evolutionary Strategies",
                "type": "a"
              },
              {
                "href": "http://blog.otoro.net/2017/10/29/visual-evolution-strategies/",
                "label": "NES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03864",
                "label": "Salimans et al, 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "exploitation vs exploration",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7776-meta-reinforcement-learning-of-structured-exploration-strategies.pdf",
                "label": "Gupta et al, 2018",
                "type": "a"
              },
              {
                "href": "http://users.umiacs.umd.edu/~xyang35/files/understanding-variational-lower.pdf",
                "label": "ELBO",
                "type": "a"
              },
              {
                "href": "https://www.cell.com/trends/cognitive-sciences/fulltext/S1364-6613(19)30061-0",
                "label": "Botvinick et al., 2019",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/3311-hippocampal-contributions-to-control-the-third-way.pdf",
                "label": "Lengyel & Dayan, 2008",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Hippocampus",
                "label": "hippocampal",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04460",
                "label": "Blundell et al., 2016",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf",
                "label": "Vinyals et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.01988",
                "label": "Pritzel et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09692",
                "label": "Ritter et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "post",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Evolutionary_algorithm",
                "label": "Evolutionary algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://gym.openai.com/envs/BipedalWalkerHardcore-v2/",
                "label": "bipedal walker",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.09846",
                "label": "Jaderberg et al, 2017",
                "type": "a"
              },
              {
                "href": "https://eng.uber.com/poet-open-ended-deep-learning/",
                "label": "POET blog post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.04640",
                "label": "Gupta et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.06070",
                "label": "Eysenbach et al., 2018",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
          "status": "partial",
          "article_id": "bf0a610ccb4a",
          "local_path": "series-follow/1601/repair/61967ef293614fa66635.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
              "bytes": 513885,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f359d38ab20e9cdac179.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
              "bytes": 1270278,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8d6f8ad7272758de8c53.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
              "bytes": 768852,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7c81aafa4666fddd3762.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
              "bytes": 2642257,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c64df87fedc22e7713a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
              "bytes": 249192,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d72676a1e2d7d681665b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
              "bytes": 737673,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/284f09a3dc26a2be2be6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "bytes": 1162740,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/574c20fa1107bf61368d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
              "bytes": 566411,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/817ed503b242a7831692.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
              "bytes": 103291,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/26dfcda8fac62755a0e6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
              "bytes": 225014,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a7ef42a592f8d64c0933.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
              "bytes": 267029,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/38455ea040ea0eae9625.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
              "bytes": 163908,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2f0fc009f289b69c8d79.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
              "bytes": 1281590,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e3a5248959b284127268.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
              "bytes": 1411892,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/316474d8ca427819890a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
              "bytes": 218384,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7dd458cefc09c96c4325.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
              "bytes": 135102,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/70000ddd170ac7e5840b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
              "bytes": 2011971,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ae4b346db197ccab2cfe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
              "bytes": 157839,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1da73a82998c80ae17c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
              "bytes": 1115258,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/976ef652676b26b5a203.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
              "bytes": 1886891,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f8bf05d0018c01caf352.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
              "bytes": 2352713,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dee16f2c447f7c91e79e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
              "bytes": 917157,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7de401f88063093a58d8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
              "bytes": 391776,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ce13a8280e64dce3dbf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
              "bytes": 1753636,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c37fd073afd7cb9698fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
              "bytes": 1839222,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e113f6beb0962c59d170.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
              "bytes": 164404,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c9ea48204e2765c959ab.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
              "bytes": 388169,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/139471e0d9b6eef5fde9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
              "bytes": 350225,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/211c4ab593d56ae944a3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Self-Supervised Representation Learning",
            "keywords": "自监督,表示学习,预训练",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "publish_date": "2019-11",
            "corpus_stage": "预训练/SFT",
            "notes": "自监督表示学习综述",
            "id": "bf0a610ccb4a",
            "collected_at": "2026-10-02T14:13:29",
            "title": "Self-Supervised Representation Learning | Lil'Log",
            "body_markdown": "[Updated on 2020-01-09: add a new section on\nContrastive Predictive Coding\n].\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n[Updated on 2020-07-08: add a\n“Bisimulation”\nsection on DeepMDP and DBC.]\n[Updated on 2020-09-12: add\nMoCo V2\nand\nBYOL\nin the “Momentum Contrast” section.]\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on\n“Contrastive Representation Learning”\n]\nGiven a task and enough labels, supervised learning can solve it really well. Good performance usually requires a decent amount of labels, but collecting manual labels is expensive (i.e. ImageNet) and hard to be scaled up. Considering the amount of unlabelled data (e.g. free text, all the images on the Internet) is substantially more than a limited number of human curated labelled datasets, it is kinda wasteful not to use them. However, unsupervised learning is not easy and usually works much less efficiently than supervised learning.\nWhat if we can get labels for free for unlabelled data and train unsupervised dataset in a supervised manner? We can achieve this by framing a supervised learning task in a special form to predict only a subset of information using the rest. In this way, all the information needed, both inputs and labels, has been provided. This is known as\nself-supervised learning\n.\nThis idea has been widely used in language modeling. The default task for a language model is to predict the next word given the past sequence.\nBERT\nadds two other auxiliary tasks and both rely on self-generated labels.\nA great summary of how self-supervised learning tasks can be constructed (Image source:\nLeCun’s talk\n)\nHere\nis a nicely curated list of papers in self-supervised learning. Please check it out if you are interested in reading more in depth.\nNote that this post does not focus on either NLP /\nlanguage modeling\nor\ngenerative modeling\n.\nWhy Self-Supervised Learning?\n#\nSelf-supervised learning empowers us to exploit a variety of labels that come with the data for free. The motivation is quite straightforward. Producing a dataset with clean labels is expensive but unlabeled data is being generated all the time. To make use of this much larger amount of unlabeled data, one way is to set the learning objectives properly so as to get supervision from the data itself.\nThe\nself-supervised task\n, also known as\npretext task\n, guides us to a supervised loss function. However, we usually don’t care about the final performance of this invented task. Rather we are interested in the learned intermediate representation with the expectation that this representation can carry good semantic or structural meanings and can be beneficial to a variety of practical downstream tasks.\nFor example, we might rotate images at random and train a model to predict how each input image is rotated. The rotation prediction task is made-up, so the actual accuracy is unimportant, like how we treat auxiliary tasks. But we expect the model to learn high-quality latent variables for real-world tasks, such as constructing an object recognition classifier with very few labeled samples.\nBroadly speaking, all the generative models can be considered as self-supervised, but with different goals: Generative models focus on creating diverse and realistic images, while self-supervised representation learning care about producing good features generally helpful for many tasks. Generative modeling is not the focus of this post, but feel free to check my\nprevious posts\n.\nImages-Based\n#\nMany ideas have been proposed for self-supervised representation learning on images. A common workflow is to train a model on one or multiple pretext tasks with unlabelled images and then use one intermediate feature layer of this model to feed a multinomial logistic regression classifier on ImageNet classification. The final classification accuracy quantifies how good the learned representation is.\nRecently, some researchers proposed to train supervised learning on labelled data and self-supervised pretext tasks on unlabelled data simultaneously with shared weights, like in\nZhai et al, 2019\nand\nSun et al, 2019\n.\nDistortion\n#\nWe expect small distortion on an image does not modify its original semantic meaning or geometric forms. Slightly distorted images are considered the same as original and thus the learned features are expected to be invariant to distortion.\nExemplar-CNN\n(\nDosovitskiy et al., 2015\n) create surrogate training datasets with unlabeled image patches:\nSample $N$ patches of size 32 × 32 pixels from different images at varying positions and scales, only from regions containing considerable gradients as those areas cover edges and tend to contain objects or parts of objects. They are\n“exemplary”\npatches.\nEach patch is distorted by applying a variety of random transformations (i.e., translation, rotation, scaling, etc.). All the resulting distorted patches are considered to belong to the\nsame surrogate class\n.\nThe pretext task is to discriminate between a set of surrogate classes. We can arbitrarily create as many surrogate classes as we want.\nThe original patch of a cute deer is in the top left corner. Random transformations are applied, resulting in a variety of distorted patches. All of them should be classified into the same class in the pretext task. (Image source:\nDosovitskiy et al., 2015\n)\nRotation\nof an entire image (\nGidaris et al. 2018\nis another interesting and cheap way to modify an input image while the semantic content stays unchanged. Each input image is first rotated by a multiple of $90^\\circ$ at random, corresponding to $[0^\\circ, 90^\\circ, 180^\\circ, 270^\\circ]$. The model is trained to predict which rotation has been applied, thus a 4-class classification problem.\nIn order to identify the same image with different rotations, the model has to learn to recognize high level object parts, such as heads, noses, and eyes, and the relative positions of these parts, rather than local patterns. This pretext task drives the model to learn semantic concepts of objects in this way.\nIllustration of self-supervised learning by rotating the entire input images. The model learns to predict which rotation is applied. (Image source:\nGidaris et al. 2018\n)\nPatches\n#\nThe second category of self-supervised learning tasks extract multiple patches from one image and ask the model to predict the relationship between these patches.\nDoersch et al. (2015)\nformulates the pretext task as predicting the\nrelative position\nbetween two random patches from one image. A model needs to understand the spatial context of objects in order to tell the relative position between parts.\nThe training patches are sampled in the following way:\nRandomly sample the first patch without any reference to image content.\nConsidering that the first patch is placed in the middle of a 3x3 grid, and the second patch is sampled from its 8 neighboring locations around it.\nTo avoid the model only catching low-level trivial signals, such as connecting a straight line across boundary or matching local patterns, additional noise is introduced by:\nAdd gaps between patches\nSmall jitters\nRandomly downsample some patches to as little as 100 total pixels, and then upsampling it, to build robustness to pixelation.\nShift green and magenta toward gray or randomly drop 2 of 3 color channels (See\n“chromatic aberration”\nbelow)\nThe model is trained to predict which one of 8 neighboring locations the second patch is selected from, a classification problem over 8 classes.\nIllustration of self-supervised learning by predicting the relative position of two random patches. (Image source:\nDoersch et al., 2015\n)\nOther than trivial signals like boundary patterns or textures continuing, another interesting and a bit surprising trivial solution was found, called\n“chromatic aberration”\n. It is triggered by different focal lengths of lights at different wavelengths passing through the lens. In the process, there might exist small offsets between color channels. Hence, the model can learn to tell the relative position by simply comparing how green and magenta are separated differently in two patches. This is a trivial solution and has nothing to do with the image content. Pre-processing images by shifting green and magenta toward gray or randomly dropping 2 of 3 color channels can avoid this trivial solution.\nIllustration of how chromatic aberration happens. (Image source:\nwikipedia\n)\nSince we have already set up a 3x3 grid in each image in the above task, why not use all of 9 patches rather than only 2 to make the task more difficult? Following this idea,\nNoroozi & Favaro (2016)\ndesigned a\njigsaw puzzle\ngame as pretext task: The model is trained to place 9 shuffled patches back to the original locations.\nA convolutional network processes each patch independently with shared weights and outputs a probability vector per patch index out of a predefined set of permutations. To control the difficulty of jigsaw puzzles, the paper proposed to shuffle patches according to a predefined permutation set and configured the model to predict a probability vector over all the indices in the set.\nBecause how the input patches are shuffled does not alter the correct order to predict. A potential improvement to speed up training is to use permutation-invariant graph convolutional network (GCN) so that we don’t have to shuffle the same set of patches multiple times, same idea as in this\npaper\n.\nIllustration of self-supervised learning by solving jigsaw puzzle. (Image source:\nNoroozi & Favaro, 2016\n)\nAnother idea is to consider “feature” or “visual primitives” as a scalar-value attribute that can be summed up over multiple patches and compared across different patches. Then the relationship between patches can be defined by\ncounting features\nand simple arithmetic (\nNoroozi, et al, 2017\n).\nThe paper considers two transformations:\nScaling\n:  If an image is scaled up by 2x, the number of visual primitives should stay the same.\nTiling\n: If an image is tiled into a 2x2 grid, the number of visual primitives is expected to be the sum, 4 times the original feature counts.\nThe model learns a feature encoder $\\phi(.)$ using the above feature counting relationship. Given an input image $\\mathbf{x} \\in \\mathbb{R}^{m \\times n \\times 3}$, considering two types of transformation operators:\nDownsampling operator, $D: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: downsample by a factor of 2\nTiling operator $T_i: \\mathbb{R}^{m \\times n \\times 3} \\mapsto \\mathbb{R}^{\\frac{m}{2} \\times \\frac{n}{2} \\times 3}$: extract the $i$-th tile from a 2x2 grid of the image.\nWe expect to learn:\n$$\n\\phi(\\mathbf{x}) = \\phi(D \\circ \\mathbf{x}) = \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\n$$\nThus the MSE loss is: $\\mathcal{L}_\\text{feat} = |\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2$. To avoid trivial solution $\\phi(\\mathbf{x}) = \\mathbf{0}, \\forall{\\mathbf{x}}$, another loss term is added to encourage the difference between features of two different images: $\\mathcal{L}_\\text{diff} = \\max(0, c -|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})|^2_2)$, where $\\mathbf{y}$ is another input image different from $\\mathbf{x}$ and $c$ is a scalar constant. The final loss is:\n$$\n\\mathcal{L} \n= \\mathcal{L}_\\text{feat} + \\mathcal{L}_\\text{diff} \n= \\|\\phi(D \\circ \\mathbf{x}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2 + \\max(0, M -\\|\\phi(D \\circ \\mathbf{y}) - \\sum_{i=1}^4 \\phi(T_i \\circ \\mathbf{x})\\|^2_2)\n$$\nSelf-supervised representation learning by counting features. (Image source:\nNoroozi, et al, 2017\n)\nColorization\n#\nColorization\ncan be used as a powerful self-supervised task: a model is trained to color a grayscale input image; precisely the task is to map this image to a distribution over quantized color value outputs (\nZhang et al. 2016\n).\nThe model outputs colors in the the\nCIE L\na\nb* color space\n. The L\na\nb* color is designed to approximate human vision, while, in contrast, RGB or CMYK models the color output of physical devices.\nL* component matches human perception of lightness; L* = 0 is black and L* = 100 indicates white.\na* component represents green (negative) / magenta (positive) value.\nb* component models blue (negative) /yellow (positive) value.\nDue to the multimodal nature of the colorization problem, cross-entropy loss of predicted probability distribution over binned color values works better than L2 loss of the raw color values. The a\nb\ncolor space is quantized with bucket size 10.\nTo balance between common colors (usually low a\nb\nvalues, of common backgrounds like clouds, walls, and dirt) and rare colors (which are likely associated with key objects in the image), the loss function is rebalanced with a weighting term that boosts the loss of infrequent color buckets. This is just like why we need both\ntf and idf\nfor scoring words in information retrieval model. The weighting term is constructed as: (1-λ) * Gaussian-kernel-smoothed empirical probability distribution + λ * a uniform distribution, where both distributions are over the quantized a\nb\ncolor space.\nGenerative Modeling\n#\nThe pretext task in generative modeling is to reconstruct the original input while learning meaningful latent representation.\nThe\ndenoising autoencoder\n(\nVincent, et al, 2008\n) learns to recover an image from a version that is partially corrupted or has random noise. The design is inspired by the fact that humans can easily recognize objects in pictures even with noise, indicating that key visual features can be extracted and separated from noise. See my\nold post\n.\nThe\ncontext encoder\n(\nPathak, et al., 2016\n) is trained to fill in a missing piece in the image. Let $\\hat{M}$ be a binary mask, 0 for dropped pixels and 1 for remaining input pixels. The model is trained with a combination of the reconstruction (L2) loss and the adversarial loss. The removed regions defined by the mask could be of any shape.\n$$\n\\begin{aligned}\n\\mathcal{L}(\\mathbf{x}) &= \\mathcal{L}_\\text{recon}(\\mathbf{x}) + \\mathcal{L}_\\text{adv}(\\mathbf{x})\\\\\n\\mathcal{L}_\\text{recon}(\\mathbf{x}) &= \\|(1 - \\hat{M}) \\odot (\\mathbf{x} - F(\\hat{M} \\odot \\mathbf{x})) \\|_2^2 \\\\\n\\mathcal{L}_\\text{adv}(\\mathbf{x}) &= \\max_D \\mathbb{E}_{\\mathbf{x}} [\\log D(\\mathbf{x}) + \\log(1 - D(F(\\hat{M} \\odot \\mathbf{x})))]\n\\end{aligned}\n$$\nwhere $F(.)$ is the full pipeline of reconstructing the input image with missing regions via impainting, including both encoder and decoder portions in $D(.)$ is the discriminator model jointly trained, like in\nGAN\n.\nIllustration of context encoder. (Image source:\nPathak, et al., 2016\n)\nWhen applying a mask on an image, the context encoder removes information of all the color channels in partial regions. How about only hiding a subset of channels? The\nsplit-brain autoencoder\n(\nZhang et al., 2017\n) does this by predicting a subset of color channels from the rest of channels. Let the data tensor $\\mathbf{x} \\in \\mathbb{R}^{h \\times w \\times \\vert C \\vert }$ with $C$ color channels be the input for the $l$-th layer of the network. It is split into two disjoint parts, $\\mathbf{x}_1 \\in \\mathbb{R}^{h \\times w \\times \\vert C_1 \\vert}$ and $\\mathbf{x}_2 \\in \\mathbb{R}^{h \\times w \\times \\vert C_2 \\vert}$, where $C_1 , C_2 \\subseteq C$. Then two sub-networks are trained to do two complementary predictions: one network $f_1$ predicts $\\mathbf{x}_2$ from $\\mathbf{x}_1$ and the other network $f_1$ predicts $\\mathbf{x}_1$ from $\\mathbf{x}_2$. The loss is either L1 loss or cross entropy if color values are quantized.\nThe split can happen once on the RGB-D or L\na\nb* colorspace, or happen even in every layer of a CNN network in which the number of channels can be arbitrary.\nIllustration of split-brain autoencoder. (Image source:\nZhang et al., 2017\n)\nThe generative adversarial networks (GANs) are able to learn to map from simple latent variables to arbitrarily complex data distributions. Studies have shown that the latent space of such generative models captures semantic variation in the data; e.g. when training GAN models on human faces, some latent variables are associated with facial expression, glasses, gender, etc  (\nRadford et al., 2016\n).\nBidirectional GANs\n(\nDonahue, et al, 2017\n) introduces an additional encoder $E(.)$ to learn the mappings from the input to the latent variable $\\mathbf{z}$. The discriminator $D(.)$ predicts in the joint space of the input data and latent representation, $(\\mathbf{x}, \\mathbf{z})$, to tell apart the generated pair $(\\mathbf{x}, E(\\mathbf{x}))$ from the real one $(G(\\mathbf{z}), \\mathbf{z})$. The model is trained to optimize the objective: $\\min_{G, E} \\max_D V(D, E, G)$, where the generator $G$ and the encoder $E$ learn to generate data and latent variables that are realistic enough to confuse the discriminator and at the same time the discriminator $D$ tries to differentiate real and generated data.\n$$\nV(D, E, G) = \\mathbb{E}_{\\mathbf{x} \\sim p_\\mathbf{x}} [ \\underbrace{\\mathbb{E}_{\\mathbf{z} \\sim p_E(.\\vert\\mathbf{x})}[\\log D(\\mathbf{x}, \\mathbf{z})]}_{\\log D(\\text{real})} ] + \\mathbb{E}_{\\mathbf{z} \\sim p_\\mathbf{z}} [ \\underbrace{\\mathbb{E}_{\\mathbf{x} \\sim p_G(.\\vert\\mathbf{z})}[\\log 1 - D(\\mathbf{x}, \\mathbf{z})]}_{\\log(1- D(\\text{fake}))}) ]\n$$\nIllustration of how Bidirectional GAN works. (Image source:\nDonahue, et al, 2017\n)\nContrastive Learning\n#\nThe\nContrastive Predictive Coding (CPC)\n(\nvan den Oord, et al. 2018\n) is an approach for unsupervised learning from high-dimensional data by translating a generative modeling problem to a classification problem. The\ncontrastive loss\nor\nInfoNCE loss\nin CPC, inspired by\nNoise Contrastive Estimation (NCE)\n, uses cross-entropy loss to measure how well the model can classify the “future” representation amongst a set of unrelated “negative” samples. Such design is partially motivated by the fact that the unimodal loss like MSE has no enough capacity but learning a full generative model could be too expensive.\nIllustration of applying Contrastive Predictive Coding on the audio input. (Image source:\nvan den Oord, et al. 2018\n)\nCPC uses an encoder to compress the input data $z_t = g_\\text{enc}(x_t)$ and an\nautoregressive\ndecoder to learn the high-level context that is potentially shared across future predictions, $c_t = g_\\text{ar}(z_{\\leq t})$. The end-to-end training relies on the NCE-inspired contrastive loss.\nWhile predicting future information, CPC is optimized to maximize the the mutual information between input $x$ and context vector $c$:\n$$\nI(x; c) = \\sum_{x, c} p(x, c) \\log\\frac{p(x, c)}{p(x)p(c)} = \\sum_{x, c} p(x, c)\\log\\frac{p(x|c)}{p(x)}\n$$\nRather than modeling the future observations $p_k(x_{t+k} \\vert c_t)$ directly (which could be fairly expensive), CPC models a density function to preserve the mutual information between $x_{t+k}$ and $c_t$:\n$$\nf_k(x_{t+k}, c_t) = \\exp(z_{t+k}^\\top W_k c_t) \\propto \\frac{p(x_{t+k}|c_t)}{p(x_{t+k})}\n$$\nwhere $f_k$ can be unnormalized and a linear transformation $W_k^\\top c_t$ is used for the prediction with a different $W_k$ matrix for every step $k$.\nGiven a set of $N$ random samples $X = \\{x_1, \\dots, x_N\\}$ containing only one positive sample $x_t \\sim p(x_{t+k} \\vert c_t)$ and $N-1$ negative samples $x_{i \\neq t} \\sim p(x_{t+k})$, the cross-entropy loss for classifying the positive sample (where $\\frac{f_k}{\\sum f_k}$ is the prediction) correctly is:\n$$\n\\mathcal{L}_N = - \\mathbb{E}_X \\Big[\\log \\frac{f_k(x_{t+k}, c_t)}{\\sum_{i=1}^N f_k (x_i, c_t)}\\Big]\n$$\nIllustration of applying Contrastive Predictive Coding on images. (Image source:\nvan den Oord, et al. 2018\n)\nWhen using CPC on images (\nHenaff, et al. 2019\n), the predictor network should only access a masked feature set to avoid a trivial prediction. Precisely:\nEach input image is divided into a set of overlapped patches and each patch is encoded by a resnet encoder, resulting in compressed feature vector $z_{i,j}$.\nA masked conv net makes prediction with a mask such that the receptive field of a given output neuron can only see things above it in the image. Otherwise, the prediction problem would be trivial. The prediction can be made in both directions (top-down and bottom-up).\nThe prediction is made for $z_{i+k, j}$ from context $c_{i,j}$: $\\hat{z}_{i+k, j} = W_k c_{i,j}$.\nA contrastive loss quantifies this prediction with a goal to correctly identify the target among a set of negative representation $\\{z_l\\}$ sampled from other patches in the same image and other images in the same batch:\n$$\n\\mathcal{L}_\\text{CPC} \n= -\\sum_{i,j,k} \\log p(z_{i+k, j} \\vert \\hat{z}_{i+k, j}, \\{z_l\\}) \n= -\\sum_{i,j,k} \\log \\frac{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j})}{\\exp(\\hat{z}_{i+k, j}^\\top z_{i+k, j}) + \\sum_l \\exp(\\hat{z}_{i+k, j}^\\top z_l)}\n$$\nFor more content on contrastive learning, check out the post on\n“Contrastive Representation Learning”\n.\nVideo-Based\n#\nA video contains a sequence of semantically related frames. Nearby frames are close in time and more correlated than frames further away. The order of frames describes certain rules of reasonings and physical logics; such as that object motion should be smooth and gravity is pointing down.\nA common workflow is to train a model on one or multiple pretext tasks with unlabelled videos and then feed one intermediate feature layer of this model to fine-tune a simple model on downstream tasks of action classification, segmentation or object tracking.\nTracking\n#\nThe movement of an object is traced by a sequence of video frames. The difference between how the same object is captured on the screen in close frames is usually not big, commonly triggered by small motion of the object or the camera. Therefore any visual representation learned for the same object across close frames should be close in the latent feature space. Motivated by this idea,\nWang & Gupta, 2015\nproposed a way of unsupervised learning of visual representation by\ntracking moving objects\nin videos.\nPrecisely patches with motion are tracked over a small time window (e.g. 30 frames). The first patch $\\mathbf{x}$ and the last patch $\\mathbf{x}^+$ are selected and used as training data points. If we train the model directly to minimize the difference between feature vectors of two patches, the model may only learn to map everything to the same value. To avoid such a trivial solution, same as\nabove\n, a random third patch $\\mathbf{x}^-$ is added. The model learns the representation by enforcing the distance between two tracked patches to be closer than the distance between the first patch and a random one in the feature space, $D(\\mathbf{x}, \\mathbf{x}^-)) > D(\\mathbf{x}, \\mathbf{x}^+)$, where $D(.)$ is the cosine distance,\n$$\nD(\\mathbf{x}_1, \\mathbf{x}_2) = 1 - \\frac{f(\\mathbf{x}_1) f(\\mathbf{x}_2)}{\\|f(\\mathbf{x}_1)\\| \\|f(\\mathbf{x}_2\\|)}\n$$\nThe loss function is:\n$$\n\\mathcal{L}(\\mathbf{x}, \\mathbf{x}^+, \\mathbf{x}^-) \n= \\max\\big(0, D(\\mathbf{x}, \\mathbf{x}^+) - D(\\mathbf{x}, \\mathbf{x}^-) + M\\big) + \\text{weight decay regularization term}\n$$\nwhere $M$ is a scalar constant controlling for the minimum gap between two distances; $M=0.5$ in the paper. The loss enforces $D(\\mathbf{x}, \\mathbf{x}^-) >= D(\\mathbf{x}, \\mathbf{x}^+) + M$ at the optimal case.\nThis form of loss function is also known as\ntriplet loss\nin the face recognition task, in which the dataset contains images of multiple people from multiple camera angles. Let $\\mathbf{x}^a$ be an anchor image of a specific person, $\\mathbf{x}^p$ be a positive image of this same person from a different angle and $\\mathbf{x}^n$ be a negative image of a different person. In the embedding space, $\\mathbf{x}^a$ should be closer to $\\mathbf{x}^p$ than $\\mathbf{x}^n$:\n$$\n\\mathcal{L}_\\text{triplet}(\\mathbf{x}^a, \\mathbf{x}^p, \\mathbf{x}^n) = \\max(0, \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^p) \\|_2^2 -  \\|\\phi(\\mathbf{x}^a) - \\phi(\\mathbf{x}^n) \\|_2^2 + M)\n$$\nA slightly different form of the triplet loss, named\nn-pair loss\nis also commonly used for learning observation embedding in robotics tasks. See a\nlater section\nfor more related content.\nOverview of learning representation by tracking objects in videos. (a) Identify moving patches in short traces; (b) Feed two related patched and one random patch into a conv network with shared weights. (c) The loss function enforces the distance between related patches to be closer than the distance between random patches. (Image source:\nWang & Gupta, 2015\n)\nRelevant patches are tracked and extracted through a two-step unsupervised\noptical flow\napproach:\nObtain\nSURF\ninterest points and use\nIDT\nto obtain motion of each SURF point.\nGiven the trajectories of SURF interest points, classify these points as moving if the flow magnitude is more than 0.5 pixels.\nDuring training, given a pair of correlated patches $\\mathbf{x}$ and $\\mathbf{x}^+$, $K$ random patches $\\{\\mathbf{x}^-\\}$ are sampled in this same batch to form $K$ training triplets. After a couple of epochs,\nhard negative mining\nis applied to make the training harder and more efficient, that is, to search for random patches that maximize the loss and use them to do gradient updates.\nFrame Sequence\n#\nVideo frames are naturally positioned in chronological order. Researchers have proposed several self-supervised tasks, motivated by the expectation that good representation should learn the\ncorrect sequence\nof frames.\nOne idea is to\nvalidate frame order\n(\nMisra, et al 2016\n). The pretext task is to determine whether a sequence of frames from a video is placed in the correct temporal order (“temporal valid”). The model needs to track and reason about small motion of an object across frames to complete such a task.\nThe training frames are sampled from high-motion windows. Every time 5 frames are sampled $(f_a, f_b, f_c, f_d, f_e)$ and the timestamps are in order $a < b < c < d < e$. Out of 5 frames, one positive tuple $(f_b, f_c, f_d)$ and two negative tuples, $(f_b, f_a, f_d)$ and $(f_b, f_e, f_d)$ are created. The parameter $\\tau_\\max = \\vert b-d \\vert$ controls the difficulty of positive training instances (i.e. higher → harder) and the parameter $\\tau_\\min = \\min(\\vert a-b \\vert, \\vert d-e \\vert)$ controls the difficulty of negatives (i.e. lower → harder).\nThe pretext task of video frame order validation is shown to improve the performance on the downstream task of action recognition when used as a pretraining step.\nOverview of learning representation by validating the order of video frames. (a) the data sample process; (b) the model is a triplet siamese network, where all input frames have shared weights. (Image source:\nMisra, et al 2016\n)\nThe task in\nO3N\n(Odd-One-Out Network;\nFernando et al. 2017\n) is based on video frame sequence validation too. One step further from above, the task is to\npick the incorrect sequence\nfrom multiple video clips.\nGiven $N+1$ input video clips, one of them has frames shuffled, thus in the wrong order, and the rest $N$ of them remain in the correct temporal order. O3N learns to predict the location of the odd video clip. In their experiments, there are 6 input clips and each contain 6 frames.\nThe\narrow of time\nin a video contains very informative messages, on both low-level physics (e.g. gravity pulls objects down to the ground; smoke rises up; water flows downward.) and high-level event reasoning (e.g. fish swim forward; you can break an egg but cannot revert it.). Thus another idea is inspired by this to learn latent representation by predicting the arrow of time (AoT) — whether video playing forwards or backwards (\nWei et al., 2018\n).\nA classifier should capture both low-level physics and high-level semantics in order to predict the arrow of time. The proposed\nT-CAM\n(Temporal Class-Activation-Map) network accepts $T$ groups, each containing a number of frames of optical flow. The conv layer outputs from each group are concatenated and fed into binary logistic regression for predicting the arrow of time.\nOverview of learning representation by predicting the arrow of time. (a) Conv features of multiple groups of frame sequences are concatenated. (b) The top level contains 3 conv layers and average pooling. (Image source:\nWei et al, 2018\n)\nInterestingly, there exist a couple of artificial cues in the dataset. If not handled properly, they could lead to a trivial classifier without relying on the actual video content:\nDue to the video compression, the black framing might not be completely black but instead may contain certain information on the chronological order. Hence black framing should be removed in the experiments.\nLarge camera motion, like vertical translation or zoom-in/out, also provides strong signals for the arrow of time but independent of content. The processing stage should stabilize the camera motion.\nThe AoT pretext task is shown to improve the performance on action classification downstream task when used as a pretraining step. Note that fine-tuning is still needed.\nVideo Colorization\n#\nVondrick et al. (2018)\nproposed\nvideo colorization\nas a self-supervised learning problem, resulting in a rich representation that can be used for video segmentation and unlabelled visual region tracking,\nwithout extra fine-tuning\n.\nUnlike the image-based\ncolorization\n, here the task is to copy colors from a normal reference frame in color to another target frame in grayscale by leveraging the natural temporal coherency of colors across video frames (thus these two frames shouldn’t be too far apart in time). In order to copy colors consistently, the model is designed to learn to keep track of correlated pixels in different frames.\nVideo colorization by copying colors from a reference frame to target frames in grayscale.  (Image source:\nVondrick et al. 2018\n)\nThe idea is quite simple and smart. Let $c_i$ be the true color of the $i-th$ pixel in the reference frame and $c_j$ be the color of $j$-th pixel in the target frame. The predicted color of $j$-th color in the target $\\hat{c}_j$ is a weighted sum of colors of all the pixels in reference, where the weighting term measures the similarity:\n$$\n\\hat{c}_j = \\sum_i A_{ij} c_i \\text{ where } A_{ij} = \\frac{\\exp(f_i f_j)}{\\sum_{i'} \\exp(f_{i'} f_j)}\n$$\nwhere $f$ are learned embeddings for corresponding pixels; $i’$ indexes all the pixels in the reference frame. The weighting term implements an attention-based pointing mechanism, similar to\nmatching network\nand\npointer network\n. As the full similarity matrix could be really large, both frames are downsampled. The categorical cross-entropy loss between $c_j$ and $\\hat{c}_j$ is used with quantized colors, just like in\nZhang et al. 2016\n.\nBased on how the reference frame are marked, the model can be used to complete several color-based downstream tasks such as tracking segmentation or human pose in time. No fine-tuning is needed. See\nUse video colorization to track object segmentation and human pose in time. (Image source:\nVondrick et al. (2018)\n)\nA couple common observations:\nCombining multiple pretext tasks improves performance;\nDeeper networks improve the quality of representation;\nSupervised learning baselines still beat all of them by far.\nControl-Based\n#\nWhen running a RL policy in the real world, such as controlling a physical robot on visual inputs, it is non-trivial to properly track states, obtain reward signals or determine whether a goal is achieved for real. The visual data has a lot of noise that is irrelevant to the true state and thus the equivalence of states cannot be inferred from pixel-level comparison. Self-supervised representation learning has shown great potential in learning useful state embedding that can be used directly as input to a control policy.\nAll the cases discussed in this section are in robotic learning, mainly for state representation from multiple camera views and goal representation.\nMulti-View Metric Learning\n#\nThe concept of metric learning has been mentioned multiple times in the\nprevious\nsections\n. A common setting is: Given a triple of samples, (\nanchor\n$s_a$,\npositive\nsample $s_p$,\nnegative\nsample $s_n$), the learned representation embedding $\\phi(s)$ fulfills that $s_a$ stays close to $s_p$ but far away from $s_n$ in the latent space.\nGrasp2Vec\n(\nJang & Devin et al., 2018\n) aims to learn an object-centric vision representation in the robot grasping task from free, unlabelled grasping activities. By object-centric, it means that, irrespective of how the environment or the robot looks like, if two images contain similar items, they should be mapped to similar representation; otherwise the embeddings should be far apart.\nA conceptual illustration of how grasp2vec learns an object-centric state embedding. (Image source:\nJang & Devin et al., 2018\n)\nThe grasping system can tell whether it moves an object but cannot tell which object it is. Cameras are set up to take images of the entire scene and the grasped object. During early training, the grasp robot is executed to grasp any object $o$ at random, producing a triple of images, $(s_\\text{pre}, s_\\text{post}, o)$:\n$o$ is an image of the grasped object held up to the camera;\n$s_\\text{pre}$ is an image of the scene\nbefore\ngrasping, with the object $o$ in the tray;\n$s_\\text{post}$ is an image of the same scene\nafter\ngrasping, without the object $o$ in the tray.\nTo learn object-centric representation, we expect the difference between embeddings of $s_\\text{pre}$ and $s_\\text{post}$ to capture the removed object $o$. The idea is quite interesting and similar to relationships that have been observed in\nword embedding\n,\ne.g.\ndistance(“king”, “queen”) ≈ distance(“man”, “woman”).\nLet $\\phi_s$ and $\\phi_o$ be the embedding functions for the scene and the object respectively. The model learns the representation by minimizing the distance between $\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})$ and $\\phi_o(o)$ using\nn-pair loss\n:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{grasp2vec} &= \\text{NPair}(\\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post}), \\phi_o(o)) + \\text{NPair}(\\phi_o(o), \\phi_s(s_\\text{pre}) - \\phi_s(s_\\text{post})) \\\\\n\\text{where }\\text{NPair}(a, p) &= \\sum_{i<{B}} -\\log\\frac{\\exp(a_i^\\top p_j)}{\\sum_{j<{B}, i\\neq j}\\exp(a_i^\\top p_j)} + \\lambda (\\|a_i\\|_2^2 + \\|p_i\\|_2^2)\n\\end{aligned}\n$$\nwhere $B$ refers to a batch of (anchor, positive) sample pairs.\nWhen framing representation learning as metric learning,\nn-pair loss\nis a common choice. Rather than processing explicit a triple of (anchor, positive, negative) samples, the n-pairs loss treats all other positive instances in one mini-batch across pairs as negatives.\nThe embedding function $\\phi_o$ works great for presenting a goal $g$ with an image. The reward function that quantifies how close the actually grasped object $o$ is close to the goal is defined as $r = \\phi_o(g) \\cdot \\phi_o(o)$. Note that computing rewards only relies on the learned latent space and doesn’t involve ground truth positions, so it can be used for training on real robots.\nLocalization results of grasp2vec embedding. The heatmap of localizing a goal object in a pre-grasping scene is defined as $\\phi\\_o(o)^\\top \\phi\\_{s, \\text{spatial}} (s\\_\\text{pre})$, where $\\phi\\_{s, \\text{spatial}}$ is the output of the last resnet block after ReLU. The fourth column is a failure case and the last three columns take real images as goals. (Image source:\nJang & Devin et al., 2018\n)\nOther than the embedding-similarity-based reward function, there are a few other tricks for training the RL policy in the grasp2vec framework:\nPosthoc labeling\n: Augment the dataset by labeling a randomly grasped object as a correct goal, like HER (Hindsight Experience Replay;\nAndrychowicz, et al., 2017\n).\nAuxiliary goal augmentation\n: Augment the replay buffer even further by relabeling transitions with unachieved goals; precisely, in each iteration, two goals are sampled $(g, g’)$ and both are used to add new transitions into replay buffer.\nTCN\n(\nTime-Contrastive Networks\n;\nSermanet, et al. 2018\n) learn from multi-camera view videos with the intuition that different viewpoints at the same timestep of the same scene should share the same embedding (like in\nFaceNet\n) while embedding should vary in time, even of the same camera viewpoint. Therefore embedding captures the semantic meaning of the underlying state rather than visual similarity. The TCN embedding is trained with\ntriplet loss\n.\nThe training data is collected by taking videos of the same scene simultaneously but from different angles. All the videos are unlabelled.\nAn illustration of time-contrastive approach for learning state embedding. The blue frames selected from two camera views at the same timestep are anchor and positive samples, while the red frame at a different timestep is the negative sample.\nTCN embedding extracts visual features that are invariant to camera configurations. It can be used to construct a reward function for imitation learning based on the euclidean distance between the demo video and the observations in the latent space.\nA further improvement over TCN is to learn embedding over multiple frames jointly rather than a single frame, resulting in\nmfTCN\n(\nMulti-frame\nTime-Contrastive Networks\n;\nDwibedi et al., 2019\n). Given a set of videos from several synchronized camera viewpoints, $v_1, v_2, \\dots, v_k$, the frame at time $t$ and the previous $n-1$ frames selected with stride $s$ in each video are aggregated and mapped into one embedding vector, resulting in a lookback window of size $(n−1) \\times s + 1$. Each frame first goes through a CNN to extract low-level features and then we use 3D temporal convolutions to aggregate frames in time. The model is trained with\nn-pairs loss\n.\nThe sampling process for training mfTCN. (Image source:\nDwibedi et al., 2019\n)\nThe training data is sampled as follows:\nFirst we construct two pairs of video clips. Each pair contains two clips from different camera views but with synchronized timesteps. These two sets of videos should be far apart in time.\nSample a fixed number of frames from each video clip in the same pair simultaneously with the same stride.\nFrames with the same timesteps are trained as positive samples in the n-pair loss, while frames across pairs are negative samples.\nmfTCN embedding can capture the position and velocity of objects in the scene (e.g. in cartpole) and can also be used as inputs for policy.\nAutonomous Goal Generation\n#\nRIG\n(\nReinforcement learning with\nImagined Goals\n;\nNair et al., 2018\n) described a way to train a goal-conditioned policy with unsupervised representation learning. A policy learns from self-supervised practice by first imagining “fake” goals and then trying to achieve them.\nThe workflow of RIG. (Image source:\nNair et al., 2018\n)\nThe task is to control a robot arm to push a small puck on a table to a desired position. The desired position, or the goal, is present in an image. During training, it learns latent embedding of both state $s$ and goal $g$ through $\\beta$-VAE encoder and the control policy operates entirely in the latent space.\nLet’s say a\n$\\beta$-VAE\nhas an encoder $q_\\phi$ mapping input states to latent variable $z$ which is modeled by a Gaussian distribution and a decoder $p_\\psi$ mapping $z$ back to the states. The state encoder in RIG is set to be the mean of $\\beta$-VAE encoder.\n$$\n\\begin{aligned}\nz &\\sim q_\\phi(z \\vert s) = \\mathcal{N}(z; \\mu_\\phi(s), \\sigma^2_\\phi(s)) \\\\\n\\mathcal{L}_{\\beta\\text{-VAE}} &= - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s)} [\\log p_\\psi (s \\vert z)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s) \\| p_\\psi(s)) \\\\\ne(s) &\\triangleq \\mu_\\phi(s)\n\\end{aligned}\n$$\nThe reward is the Euclidean distance between state and goal embedding vectors: $r(s, g) = -|e(s) - e(g)|$. Similar to\ngrasp2vec\n, RIG applies data augmentation as well by latent goal relabeling: precisely half of the goals are generated from the prior at random and the other half are selected using HER. Also same as grasp2vec, rewards do not depend on any ground truth states but only the learned state encoding, so it can be used for training on real robots.\nThe algorithm of RIG. (Image source:\nNair et al., 2018\n)\nThe problem with RIG is a lack of object variations in the imagined goal pictures. If $\\beta$-VAE is only trained with a black puck, it would not be able to create a goal with other objects like blocks of different shapes and colors. A follow-up improvement replaces $\\beta$-VAE with a\nCC-VAE\n(Context-Conditioned VAE;\nNair, et al., 2019\n), inspired by\nCVAE\n(Conditional VAE;\nSohn, Lee & Yan, 2015\n), for goal generation.\nThe workflow of context-conditioned RIG. (Image source:\nNair, et al., 2019\n).\nA CVAE conditions on a context variable $c$. It trains an encoder $q_\\phi(z \\vert s, c)$ and a decoder $p_\\psi (s \\vert z, c)$ and note that both have access to $c$. The CVAE loss penalizes information passing from the input state $s$ through an information bottleneck but allows for\nunrestricted\ninformation flow from $c$ to both encoder and decoder.\n$$\n\\mathcal{L}_\\text{CVAE} = - \\mathbb{E}_{z \\sim q_\\phi(z \\vert s,c)} [\\log p_\\psi (s \\vert z, c)] + \\beta D_\\text{KL}(q_\\phi(z \\vert s, c) \\| p_\\psi(s))\n$$\nTo create plausible goals, CC-VAE conditions on a starting state $s_0$ so that the generated goal presents a consistent type of object as in $s_0$. This goal consistency is necessary; e.g. if the current scene contains a red puck but the goal has a blue block, it would confuse the policy.\nOther than the state encoder $e(s) \\triangleq \\mu_\\phi(s)$, CC-VAE trains a second convolutional encoder $e_0(.)$ to translate the starting state $s_0$ into a compact context representation $c = e_0(s_0)$. Two encoders, $e(.)$ and $e_0(.)$, are intentionally different without shared weights, as they are expected to encode different factors of image variation. In addition to the loss function of CVAE, CC-VAE adds an extra term to learn to reconstruct $c$ back to $s_0$, $\\hat{s}_0 = d_0(c)$.\n$$\n\\mathcal{L}_\\text{CC-VAE} = \\mathcal{L}_\\text{CVAE} + \\log p(s_0\\vert c)\n$$\nExamples of imagined goals generated by CVAE that conditions on the context image (the first row), while VAE fails to capture the object consistency. (Image source:\nNair, et al., 2019\n).\nBisimulation\n#\nTask-agnostic representation (e.g. a model that intends to represent all the dynamics in the system) may distract the RL algorithms as irrelevant information is also presented. For example, if we just train an auto-encoder to reconstruct the input image, there is no guarantee that the entire learned representation will be useful for RL. Therefore, we need to move away from reconstruction-based representation learning if we only want to learn information relevant to control, as irrelevant details are still important for reconstruction.\nRepresentation learning for control based on bisimulation does not depend on reconstruction, but aims to group states based on their behavioral similarity in MDP.\nBisimulation\n(\nGivan et al. 2003\n) refers to an equivalence relation between two states with similar long-term behavior.\nBisimulation metrics\nquantify such relation so that we can aggregate states to compress a high-dimensional state space into a smaller one for more efficient computation. The\nbisimulation distance\nbetween two states corresponds to how behaviorally different these two states are.\nGiven a\nMDP\n$\\mathcal{M} = \\langle \\mathcal{S}, \\mathcal{A}, \\mathcal{P}, \\mathcal{R}, \\gamma \\rangle$ and a bisimulation relation $B$, two states that are equal under relation $B$ (i.e. $s_i B s_j$) should have the same immediate reward for all actions and the same transition probabilities over the next bisimilar states:\n$$\n\\begin{aligned}\n\\mathcal{R}(s_i, a) &= \\mathcal{R}(s_j, a) \\; \\forall a \\in \\mathcal{A} \\\\\n\\mathcal{P}(G \\vert s_i, a) &= \\mathcal{P}(G \\vert s_j, a) \\; \\forall a \\in \\mathcal{A} \\; \\forall G \\in \\mathcal{S}_B\n\\end{aligned}\n$$\nwhere $\\mathcal{S}_B$ is a partition of the state space under the relation $B$.\nNote that $=$ is always a bisimulation relation. The most interesting one is the maximal bisimulation relation $\\sim$, which defines a partition $\\mathcal{S}_\\sim$ with\nfewest\ngroups of states.\nDeepMDP learns a latent space model by minimizing two losses on a reward model and a dynamics model. (Image source:\nGelada, et al. 2019\n)\nWith a goal similar to bisimulation metric,\nDeepMDP\n(\nGelada, et al. 2019\n) simplifies high-dimensional observations in RL tasks and learns a latent space model via minimizing two losses:\nprediction of rewards and\nprediction of the distribution over next latent states.\n$$\n\\begin{aligned}\n\\mathcal{L}_{\\bar{\\mathcal{R}}}(s, a) = \\vert \\mathcal{R}(s, a) - \\bar{\\mathcal{R}}(\\phi(s), a) \\vert \\\\\n\\mathcal{L}_{\\bar{\\mathcal{P}}}(s, a) = D(\\phi \\mathcal{P}(s, a), \\bar{\\mathcal{P}}(. \\vert \\phi(s), a))\n\\end{aligned}\n$$\nwhere $\\phi(s)$ is the embedding of state $s$; symbols with bar are functions (reward function $R$ and transition function $P$) in the same MDP but running in the latent low-dimensional observation space. Here the embedding representation $\\phi$ can be connected to bisimulation metrics, as the bisimulation distance is proved to be upper-bounded by the L2 distance in the latent space.\nThe function $D$ quantifies the distance between two probability distributions and should be chosen carefully. DeepMDP focuses on\nWasserstein-1\nmetric (also known as\n“earth-mover distance”\n). The Wasserstein-1 distance between distributions $P$ and $Q$ on a metric space $(M, d)$ (i.e., $d: M \\times M \\to \\mathbb{R}$) is:\n$$\nW_d (P, Q) = \\inf_{\\lambda \\in \\Pi(P, Q)} \\int_{M \\times M} d(x, y) \\lambda(x, y) \\; \\mathrm{d}x \\mathrm{d}y\n$$\nwhere $\\Pi(P, Q)$ is the set of all\ncouplings\nof $P$ and $Q$. $d(x, y)$ defines the cost of moving a particle from point $x$ to point $y$.\nThe Wasserstein metric has a dual form according to the Monge-Kantorovich duality:\n$$\nW_d (P, Q) = \\sup_{f \\in \\mathcal{F}_d} \\vert \\mathbb{E}_{x \\sim P} f(x) - \\mathbb{E}_{y \\sim Q} f(y) \\vert\n$$\nwhere $\\mathcal{F}_d$ is the set of 1-Lipschitz functions under the metric $d$ - $\\mathcal{F}_d = \\{ f: \\vert f(x) - f(y) \\vert \\leq d(x, y) \\}$.\nDeepMDP generalizes the model to the Norm Maximum Mean Discrepancy (Norm-\nMMD\n) metrics to improve the tightness of the bounds of its deep value function and, at the same time, to save computation (Wasserstein is expensive computationally). In their experiments, they found the model architecture of the transition prediction model can have a big impact on the performance. Adding these DeepMDP losses as auxiliary losses when training model-free RL agents leads to good improvement on most of the Atari games.\nDeep Bisimulatioin for Control\n(short for\nDBC\n;\nZhang et al. 2020\n) learns the latent representation of observations that are good for control in RL tasks, without domain knowledge or pixel-level reconstruction.\nThe Deep Bisimulation for Control algorithm learns a bisimulation metric representation via learning a reward model and a dynamics model. The model architecture is a siamese network. (Image source:\nZhang et al. 2020\n)\nSimilar to DeepMDP, DBC models the dynamics by learning a reward model and a transition model. Both models operate in the latent space, $\\phi(s)$. The optimization of embedding $\\phi$ depends on one important conclusion from\nFerns, et al. 2004\n(Theorem 4.5) and\nFerns, et al 2011\n(Theorem 2.6):\nGiven $c \\in (0, 1)$ a discounting factor, $\\pi$ a policy that is being improved continuously, and $M$ the space of bounded\npseudometric\non the state space $\\mathcal{S}$, we can define $\\mathcal{F}: M \\mapsto M$:\n$$\n\\mathcal{F}(d; \\pi)(s_i, s_j) = (1-c) \\vert \\mathcal{R}_{s_i}^\\pi - \\mathcal{R}_{s_j}^\\pi \\vert + c W_d (\\mathcal{P}_{s_i}^\\pi, \\mathcal{P}_{s_j}^\\pi)\n$$\nThen, $\\mathcal{F}$ has a unique fixed point $\\tilde{d}$ which is a $\\pi^*$-bisimulation metric and $\\tilde{d}(s_i, s_j) = 0 \\iff s_i \\sim s_j$.\n[The proof is not trivial. I may or may not add it in the future  _(:3」∠)_ …]\nGiven batches of observations pairs, the training loss for $\\phi$, $J(\\phi)$, minimizes the mean square error between the on-policy bisimulation metric and Euclidean distance in the latent space:\n$$\nJ(\\phi) = \\Big( \\|\\phi(s_i) - \\phi(s_j)\\|_1 - \\vert \\hat{\\mathcal{R}}(\\bar{\\phi}(s_i)) - \\hat{\\mathcal{R}}(\\bar{\\phi}(s_j)) \\vert - \\gamma W_2(\\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_i), \\bar{\\pi}(\\bar{\\phi}(s_i))), \\hat{\\mathcal{P}}(\\cdot \\vert \\bar{\\phi}(s_j), \\bar{\\pi}(\\bar{\\phi}(s_j)))) \\Big)^2\n$$\nwhere $\\bar{\\phi}(s)$ denotes $\\phi(s)$ with stop gradient and $\\bar{\\pi}$ is the mean policy output. The learned reward model $\\hat{\\mathcal{R}}$ is deterministic and the learned forward dynamics model $\\hat{\\mathcal{P}}$ outputs a Gaussian distribution.\nDBC is based on SAC but operates on the latent space:\nThe algorithm of Deep Bisimulation for Control. (Image source:\nZhang et al. 2020\n)\nCited as:\n@article{weng2019selfsup,\n  title   = \"Self-Supervised Representation Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-11-10-self-supervised/\"\n}\nReferences\n#\n[1] Alexey Dosovitskiy, et al.\n“Discriminative unsupervised feature learning with exemplar convolutional neural networks.”\nIEEE transactions on pattern analysis and machine intelligence 38.9 (2015): 1734-1747.\n[2] Spyros Gidaris, Praveer Singh & Nikos Komodakis.\n“Unsupervised Representation Learning by Predicting Image Rotations”\nICLR 2018.\n[3] Carl Doersch, Abhinav Gupta, and Alexei A. Efros.\n“Unsupervised visual representation learning by context prediction.”\nICCV. 2015.\n[4] Mehdi Noroozi & Paolo Favaro.\n“Unsupervised learning of visual representations by solving jigsaw puzzles.”\nECCV, 2016.\n[5] Mehdi Noroozi, Hamed Pirsiavash, and Paolo Favaro.\n“Representation learning by learning to count.”\nICCV. 2017.\n[6] Richard Zhang, Phillip Isola & Alexei A. Efros.\n“Colorful image colorization.”\nECCV, 2016.\n[7] Pascal Vincent, et al.\n“Extracting and composing robust features with denoising autoencoders.”\nICML, 2008.\n[8] Jeff Donahue, Philipp Krähenbühl, and Trevor Darrell.\n“Adversarial feature learning.”\nICLR 2017.\n[9] Deepak Pathak, et al.\n“Context encoders: Feature learning by inpainting.”\nCVPR. 2016.\n[10] Richard Zhang, Phillip Isola, and Alexei A. Efros.\n“Split-brain autoencoders: Unsupervised learning by cross-channel prediction.”\nCVPR. 2017.\n[11] Xiaolong Wang & Abhinav Gupta.\n“Unsupervised Learning of Visual Representations using Videos.”\nICCV. 2015.\n[12] Carl Vondrick, et al.\n“Tracking Emerges by Colorizing Videos”\nECCV. 2018.\n[13] Ishan Misra, C. Lawrence Zitnick, and Martial Hebert.\n“Shuffle and learn: unsupervised learning using temporal order verification.”\nECCV. 2016.\n[14] Basura Fernando, et al.\n“Self-Supervised Video Representation Learning With Odd-One-Out Networks”\nCVPR. 2017.\n[15] Donglai Wei, et al.\n“Learning and Using the Arrow of Time”\nCVPR. 2018.\n[16] Florian Schroff, Dmitry Kalenichenko and James Philbin.\n“FaceNet: A Unified Embedding for Face Recognition and Clustering”\nCVPR. 2015.\n[17] Pierre Sermanet, et al.\n“Time-Contrastive Networks: Self-Supervised Learning from Video”\nCVPR. 2018.\n[18] Debidatta Dwibedi, et al.\n“Learning actionable representations from visual observations.”\nIROS. 2018.\n[19] Eric Jang & Coline Devin, et al.\n“Grasp2Vec: Learning Object Representations from Self-Supervised Grasping”\nCoRL. 2018.\n[20] Ashvin Nair, et al.\n“Visual reinforcement learning with imagined goals”\nNeuriPS. 2018.\n[21] Ashvin Nair, et al.\n“Contextual imagined goals for self-supervised robotic learning”\nCoRL. 2019.\n[22] Aaron van den Oord, Yazhe Li & Oriol Vinyals.\n“Representation Learning with Contrastive Predictive Coding”\narXiv preprint arXiv:1807.03748, 2018.\n[23] Olivier J. Henaff, et al.\n“Data-Efficient Image Recognition with Contrastive Predictive Coding”\narXiv preprint arXiv:1905.09272, 2019.\n[24] Kaiming He, et al.\n“Momentum Contrast for Unsupervised Visual Representation Learning.”\nCVPR 2020.\n[25] Zhirong Wu, et al.\n“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”\nCVPR 2018.\n[26] Ting Chen, et al.\n“A Simple Framework for Contrastive Learning of Visual Representations.”\narXiv preprint arXiv:2002.05709, 2020.\n[27] Aravind Srinivas, Michael Laskin & Pieter Abbeel\n“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”\narXiv preprint arXiv:2004.04136, 2020.\n[28] Carles Gelada, et al.\n“DeepMDP: Learning Continuous Latent Space Models for Representation Learning”\nICML 2019.\n[29] Amy Zhang, et al.\n“Learning Invariant Representations for Reinforcement Learning without Reconstruction”\narXiv preprint arXiv:2006.10742, 2020.\n[30] Xinlei Chen, et al.\n“Improved Baselines with Momentum Contrastive Learning”\narXiv preprint arXiv:2003.04297, 2020.\n[31] Jean-Bastien Grill, et al.\n“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”\narXiv preprint arXiv:2006.07733, 2020.\n[32] Abe Fetterman & Josh Albrecht.\n“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”\nUntitled blog. Aug 24, 2020.",
            "metadata": {
              "title": "Self-Supervised Representation Learning | Lil'Log",
              "description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "keywords": "representation-learning, long-read, generative-model, object-recognition, reinforcement-learning, unsupervised-learning",
              "author": "Lilian Weng",
              "og:title": "Self-Supervised Representation Learning",
              "og:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
              "og:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:card": "summary_large_image",
              "twitter:image": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
              "twitter:title": "Self-Supervised Representation Learning",
              "twitter:description": "[Updated on 2020-01-09: add a new section on Contrastive Predictive Coding].\n\n[Updated on 2020-04-13: add a “Momentum Contrast” section on MoCo, SimCLR and CURL.]\n\n[Updated on 2020-07-08: add a “Bisimulation” section on DeepMDP and DBC.]\n\n[Updated on 2020-09-12: add MoCo V2 and BYOL in the “Momentum Contrast” section.]\n\n[Updated on 2021-05-31: remove section on “Momentum Contrast” and add a pointer to a full post on “Contrastive Representation Learning”]",
              "article:section": "posts",
              "article:published_time": "2019-11-10T00:00:00+00:00",
              "article:modified_time": "2019-11-10T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bf0a610ccb4a/code/body-000.txt",
                "chars": 244,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "bytes": 513885,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f359d38ab20e9cdac179.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-lecun.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "bytes": 1270278,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-8d6f8ad7272758de8c53.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/examplar-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "bytes": 768852,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7c81aafa4666fddd3762.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-rotation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "bytes": 2642257,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c64df87fedc22e7713a8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-by-relative-position.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "bytes": 249192,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-d72676a1e2d7d681665b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/chromatic-aberration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "bytes": 737673,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-284f09a3dc26a2be2be6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-jigsaw-puzzle.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "bytes": 1162740,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-574c20fa1107bf61368d.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/self-sup-counting-features.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "bytes": 566411,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-817ed503b242a7831692.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/context-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "bytes": 103291,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-26dfcda8fac62755a0e6.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/split-brain-autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "bytes": 225014,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-a7ef42a592f8d64c0933.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/bi-GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "bytes": 267029,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-38455ea040ea0eae9625.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-audio.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "bytes": 163908,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-2f0fc009f289b69c8d79.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CPC-image.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "bytes": 1281590,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e3a5248959b284127268.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/tracking-videos.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "bytes": 1411892,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-316474d8ca427819890a.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/frame-order-validation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "bytes": 218384,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7dd458cefc09c96c4325.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/learning-arrow-of-time.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "bytes": 135102,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-70000ddd170ac7e5840b.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "bytes": 2011971,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ae4b346db197ccab2cfe.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/video-colorization-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "bytes": 157839,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-1da73a82998c80ae17c9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "bytes": 1115258,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-976ef652676b26b5a203.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/grasp2vec-attention-map.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "bytes": 1886891,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-f8bf05d0018c01caf352.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/TCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "bytes": 2352713,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-dee16f2c447f7c91e79e.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/mfTCN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "bytes": 917157,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-7de401f88063093a58d8.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "bytes": 391776,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-ce13a8280e64dce3dbf1.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/RIG-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "bytes": 1753636,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c37fd073afd7cb9698fa.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "bytes": 1839222,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-e113f6beb0962c59d170.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/CC-RIG-goal-samples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "bytes": 164404,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-c9ea48204e2765c959ab.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DeepMDP.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "bytes": 388169,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-139471e0d9b6eef5fde9.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "bytes": 350225,
                "reused": false,
                "local_path": "attachments/bf0a610ccb4a/images/body-211c4ab593d56ae944a3.png",
                "src": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/DBC-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "src": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "status": "no_1080_or_720",
                "kind": "single_video",
                "error": "ERROR: [youtube] 7I0Qt7GALVk: Requested format is not available. Use --list-formats for a list of available formats\n",
                "title": "",
                "retried_at": "2026-10-20T17:59:07Z"
              }
            ],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "MoCo V2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/watch?v=7I0Qt7GALVk",
                "label": "LeCun’s talk",
                "type": "a"
              },
              {
                "href": "https://github.com/jason718/awesome-self-supervised-learning",
                "label": "Here",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/tags/generative-model/",
                "label": "generative modeling",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.03670",
                "label": "Zhai et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11825",
                "label": "Sun et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1406.6909",
                "label": "Dosovitskiy et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.07728",
                "label": "Gidaris et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05192",
                "label": "Doersch et al. (2015)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Chromatic_aberration",
                "label": "“chromatic aberration”",
                "type": "a"
              },
              {
                "href": "https://upload.wikimedia.org/wikipedia/commons/a/aa/Chromatic_aberration_lens_diagram.svg",
                "label": "wikipedia",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.09246",
                "label": "Noroozi & Favaro (2016)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00025",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.06734",
                "label": "Noroozi, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08511",
                "label": "Zhang et al. 2016",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CIELAB_color_space",
                "label": "CIE L a b* color space",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "tf and idf",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "label": "Vincent, et al, 2008",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "old post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.07379",
                "label": "Pathak, et al., 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.09842",
                "label": "Zhang et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "Radford et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.09782",
                "label": "Donahue, et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03748",
                "label": "van den Oord, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Noise Contrastive Estimation (NCE)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.09272",
                "label": "Henaff, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.00687",
                "label": "Wang & Gupta, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1503.03832",
                "label": "triplet loss",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/6200-improved-deep-metric-learning-with-multi-class-n-pair-loss-objective",
                "label": "n-pair loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Optical_flow",
                "label": "optical flow",
                "type": "a"
              },
              {
                "href": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "label": "SURF",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/hal-00873267v2/document",
                "label": "IDT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.08561",
                "label": "Misra, et al 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.06646",
                "label": "Fernando et al. 2017",
                "type": "a"
              },
              {
                "href": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "label": "Wei et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09594",
                "label": "Vondrick et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "matching network",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "pointer network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06964",
                "label": "Jang & Devin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://developers.google.com/machine-learning/crash-course/embeddings/translating-to-a-lower-dimensional-space",
                "label": "e.g.",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "label": "Andrychowicz, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.06888",
                "label": "Sermanet, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00928",
                "label": "Dwibedi et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.04742",
                "label": "Nair et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.11670",
                "label": "Nair, et al., 2019",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5775-learning-structured-output-representation-using-deep-conditional-generative-models",
                "label": "Sohn, Lee & Yan, 2015",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.61.2493&rep=rep1&type=pdf",
                "label": "Givan et al. 2003",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "MDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.02736",
                "label": "Gelada, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coupling_(probability)",
                "label": "couplings",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_embedding_of_distributions",
                "label": "MMD",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.10742",
                "label": "Zhang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1207.4114",
                "label": "Ferns, et al. 2004",
                "type": "a"
              },
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.295.2114&rep=rep1&type=pdf",
                "label": "Ferns, et al 2011",
                "type": "a"
              },
              {
                "href": "https://mathworld.wolfram.com/Pseudometric.html",
                "label": "pseudometric",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1806.09594.pdf",
                "label": "“Tracking Emerges by Colorizing Videos”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05722",
                "label": "“Momentum Contrast for Unsupervised Visual Representation Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.01978v1",
                "label": "“Unsupervised Feature Learning via Non-Parametric Instance-level Discrimination.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.05709",
                "label": "“A Simple Framework for Contrastive Learning of Visual Representations.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04136",
                "label": "“CURL: Contrastive Unsupervised Representations for Reinforcement Learning.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.04297",
                "label": "“Improved Baselines with Momentum Contrastive Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.07733",
                "label": "“Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”",
                "type": "a"
              },
              {
                "href": "https://untitled-ai.github.io/understanding-self-supervised-contrastive-learning.html",
                "label": "“Understanding self-supervised and contrastive learning with Bootstrap Your Own Latent (BYOL)”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:35Z",
            "source_url": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.03670",
                "bytes": 933247,
                "reused": false,
                "local_path": "papers/repair/687ecfe304e8db4ee6a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11825",
                "bytes": 1510344,
                "reused": false,
                "local_path": "papers/repair/abe216f7fcd57c5bf090.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.6909",
                "bytes": 1208023,
                "reused": false,
                "local_path": "papers/repair/02461cd2b74a44803bcb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.07728",
                "bytes": 2524968,
                "reused": false,
                "local_path": "papers/repair/09768e0dd5ddaf3f5115.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05192",
                "bytes": 3688221,
                "reused": false,
                "local_path": "papers/repair/8660d67d6d9beb2f409e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.09246",
                "bytes": 7884325,
                "reused": false,
                "local_path": "papers/repair/3fad0ba70064de418e86.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00025",
                "bytes": 915177,
                "reused": false,
                "local_path": "papers/repair/e965789a54661a85f29b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.06734",
                "bytes": 4282240,
                "reused": false,
                "local_path": "papers/repair/9041a39543be512b895f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08511",
                "bytes": 8866382,
                "reused": false,
                "local_path": "papers/repair/adde21ae45e292b51011.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf",
                "bytes": 527511,
                "reused": false,
                "local_path": "papers/repair/afb5d72ab0895a64362a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.07379",
                "bytes": 9914955,
                "reused": false,
                "local_path": "papers/repair/24d4451e560641d4763c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.09842",
                "bytes": 2531668,
                "reused": false,
                "local_path": "papers/repair/20050e06cbfd43bbb68b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": true,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.09782",
                "bytes": 5938452,
                "reused": false,
                "local_path": "papers/repair/407a2bae3cb6f778a5c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03748",
                "bytes": 3182089,
                "reused": true,
                "local_path": "papers/repair/7ace1819f0b552bee2ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.09272",
                "bytes": 2411659,
                "reused": false,
                "local_path": "papers/repair/b9006248b176b4b194f1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.00687",
                "bytes": 3737012,
                "reused": false,
                "local_path": "papers/repair/3078161f1da978e0de72.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.03832",
                "bytes": 4705274,
                "reused": true,
                "local_path": "papers/repair/a71730a10b0aef666206.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.vision.ee.ethz.ch/~surf/eccv06.pdf",
                "bytes": 723370,
                "reused": false,
                "local_path": "papers/repair/780b0a793aeb990a3f71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.08561",
                "bytes": 2615687,
                "reused": false,
                "local_path": "papers/repair/1d251b8fc37ee017f4bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.06646",
                "bytes": 7497944,
                "reused": false,
                "local_path": "papers/repair/739b5e4d4e24134d409b.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.robots.ox.ac.uk/~vgg/publications/2018/Wei18/wei18.pdf",
                "bytes": 1011708,
                "reused": false,
                "local_path": "papers/repair/afdd1eb32a82a2145ccc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/643dffc114da13aa653b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06964",
                "bytes": 6707774,
                "reused": false,
                "local_path": "papers/repair/fa128df9eb0f1f235ebb.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/7090-hindsight-experience-replay.pdf",
                "bytes": 2040774,
                "reused": false,
                "local_path": "papers/repair/d153f5fcbc7ada7f48f2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.06888",
                "bytes": 9504974,
                "reused": false,
                "local_path": "papers/repair/2b339f780c6bfb664948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00928",
                "bytes": 1382430,
                "reused": false,
                "local_path": "papers/repair/a8b22a546f22c92d1a5c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.04742",
                "bytes": 9328088,
                "reused": false,
                "local_path": "papers/repair/509c62da689529aeb058.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.11670",
                "bytes": 2075834,
                "reused": false,
                "local_path": "papers/repair/909f08f6590adde49f8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.02736",
                "bytes": 8541253,
                "reused": false,
                "local_path": "papers/repair/04f92d456ed7ee16b0e3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.10742",
                "bytes": 5605228,
                "reused": false,
                "local_path": "papers/repair/1f176920cb7853662844.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1207.4114",
                "bytes": 386038,
                "reused": false,
                "local_path": "papers/repair/b3516a025350622055b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09594.pdf",
                "bytes": 1964458,
                "reused": false,
                "local_path": "papers/repair/591acb652d41fe6382d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05722",
                "bytes": 593470,
                "reused": true,
                "local_path": "papers/repair/5c3c001fd908f6dae2c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.01978v1",
                "bytes": 4452342,
                "reused": true,
                "local_path": "papers/repair/e90b74cda724c45827a6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.05709",
                "bytes": 6564895,
                "reused": true,
                "local_path": "papers/repair/702dc85ba981458cb06f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04136",
                "bytes": 4108339,
                "reused": true,
                "local_path": "papers/repair/c9a2ff8f5b0e5380a701.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.04297",
                "bytes": 262792,
                "reused": true,
                "local_path": "papers/repair/43fc2eaa495db084a96e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.07733",
                "bytes": 4837213,
                "reused": true,
                "local_path": "papers/repair/7c03b7b76959caf6d3ab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53089,
            "expected_body_images": 28,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "no_1080_or_720",
            "raw_html": "attachments/bf0a610ccb4a/pages/source.html",
            "local_html": "attachments/bf0a610ccb4a/pages/article.html",
            "body_base_path": "attachments/bf0a610ccb4a/pages/",
            "body_markdown_path": "attachments/bf0a610ccb4a/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
          "status": "partial",
          "article_id": "3e47ba682561",
          "local_path": "series-follow/1601/repair/f7460f9330e723bf3e4f.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
              "bytes": 179202,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e21a214c6127867b9495.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
              "bytes": 183003,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0f5bdb5a435b843e8180.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
              "bytes": 18594,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f369233bacf831326935.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Learning Word Embedding",
            "keywords": "词嵌入,word2vec,GloVe",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "publish_date": "2017-10",
            "corpus_stage": "预训练/SFT",
            "notes": "词嵌入学习综述",
            "id": "3e47ba682561",
            "collected_at": "2026-10-02T14:13:32",
            "title": "Learning Word Embedding | Lil'Log",
            "body_markdown": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).\nHowever, one-hot encoding is impractical computationally when dealing with the entire vocabulary, as the representation demands hundreds of thousands of dimensions. Word embedding represents words and phrases in vectors of (non-binary) numeric values with much lower and thus denser dimensions. An intuitive assumption for good word embedding is that they can approximate the similarity between words (i.e., “cat” and “kitten” are similar words, and thus they are expected to be close in the reduced vector space) or disclose hidden semantic relationships (i.e., the relationship between “cat” and “kitten” is an analogy to the one between “dog” and “puppy”). Contextual information is super useful for learning word meaning and relationship, as similar words may appear in the similar context often.\nThere are two main approaches for learning word embedding, both relying on the contextual knowledge.\nCount-based\n: The first one is unsupervised, based on matrix factorization of a global word co-occurrence matrix. Raw co-occurrence counts do not work well, so we want to do smart things on top.\nContext-based\n: The second approach is supervised. Given a local context, we want to design a model to predict the target words and in the meantime, this model learns the efficient word embedding representation.\nCount-Based Vector Space Model\n#\nCount-based vector space models heavily rely on the word frequency and co-occurrence matrix with the assumption that words in the same contexts share similar or related semantic meanings. The models map count-based statistics like co-occurrences between neighboring words down to a small and dense word vectors. PCA, topic models, and neural probabilistic language models are all good examples of this category.\nDifferent from the count-based approaches, context-based methods build predictive models that directly target at predicting a word given its neighbors. The dense word vectors are part of the model parameters. The best vector representation of each word is learned during the model training process.\nContext-Based: Skip-Gram Model\n#\nSuppose that you have a sliding window of a fixed size moving along a sentence: the word in the middle is the “target” and those on its left and right within the sliding window are the context words. The skip-gram model (\nMikolov et al., 2013\n) is trained to predict the probabilities of a word being a context word for the given target.\nThe following example demonstrates multiple pairs of target and context words as training samples, generated by a 5-word window sliding along the sentence.\n“The man who passes the sentence should swing the sword.” – Ned Stark\nSliding window (size = 5)\nTarget word\nContext\n[The man who]\nthe\nman, who\n[The man who passes]\nman\nthe, who, passes\n[The man who passes the]\nwho\nthe, man, passes, the\n[man who passes the sentence]\npasses\nman, who, the, sentence\n…\n…\n…\n[sentence should swing the sword]\nswing\nsentence, should, the, sword\n[should swing the sword]\nthe\nshould, swing, sword\n[swing the sword]\nsword\nswing, the\n{:.info}\nEach context-target pair is treated as a new observation in the data. For example, the target word “swing” in the above case produces four training samples: (“swing”, “sentence”), (“swing”, “should”), (“swing”, “the”), and (“swing”, “sword”).\nThe skip-gram model. Both the input vector $\\mathbf{x}$ and the output $\\mathbf{y}$ are one-hot encoded word representations. The hidden layer is the word embedding of size $N$.\nGiven the vocabulary size $V$, we are about to learn word embedding vectors of size $N$. The model learns to predict one context word (output) using one target word (input) at a time.\nAccording to Fig. 1,\nBoth input word $w_i$ and the output word $w_j$ are one-hot encoded into binary vectors $\\mathbf{x}$ and $\\mathbf{y}$ of size $V$.\nFirst, the multiplication of the binary vector $\\mathbf{x}$ and the word embedding matrix $W$ of size $V \\times N$ gives us the embedding vector of the input word $w_i$: the i-th row of the matrix $W$.\nThis newly discovered embedding vector of dimension $N$ forms the hidden layer.\nThe multiplication of the hidden layer and the word context matrix $W’$ of size $N \\times V$ produces the output one-hot encoded vector $\\mathbf{y}$.\nThe output context matrix $W’$ encodes the meanings of words as context, different from the embedding matrix $W$. NOTE: Despite the name, $W’$ is independent of $W$, not a transpose or inverse or whatsoever.\nContext-Based: Continuous Bag-of-Words (CBOW)\n#\nThe Continuous Bag-of-Words (CBOW) is another similar model for learning word vectors. It predicts the target word (i.e. “swing”) from source context words (i.e., “sentence should the sword”).\nThe CBOW model. Word vectors of multiple context words are averaged to get a fixed-length vector as in the hidden layer. Other symbols have the same meanings as in Fig 1.\nBecause there are multiple contextual words, we average their corresponding word vectors, constructed by the multiplication of the input vector and the matrix $W$. Because the averaging stage smoothes over a lot of the distributional information, some people believe the CBOW model is better for small dataset.\nLoss Functions\n#\nBoth the skip-gram model and the CBOW model should be trained to minimize a well-designed loss/objective function. There are several loss functions we can incorporate to train these language models. In the following discussion, we will use the skip-gram model as an example to describe how the loss is computed.\nFull Softmax\n#\nThe skip-gram model defines the embedding vector of every word by the matrix $W$ and the context vector by the output matrix $W’$. Given an input word $w_I$, let us label the corresponding row of $W$ as vector $v_{w_I}$ (embedding vector) and its corresponding column of $W’$ as $v’_{w_I}$ (context vector). The final output layer applies softmax to compute the probability of predicting the output word $w_O$ given $w_I$, and therefore:\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nThis is accurate as presented in However, when $V$ is extremely large, calculating the denominator by going through all the words for every single sample is computationally impractical. The demand for more efficient conditional probability estimation leads to the new methods like\nhierarchical softmax\n.\nHierarchical Softmax\n#\nMorin and Bengio (\n2005\n) proposed hierarchical softmax to make the sum calculation faster with the help of a binary tree structure. The hierarchical softmax encodes the language model’s output softmax layer into a tree hierarchy, where each leaf is one word and each internal node stands for relative probabilities of the children nodes.\nAn illustration of the hierarchical softmax binary tree. The leaf nodes in white are words in the vocabulary. The gray inner nodes carry information on the probabilities of reaching its child nodes. One path starting from the root to the leaf $w\\_i$. $n(w\\_i, j)$ denotes the j-th node on this path. (Image source:\nword2vec Parameter Learning Explained\n)\nEach word $w_i$ has a unique path from the root down to its corresponding leaf. The probability of picking this word is equivalent to the probability of taking this path from the root down through the tree branches. Since we know the embedding vector $v_n$ of the internal node $n$, the probability of getting the word can be computed by the product of taking left or right turn at every internal node stop.\nAccording to Fig. 3, the probability of one node is ($\\sigma$ is the sigmoid function):\n$$\n\\begin{align}\np(\\text{turn right} \\to \\dots w_I \\vert n) &= \\sigma({v'_n}^{\\top} v_{w_I})\\\\\np(\\text{turn left } \\to \\dots w_I \\vert n) &= 1 - p(\\text{turn right} \\vert n) = \\sigma(-{v'_n}^{\\top} v_{w_I})\n\\end{align}\n$$\nThe final probability of getting a context word $w_O$ given an input word $w_I$ is:\n$$\np(w_O \\vert w_I) = \\prod_{k=1}^{L(w_O)} \\sigma(\\mathbb{I}_{\\text{turn}}(n(w_O, k), n(w_O, k+1)) \\cdot {v'_{n(w_O, k)}}^{\\top} v_{w_I})\n$$\nwhere $L(w_O)$ is the depth of the path leading to the word $w_O$ and $\\mathbb{I}_{\\text{turn}}$ is a specially indicator function which returns 1 if $n(w_O, k+1)$ is the left child of $n(w_O, k)$ otherwise -1. The internal nodes’ embeddings are learned during the model training. The tree structure helps greatly reduce the complexity of the denominator estimation from O(V) (vocabulary size) to O(log V) (the depth of the tree) at the training time. However, at the prediction time, we still to compute the probability of every word and pick the best, as we don’t know which leaf to reach for in advance.\nA good tree structure is crucial to the model performance. Several handy principles are: group words by frequency like what is implemented by Huffman tree for simple speedup; group similar words into same or close branches (i.e. use predefined word clusters, WordNet).\nCross Entropy\n#\nAnother approach completely steers away from the softmax framework. Instead, the loss function measures the cross entropy between the predicted probabilities $p$ and the true binary labels $\\mathbf{y}$.\nFirst, let’s recall that the cross entropy between two distributions $p$ and $q$ is measured as $ H(p, q) = -\\sum_x p(x) \\log q(x) $. In our case, the true label $y_i$ is 1 only when $w_i$ is the output word; $y_j$ is 0 otherwise. The loss function $\\mathcal{L}_\\theta$ of the model with parameter config $\\theta$ aims to minimize the cross entropy between the prediction and the ground truth, as lower cross entropy indicates high similarity between two distributions.\n$$\n\\mathcal{L}_\\theta = - \\sum_{i=1}^V y_i \\log p(w_i | w_I) = - \\log p(w_O \\vert w_I)\n$$\nRecall that,\n$$\np(w_O \\vert w_I) = \\frac{\\exp({v'_{w_O}}^{\\top} v_{w_I})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top} v_{w_I})}\n$$\nTherefore,\n$$\n\\mathcal{L}_{\\theta} \n= - \\log \\frac{\\exp({v'_{w_O}}^{\\top}{v_{w_I}})}{\\sum_{i=1}^V \\exp({v'_{w_i}}^{\\top}{v_{w_I} })}\n= - {v'_{w_O}}^{\\top}{v_{w_I} } + \\log \\sum_{i=1}^V \\exp({v'_{w_i} }^{\\top}{v_{w_I}})\n$$\nTo start training the model using back-propagation with SGD, we need to compute the gradient of the loss function. For simplicity, let’s label $z_{IO} = {v’_{w_O}}^{\\top}{v_{w_I}}$.\n$$\n\\begin{align}\n\\nabla_\\theta \\mathcal{L}_{\\theta}\n&= \\nabla_\\theta\\big( - z_{IO} + \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\ \n&= - \\nabla_\\theta z_{IO} + \\nabla_\\theta \\big( \\log \\sum_{i=1}^V e^{z_{Ii}} \\big) \\\\\n&= - \\nabla_\\theta z_{IO} + \\frac{1}{\\sum_{i=1}^V e^{z_{Ii}}} \\sum_{i=1}^V e^{z_{Ii}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V \\frac{e^{z_{Ii}}}{\\sum_{i=1}^V e^{z_{Ii}}} \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\sum_{i=1}^V p(w_i \\vert w_I) \\nabla_\\theta z_{Ii} \\\\\n&= - \\nabla_\\theta z_{IO} + \\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta z_{Ii}\n\\end{align}\n$$\nwhere $Q(\\tilde{w})$ is the distribution of noise samples.\nAccording to the formula above, the correct output word has a positive reinforcement according to the first term (the larger $\\nabla_\\theta z_{IO}$ the better loss we have), while other words have a negative impact as captured by the second term.\nHow to estimate $\\mathbb{E}_{w_i \\sim Q(\\tilde{w})} \\nabla_\\theta {v’_{w_i}}^{\\top}{v_{w_I}}$ with a sample set of noise words rather than scanning through the entire vocabulary is the key of using cross-entropy-based sampling approach.\nNoise Contrastive Estimation (NCE)\n#\nThe Noise Contrastive Estimation (NCE) metric intends to differentiate the target word from noise samples using a logistic regression classifier (\nGutmann and Hyvärinen, 2010\n).\nGiven an input word $w_I$, the correct output word is known as $w$. In the meantime, we sample $N$ other words from the noise sample distribution $Q$, denoted as $\\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N \\sim Q$. Let’s label the decision of the binary classifier as $d$ and $d$$ can only take a binary value.\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) + \\sum_{i=1, \\tilde{w}_i \\sim Q}^N \\log p(d=0|\\tilde{w}_i, w_I) ]\n$$\nWhen $N$ is big enough, according to\nthe Law of large numbers\n,\n$$\n\\mathcal{L}_\\theta = - [ \\log p(d=1 \\vert w, w_I) +  N\\mathbb{E}_{\\tilde{w}_i \\sim Q} \\log p(d=0|\\tilde{w}_i, w_I)]\n$$\nTo compute the probability $p(d=1 \\vert w, w_I)$, we can start with the joint probability $p(d, w \\vert w_I)$. Among $w, \\tilde{w}_1, \\tilde{w}_2, \\dots, \\tilde{w}_N$, we have 1 out of (N+1) chance to pick the true word $w$, which is sampled from the conditional probability $p(w \\vert w_I)$; meanwhile, we have N out of (N+1) chances to pick a noise word, each sampled from $q(\\tilde{w}) \\sim Q$. Thus,\n$$\np(d, w | w_I) = \n  \\begin{cases}\n  \\frac{1}{N+1} p(w \\vert w_I) & \\text{if } d=1 \\\\\n  \\frac{N}{N+1} q(\\tilde{w}) & \\text{if } d=0\n  \\end{cases}\n$$\nThen we can figure out $p(d=1 \\vert w, w_I)$ and $p(d=0 \\vert w, w_I)$:\n$$\n\\begin{align}\np(d=1 \\vert w, w_I) \n&= \\frac{p(d=1, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\n$$\n\\begin{align}\np(d=0 \\vert w, w_I) \n&= \\frac{p(d=0, w \\vert w_I)}{p(d=1, w \\vert w_I) + p(d=0, w \\vert w_I)}\n&= \\frac{Nq(\\tilde{w})}{p(w \\vert w_I) + Nq(\\tilde{w})}\n\\end{align}\n$$\nFinally the loss function of NCE’s binary classifier becomes:\n$$\n\\begin{align}\n\\mathcal{L}_\\theta \n& = - [ \\log p(d=1 \\vert w, w_I) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log p(d=0|\\tilde{w}_i, w_I)] \\\\\n& = - [ \\log \\frac{p(w \\vert w_I)}{p(w \\vert w_I) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{p(w \\vert w_I) + Nq(\\tilde{w}_i)}]\n\\end{align}\n$$\nHowever, $p(w \\vert w_I)$ still involves summing up the entire vocabulary in the denominator. Let’s label the denominator as a partition function of the input word, $Z(w_I)$. A common assumption is $Z(w) \\approx 1$ given that we expect the softmax output layer to be normalized (\nMinh and Teh, 2012\n). Then the loss function is simplified to:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\frac{\\exp({v'_w}^{\\top}{v_{w_I}})}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w})} +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\frac{Nq(\\tilde{w}_i)}{\\exp({v'_w}^{\\top}{v_{w_I}}) + Nq(\\tilde{w}_i)}]\n$$\nThe noise distribution $Q$ is a tunable parameter and we would like to design it in a way so that:\nintuitively it should be very similar to the real data distribution; and\nit should be easy to sample from.\nFor example, the sampling implementation (\nlog_uniform_candidate_sampler\n) of NCE loss in tensorflow assumes that such noise samples follow a log-uniform distribution, also known as\nZipfian’s law\n. The probability of a given word in logarithm is expected to be reversely proportional to its rank, while high-frequency words are assigned with lower ranks. In this case, $q(\\tilde{w}) = \\frac{1}{ \\log V}(\\log (r_{\\tilde{w}} + 1) - \\log r_{\\tilde{w}})$, where $r_{\\tilde{w}} \\in [1, V]$ is the rank of a word by frequency in descending order.\nNegative Sampling (NEG)\n#\nThe Negative Sampling (NEG) proposed by Mikolov et al. (\n2013\n) is a simplified variation of NCE loss. It is especially famous for training Google’s\nword2vec\nproject. Different from NCE Loss which attempts to approximately maximize the log probability of the softmax output, negative sampling did further simplification because it focuses on learning high-quality word embedding rather than modeling the word distribution in natural language.\nNEG approximates the binary classifier’s output with sigmoid functions as follows:\n$$\n\\begin{align}\np(d=1 \\vert w_, w_I) &= \\sigma({v'_{w}}^\\top v_{w_I}) \\\\\np(d=0 \\vert w, w_I) &= 1 - \\sigma({v'_{w}}^\\top v_{w_I}) = \\sigma(-{v'_{w}}^\\top v_{w_I})\n\\end{align}\n$$\nThe final NCE loss function looks like:\n$$\n\\mathcal{L}_\\theta = - [ \\log \\sigma({v'_{w}}^\\top v_{w_I}) +  \\sum_{\\substack{i=1 \\\\ \\tilde{w}_i \\sim Q}}^N \\log \\sigma(-{v'_{\\tilde{w}_i}}^\\top v_{w_I})]\n$$\nOther Tips for Learning Word Embedding\n#\nMikolov et al. (\n2013\n) suggested several helpful practices that could result in good word embedding learning outcomes.\nSoft sliding window\n. When pairing the words within the sliding window, we could assign less weight to more distant words. One heuristic is — given a maximum window size parameter defined, $s_{\\text{max}}$, the actual window size is randomly sampled between 1 and $s_{\\text{max}}$ for every training sample. Thus, each context word has the probability of 1/(its distance to the target word) being observed, while the adjacent words are always observed.\nSubsampling frequent words\n. Extremely frequent words might be too general to differentiate the context (i.e. think about stopwords). While on the other hand, rare words are more likely to carry distinct information. To balance the frequent and rare words, Mikolov et al. proposed to discard words $w$ with probability $1-\\sqrt{t/f(w)}$ during sampling. Here $f(w)$ is the word frequency and $t$ is an adjustable threshold.\nLearning phrases first\n. A phrase often stands as a conceptual unit, rather than a simple composition of individual words. For example, we cannot really tell “New York” is a city name even we know the meanings of “new” and “york”. Learning such phrases first and treating them as word units before training the word embedding model improves the outcome quality. A simple data-driven approach is based on unigram and bigram counts: $s_{\\text{phrase}} = \\frac{C(w_i w_j) - \\delta}{ C(w_i)C(w_j)}$, where $C(.)$ is simple count of an unigram $w_i$ or bigram $w_i w_j$ and $\\delta$ is a discounting threshold to prevent super infrequent words and phrases. Higher scores indicate higher chances of being phrases. To form phrases longer than two words, we can scan the vocabulary multiple times with decreasing score cutoff values.\nGloVe: Global Vectors\n#\nThe Global Vector (GloVe) model proposed by Pennington et al. (\n2014\n) aims to combine the count-based matrix factorization and the context-based skip-gram model together.\nWe all know the counts and co-occurrences can reveal the meanings of words. To distinguish from $p(w_O \\vert w_I)$ in the context of a word embedding word, we would like to define the co-ocurrence probability as:\n$$\np_{\\text{co}}(w_k \\vert w_i) = \\frac{C(w_i, w_k)}{C(w_i)}\n$$\n$C(w_i, w_k)$ counts the co-occurrence between words $w_i$ and $w_k$.\nSay, we have two words, $w_i$=“ice” and $w_j$=“steam”. The third word $\\tilde{w}_k$=“solid” is related to “ice” but not “steam”, and thus we expect $p_{\\text{co}}(\\tilde{w}_k \\vert w_i)$ to be much larger than $p_{\\text{co}}(\\tilde{w}_k \\vert w_j)$ and therefore $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ to be very large. If the third word $\\tilde{w}_k$ = “water” is related to both or $\\tilde{w}_k$ = “fashion” is unrelated to either of them, $\\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}$ is expected to be close to one.\nThe intuition here is that the word meanings are captured by the ratios of co-occurrence probabilities rather than the probabilities themselves. The global vector models the relationship between two words regarding to the third context word as:\n$$\nF(w_i, w_j, \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nFurther, since the goal is to learn meaningful word vectors, $F$ is designed to be a function of the linear difference between two words $w_i - w_j$:\n$$\nF((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n$$\nWith the consideration of $F$ being symmetric between target words and context words, the final solution is to model $F$ as an\nexponential\nfunction. Please read the original paper (\nPennington et al., 2014\n) for more details of the equations.\n$$\n\\begin{align}\nF({w_i}^\\top \\tilde{w}_k) &= \\exp({w_i}^\\top \\tilde{w}_k) = p_{\\text{co}}(\\tilde{w}_k \\vert w_i) \\\\\nF((w_i - w_j)^\\top \\tilde{w}_k) &= \\exp((w_i - w_j)^\\top \\tilde{w}_k) = \\frac{\\exp(w_i^\\top \\tilde{w}_k)}{\\exp(w_j^\\top \\tilde{w}_k)} = \\frac{p_{\\text{co}}(\\tilde{w}_k \\vert w_i)}{p_{\\text{co}}(\\tilde{w}_k \\vert w_j)}\n\\end{align}\n$$\nFinally,\n$$\n{w_i}^\\top \\tilde{w}_k = \\log p_{\\text{co}}(\\tilde{w}_k \\vert w_i) = \\log \\frac{C(w_i, \\tilde{w}_k)}{C(w_i)} = \\log C(w_i, \\tilde{w}_k) - \\log C(w_i)\n$$\nSince the second term $-\\log C(w_i)$ is independent of $k$, we can add bias term $b_i$ for $w_i$ to capture $-\\log C(w_i)$. To keep the symmetric form, we also add in a bias $\\tilde{b}_k$ for $\\tilde{w}_k$.\n$$\n\\log C(w_i, \\tilde{w}_k) = {w_i}^\\top \\tilde{w}_k + b_i + \\tilde{b}_k\n$$\nThe loss function for the GloVe model is designed to preserve the above formula by minimizing the sum of the squared errors:\n$$\n\\mathcal{L}_\\theta = \\sum_{i=1, j=1}^V f(C(w_i,w_j)) ({w_i}^\\top \\tilde{w}_j + b_i + \\tilde{b}_j - \\log C(w_i, \\tilde{w}_j))^2\n$$\nThe weighting schema $f(c)$ is a function of the co-occurrence of $w_i$ and $w_j$ and it is an adjustable model configuration. It should be close to zero as $c \\to 0$; should be non-decreasing as higher co-occurrence should have more impact; should saturate when $c$ become extremely large. The paper proposed the following weighting function.\n$$\nf(c) = \n  \\begin{cases}\n  (\\frac{c}{c_{\\max}})^\\alpha & \\text{if } c < c_{\\max} \\text{, } c_{\\max} \\text{ is adjustable.} \\\\\n  1 & \\text{if } \\text{otherwise}\n  \\end{cases}\n$$\nExamples: word2vec on “Game of Thrones”\n#\nAfter reviewing all the theoretical knowledge above, let’s try a little experiment in word embedding extracted from “the Games of Thrones corpus”. The process is super straightforward using\ngensim\n.\nStep 1: Extract words\nimport\nsys\nfrom\nnltk.corpus\nimport\nstopwords\nfrom\nnltk.tokenize\nimport\nsent_tokenize\nSTOP_WORDS\n=\nset(stopwords\n.\nwords(\n'english'\n))\ndef\nget_words\n(txt):\nreturn\nfilter(\nlambda\nx: x\nnot\nin\nSTOP_WORDS,\nre\n.\nfindall(\nr\n'\\b(\\w+)\\b'\n, txt)\n)\ndef\nparse_sentence_words\n(input_file_names):\n\"\"\"Returns a list of a list of words. Each sublist is a sentence.\"\"\"\nsentence_words\n=\n[]\nfor\nfile_name\nin\ninput_file_names:\nfor\nline\nin\nopen(file_name):\nline\n=\nline\n.\nstrip()\n.\nlower()\nline\n=\nline\n.\ndecode(\n'unicode_escape'\n)\n.\nencode(\n'ascii'\n,\n'ignore'\n)\nsent_words\n=\nmap(get_words, sent_tokenize(line))\nsent_words\n=\nfilter(\nlambda\nsw: len(sw)\n>\n1\n, sent_words)\nif\nlen(sent_words)\n>\n1\n:\nsentence_words\n+=\nsent_words\nreturn\nsentence_words\n# You would see five .txt files after unzip 'a_song_of_ice_and_fire.zip'\ninput_file_names\n=\n[\n\"001ssb.txt\"\n,\n\"002ssb.txt\"\n,\n\"003ssb.txt\"\n,\n\"004ssb.txt\"\n,\n\"005ssb.txt\"\n]\nGOT_SENTENCE_WORDS\n=\nparse_sentence_words(input_file_names)\nStep 2: Feed a word2vec model\nfrom\ngensim.models\nimport\nWord2Vec\n# size: the dimensionality of the embedding vectors.\n# window: the maximum distance between the current and predicted word within a sentence.\nmodel\n=\nWord2Vec(GOT_SENTENCE_WORDS, size\n=\n128\n, window\n=\n3\n, min_count\n=\n5\n, workers\n=\n4\n)\nmodel\n.\nwv\n.\nsave_word2vec_format(\n\"got_word2vec.txt\"\n, binary\n=\nFalse\n)\nStep 3: Check the results\nIn the GoT word embedding space, the top similar words to “king” and “queen” are:\nmodel.most_similar('king', topn=10)\n(word, similarity with ‘king’)\nmodel.most_similar('queen', topn=10)\n(word, similarity with ‘queen’)\n(‘kings’, 0.897245)\n(‘cersei’, 0.942618)\n(‘baratheon’, 0.809675)\n(‘joffrey’, 0.933756)\n(‘son’, 0.763614)\n(‘margaery’, 0.931099)\n(‘robert’, 0.708522)\n(‘sister’, 0.928902)\n(’lords’, 0.698684)\n(‘prince’, 0.927364)\n(‘joffrey’, 0.696455)\n(‘uncle’, 0.922507)\n(‘prince’, 0.695699)\n(‘varys’, 0.918421)\n(‘brother’, 0.685239)\n(’ned’, 0.917492)\n(‘aerys’, 0.684527)\n(‘melisandre’, 0.915403)\n(‘stannis’, 0.682932)\n(‘robb’, 0.915272)\nCited as:\n@article{weng2017wordembedding,\n  title   = \"Learning word embedding\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-15-word-embedding/\"\n}\nReferences\n#\n[1] Tensorflow Tutorial\nVector Representations of Words\n.\n[2]\n“Word2Vec Tutorial - The Skip-Gram Model”\nby Chris McCormick.\n[3]\n“On word embeddings - Part 2: Approximating the Softmax”\nby Sebastian Ruder.\n[4] Xin Rong.\nword2vec Parameter Learning Explained\n[5] Mikolov, Tomas, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[6] Frederic Morin and Yoshua Bengio.\n“Hierarchical Probabilistic Neural Network Language Model.”\nAistats. Vol. 5. 2005.\n[7] Michael Gutmann and Aapo Hyvärinen.\n“Noise-contrastive estimation: A new estimation principle for unnormalized statistical models.”\nProc. Intl. Conf. on Artificial Intelligence and Statistics. 2010.\n[8] Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Distributed representations of words and phrases and their compositionality.”\nAdvances in neural information processing systems. 2013.\n[9] Tomas Mikolov, Kai Chen, Greg Corrado, and Jeffrey Dean.\n“Efficient estimation of word representations in vector space.”\narXiv preprint arXiv:1301.3781 (2013).\n[10] Marco Baroni, Georgiana Dinu, and Germán Kruszewski.\n“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”\nACL (1). 2014.\n[11] Jeffrey Pennington, Richard Socher, and Christopher Manning.\n“Glove: Global vectors for word representation.”\nProc. Conf. on empirical methods in natural language processing (EMNLP). 2014.",
            "metadata": {
              "title": "Learning Word Embedding | Lil'Log",
              "description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "keywords": "nlp, language-model",
              "author": "Lilian Weng",
              "og:title": "Learning Word Embedding",
              "og:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
              "twitter:card": "summary",
              "twitter:title": "Learning Word Embedding",
              "twitter:description": "Human vocabulary comes in free text. In order to make a machine learning model understand and process the natural language, we need to transform the free-text words into numeric values. One of the simplest transformation approaches is to do a one-hot encoding in which each distinct word stands for one dimension of the resulting vector and a binary value indicates whether the word presents (1) or not (0).",
              "article:section": "posts",
              "article:published_time": "2017-10-15T00:00:00+00:00",
              "article:modified_time": "2017-10-15T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/3e47ba682561/code/body-000.txt",
                "chars": 1066,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-001.txt",
                "chars": 323,
                "language": "text"
              },
              {
                "file": "attachments/3e47ba682561/code/body-002.txt",
                "chars": 233,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "bytes": 179202,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-e21a214c6127867b9495.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-skip-gram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "bytes": 183003,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-0f5bdb5a435b843e8180.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-cbow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "bytes": 18594,
                "reused": false,
                "local_path": "attachments/3e47ba682561/images/body-f369233bacf831326935.png",
                "src": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/word2vec-hierarchical-softmax.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://arxiv.org/pdf/1301.3781.pdf",
                "label": "Mikolov et al., 2013",
                "type": "a"
              },
              {
                "href": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "label": "2005",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1411.2738.pdf",
                "label": "word2vec Parameter Learning Explained",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "label": "Gutmann and Hyvärinen, 2010",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Law_of_large_numbers",
                "label": "the Law of large numbers",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "label": "Minh and Teh, 2012",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/candidate_sampling_ops.py",
                "label": "log_uniform_candidate_sampler",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Zipf%27s_law",
                "label": "Zipfian’s law",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "label": "2013",
                "type": "a"
              },
              {
                "href": "https://code.google.com/archive/p/word2vec/",
                "label": "word2vec",
                "type": "a"
              },
              {
                "href": "http://www.aclweb.org/anthology/D14-1162",
                "label": "2014",
                "type": "a"
              },
              {
                "href": "https://radimrehurek.com/gensim/models/word2vec.html",
                "label": "gensim",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/word2vec",
                "label": "Vector Representations of Words",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/",
                "label": "“Word2Vec Tutorial - The Skip-Gram Model”",
                "type": "a"
              },
              {
                "href": "http://ruder.io/word-embeddings-softmax/",
                "label": "“On word embeddings - Part 2: Approximating the Softmax”",
                "type": "a"
              },
              {
                "href": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "label": "“Don’t count, predict! A systematic comparison of context-counting vs. context-predicting semantic vectors.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:36Z",
            "source_url": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1301.3781.pdf",
                "bytes": 228716,
                "reused": false,
                "local_path": "papers/repair/1e8e84311c23b0346b07.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://www.iro.umontreal.ca/~lisa/pointeurs/hierarchical-nnlm-aistats05.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T18:04:55Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1411.2738.pdf",
                "bytes": 816833,
                "reused": false,
                "local_path": "papers/repair/b37b38f8ebbcb26bcb27.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v9/gutmann10a/gutmann10a.pdf",
                "bytes": 633631,
                "reused": false,
                "local_path": "papers/repair/4e238b55e8eb6f9638d6.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cs.toronto.edu/~amnih/papers/ncelm.pdf",
                "bytes": 332740,
                "reused": false,
                "local_path": "papers/repair/d0eae5ee0263039f0b98.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf",
                "bytes": 111997,
                "reused": false,
                "local_path": "papers/repair/32de112509f802883250.pdf"
              },
              {
                "status": "ok",
                "url": "http://anthology.aclweb.org/P/P14/P14-1023.pdf",
                "bytes": 152976,
                "reused": false,
                "local_path": "papers/repair/c28d8258a40dec5bef84.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25736,
            "expected_body_images": 3,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/3e47ba682561/pages/source.html",
            "local_html": "attachments/3e47ba682561/pages/article.html",
            "body_base_path": "attachments/3e47ba682561/pages/",
            "body_markdown_path": "attachments/3e47ba682561/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
          "status": "partial",
          "article_id": "2cf34df8cd69",
          "local_path": "series-follow/1601/repair/755e367caba0c679040a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
              "bytes": 661245,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7efefadad7e7dd1bd368.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
              "bytes": 173461,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ef8c4099815df32d696d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
              "bytes": 192230,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a2c96b21ecb7e2fe5261.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
              "bytes": 180723,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9d359913e38042c21f68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
              "bytes": 131727,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/658614a9a3e7c1d7b935.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
              "bytes": 337530,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/eaf24c5188513fae50ed.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
              "bytes": 124437,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ff31b70ac499e0b32939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
              "bytes": 865287,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2e1a4cd54853b0630bf6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
              "bytes": 553919,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7826a791054014f6fcfb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
              "bytes": 260572,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d37427b8abf7df28ba56.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
              "bytes": 198348,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1debd5c40323ec83577c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
              "bytes": 290218,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/76ae01d2ac36750aac13.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
              "bytes": 145311,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cb02352f1fcc5796b966.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
              "bytes": 201245,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4a06ae2c872925f426c9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
              "bytes": 329545,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/592734de78cf202658cc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
              "bytes": 244182,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f4f90d0aeb9507c08585.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Build an Open-Domain Question Answering System?",
            "keywords": "开放域问答,检索,ODQA",
            "domain": "文本处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "publish_date": "2020-10",
            "corpus_stage": "预训练/SFT",
            "notes": "开放域问答系统构建综述",
            "id": "2cf34df8cd69",
            "collected_at": "2026-10-02T14:13:11",
            "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
            "body_markdown": "[Updated on 2020-11-12: add\nan example\non closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.\nDisclaimers given so many papers in the wild:\nAssume we have access to a powerful pretrained\nlanguage model\n.\nWe do not cover how to use structured knowledge base (e.g. Freebase, WikiData) here.\nWe only focus on a single-turn QA instead of a multi-turn conversation style QA.\nWe mostly focus on QA models that contain neural networks, specially Transformer-based language models.\nI admit that I missed a lot of papers with architectures designed specifically for QA tasks between 2017-2019😔\nWhat is Open-Domain Question Answering?\n#\nOpen-domain Question Answering (ODQA)\nis a type of language tasks, asking a model to produce answers to factoid questions in natural language. The true answer is objective, so it is simple to evaluate model performance.\nFor example,\nQuestion: What did Albert Einstein win the Nobel Prize for?\nAnswer: The law of the photoelectric effect.\nThe “open-domain” part refers to the lack of the relevant context for any arbitrarily asked factual question. In the above case, the model only takes as the input the question but no article about “why Einstein didn’t win a Nobel Prize for the theory of relativity” is provided, where the term “the law of the photoelectric effect” is likely mentioned. In the case when both the question and the context are provided, the task is known as\nReading comprehension (RC)\n.\nAn ODQA model may work with or without\naccess to an external source of knowledge\n(e.g. Wikipedia) and these two conditions are referred to as\nopen-book\nor\nclosed-book\nquestion answering, respectively.\nWhen considering different types of open-domain questions, I like the classification by\nLewis, et al., 2020\n, in increasing order of difficulty:\nA model is able to correctly memorize and respond with the answer to a question that has been seen at training time.\nA model is able to answer novel questions at test time and choose an answer from the set of answers it has seen during training.\nA model is able to answer novel questions which have answers not contained in the training dataset.\nOverview of three frameworks discussed in this post.\nNotation\n#\nGiven a question $x$ and a ground truth answer span $y$, the context passage containing the true answer is labelled as $z \\in \\mathcal{Z}$, where $\\mathcal{Z}$ is an external knowledge corpus. Wikipedia is a common choice for such an external knowledge source.\nConcerns of QA data fine-tuning\n#\nBefore we dive into the details of many models below. I would like to point out one concern of fine-tuning a model with common QA datasets, which appears as one fine-tuning step in several ODQA models. It could be concerning, because there is a significant overlap between questions in the train and test sets in several public QA datasets.\nLewis, et al., (2020)\n(\ncode\n) found that 58-71% of test-time answers are also present somewhere in the training sets and 28-34% of test-set questions have a near-duplicate paraphrase in their corresponding training sets. In their experiments, several models performed notably worse when duplicated or paraphrased questions were removed from the training set.\nOpen-book QA: Retriever-Reader\n#\nGiven a factoid question, if a language model has no context or is not big enough to memorize the context which exists in the training dataset, it is unlikely to guess the correct answer. In an open-book exam, students are allowed to refer to external resources like notes and books while answering test questions. Similarly, a ODQA system can be paired with a rich knowledge base to identify relevant documents as evidence of answers.\nWe can decompose the process of finding answers to given questions into two stages,\nFind the related context in an external repository of knowledge;\nProcess the retrieved context to\nextract\nan answer.\nThe retriever-reader QA framework combines information retrieval with machine reading comprehension.\nSuch a retriever + reader framework was first proposed in\nDrQA\n(“Document retriever Question-Answering” by\nChen et al., 2017\n;\ncode\n). The retriever and the reader components can be set up and trained independently, or jointly trained\nend-to-end\n.\nRetriever Model\n#\nTwo popular approaches for implementing the retriever is to use the information retrieval (IR) system that depends on (1) the classic non-learning-based\nTF-IDF\nfeatures (“classic IR”) or (2) dense embedding vectors of text produced by neural networks (“neural IR”).\nClassic IR\n#\nDrQA\n(\nChen et al., 2017\n) adopts an efficient non-learning-based search engine based on the\nvector space model\n. Every query and document is modelled as a bag-of-word vector, where each term is weighted by TF-IDF (term frequency $\\times$ inverse document frequency).\n$$\n\\begin{aligned}\n\\text{tf-idf}(t, d, \\mathcal{D}) &= \\text{tf}(t, d) \\times \\text{idf}(t, \\mathcal{D}) \\\\\n\\text{tf}(t, d) &= \\log(1 + \\text{freq}(t, d)) \\\\\n\\text{idf}(t, \\mathcal{D}) &= \\log \\Big( \\frac{\\vert\\mathcal{D}\\vert}{\\vert d\\in\\mathcal{D}: t\\in d\\vert} \\Big)\n\\end{aligned}\n$$\nwhere $t$ is a unigram or bigram term in a document $d$ from a collection of documents $\\mathcal{D}$ . $\\text{freq}(t, d)$ measures how many times a term $t$ appears in $d$. Note that the term-frequency here includes bigram counts too, which is found to be very helpful because the local word order is taken into consideration via bigrams. As part of the implementation, DrQA maps the bigrams of $2^{24}$ bins using unsigned murmur3 hash.\nPrecisely, DrQA implemented Wikipedia as its knowledge source and this choice has became a default setting for many ODQA studies since then. The non-ML document retriever returns the top $k=5$ most relevant Wikipedia articles given a question.\nBERTserini\n(\nYang et al., 2019\n) pairs the open-source\nAnserini\nIR toolkit as the retriever with a fine-tuned pre-trained BERT model as the reader. The top $k$ documents ($k=10$) are retrieved via the\npost-v3.0\nbranch of Anserini with the query treated as a bag of words. The retrieved text segments are ranked by\nBM25\n, a classic TF-IDF-based retrieval scoring function. In terms of the effect of text granularity on performance, they found that paragraph retrieval > sentence retrieval > article retrieval.\nAn illustration of BERTserini architecture. (Image source:\nYang et al., 2019\n)\nElasticSearch + BM25\nis used by the\nMulti-passage BERT\nQA model (\nWang et al., 2019\n). They found that splitting articles into passages with the length of 100 words by\nsliding window\nbrings 4% improvements, since splitting documents into passages without overlap may cause some near-boundary evidence to lose useful contexts.\nNeural IR\n#\nThere is a long history in learning a low-dimensional representation of text, denser than raw term-based vectors (\nDeerwester et al., 1990\n;\nYih, et al., 2011\n). Dense representations can be learned through matrix decomposition or some neural network architectures (e.g. MLP, LSTM, bidirectional LSTM, etc). When involving neural networks, such approaches are referred to as “Neural IR”, Neural IR is a new category of methods for retrieval problems, but it is not necessary to perform better/superior than classic IR (\nLim, 2018\n).\nAfter the success of many large-scale\ngeneral language models\n, many QA models embrace the following approach:\n$$\nh_x = E_x(x)\\quad\nh_z = E_z(z)\\quad\n\\text{score}(x, z) = h_x^\\top h_z\n$$\nExtract the dense representations of a question $x$ and a context passage $z$ by feeding them into a language model;\nUse the dot-product of these two representations as the retrieval score to rank and select most relevant passages.\nORQA, REALM and DPR all use such a scoring function for context retrieval, which will be described in detail in a\nlater section\non the end-to-end QA model.\nAn extreme approach, investigated by\nDenSPI\n(“Dense-Sparse Phrase Index”;\nSeo et al., 2019\n), is to encode all the text in the knowledge corpus at the\nphrase\nlevel and then only rely on the retriever to identify the most relevant phrase as the predicted answer. In this way, the retriever+reader pipeline is reduced to only retriever. Of course, the index would be much larger and the retrieval problem is more challenging.\nDenSPI introduces a\nquery-agnostic\nindexable representation of document phrases. Precisely it encodes query-agnostic representations of text spans in Wikipedia offline and looks for the answer at inference time by performing nearest neighbor search. It can drastically speed up the inference time, because there is no need to re-encode documents for every new query, which is often required by a reader model.\nGiven a question $x$ and a fixed set of (Wikipedia) documents, $z_1, \\dots, z_K$ and each document $z_k$ contains $N_k$ words, $z_k = \\langle z_k^{(1)}, \\dots, z_k^{(N_k)}\\rangle$. An ODQA model is a scoring function $F$ for each candidate phrase span $z_k^{(i:j)}, 1 \\leq i \\leq j \\leq N_k$, such that the truth answer is the phrase with maximum score: $y = {\\arg\\max}_{k,i,j} F(x, z_k^{(i:j)})$.\nThe phrase representation $z_k^{(i:j)}$ combines both dense and sparse vectors, $z_k^{(i:j)} = [d_k^{(i:j)}, s_k^{(i:j)}] \\in \\mathbb{R}^{d^d + d^s}$ (note that $d^d \\ll d^s$):\nThe dense vector $d_k^{(i:j)}$ is effective for encoding local\nsyntactic\nand\nsemantic\ncues, as what can be learned by a pretrained language model.\nThe sparse vector $s_k^{(i:j)}$ is superior at encoding precise\nlexical\ninformation. The sparse vector is term-frequency-based encoding. DenSPI uses 2-gram term-frequency same as DrQA, resulting a highly sparse representation ($d^s \\approx 16$M)\nThe dense vector $d^{(i:j)}$ is further decomposed into three parts, $d^{(i:j)} = [a_i, b_j, c_{ij}] \\in \\mathbb{R}^{2d^b + 1}$ where $2d^b + 1 = d^d$. All three components are learned based on different columns of the fine-tuned BERT representations.\nA vector $a_i$ encodes the\nstart\nposition for the $i$-th word of the document;\nA vector $b_j$ encodes the\nend\nposition for the $j$-th word of the document;\nA scalar $c_{ij}$ measures the\ncoherency\nbetween the start and the end vectors, helping avoid non-constituent phrases during inference.\nFor all possible $(i,j,k)$ tuples where $j-i < J$, the text span embeddings are precomputed and stored as a\nphrase index\n. The maximum span length $J$ is a predefined scalar constant.\nAn illustration of Dense-Sparse Phrase Index (DenSPI) architecture. (Image source:\nSeo et al., 2019\n)\nAt the inference time, the question is mapped into the same vector space $x=[d’, s’] \\in \\mathbb{R}^{d^d + d^s}$, where the dense vector $d’$ is extracted from the BERT embedding of the special\n[CLS]\nsymbol. The same BERT model is shared for encoding both questions and phrases. The final answer is predicted by $k^*, i^*, j^* = \\arg\\max x^\\top z_k^{(i:j)}$.\nReader Model\n#\nThe reader model learns to solve the reading comprehension task — extract an answer for a given question from a given context document. Here we only discuss approaches for machine comprehension using neural networks.\nBi-directional LSTM\n#\nThe reader model for answer detection of\nDrQA\n(\nChen et al., 2017\n) is a 3-layer bidirectional LSTM with hidden size 128. Every relevant paragraph of retrieved Wikipedia articles is encoded by a sequence of feature vector, $\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m \\}$. Each feature vector $\\hat{\\mathbf{z}}_i \\in \\mathbb{R}^{d_z}$ is expected to capture useful contextual information around one token $z_i$. The feature consists of several categories of features:\nWord embeddings: A 300d\nGlove\nword embedding trained from 800B Web crawl data, $f_\\text{embed} = E_g(z_i)$.\nExact match: Whether a word $z_i$ appears in the question $x$, $f_\\text{match} = \\mathbb{I}(z_i \\in x)$.\nToken features: This includes POS (part-of-speech) tagging, NER (named entity recognition), and TF (term-frequency), $f_\\text{token}(z_i) = (\\text{POS}(z_i), \\text{NER}(z_i), \\text{TF}(z_i))$.\nAligned question embedding: The attention score $y_{ij}$ is designed to capture inter-sentence matching and similarity between the paragraph token $z_i$ and the question word $x_j$. This feature adds soft alignments between similar but non-identical words.\n$$\n\\begin{aligned}\nf_\\text{align}(z_i) &= \\sum_j y_{i,j} E_g(x_j) \\\\ \ny_{i,j} &= \\frac{\\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_j)) )}{\\sum_{j'} \\exp(\\alpha(E_g(z_i))^\\top \\alpha(E_g(x_{j'})) ) }\n\\end{aligned}\n$$\nwhere $\\alpha$ is a single dense layer with ReLU and $E_g(.)$ is the glove word embedding.\nThe feature vector of a paragraph of $m$ tokens is fed into LSTM to obtain the final paragraph vectors:\n$$\n\\begin{aligned}\n\\mathbf{z} = \\{\\mathbf{z}_1, \\dots, \\mathbf{z}_m\\} &= \\text{LSTM}(\\{\\tilde{\\mathbf{z}}_1, \\dots, \\tilde{\\mathbf{z}}_m\\}) \\\\\n\\text{where } \\tilde{\\mathbf{z}}_i &= \\{f_\\text{embed}, f_\\text{match}, f_\\text{token}, f_\\text{align}\\}\n\\end{aligned}\n$$\nThe question is encoded as a weighted sum of the embeddings of every word in the question:\n$$\n\\mathbf{x} = \\sum_j b_j E(x_j) \\quad b_j = \\text{softmax}(\\mathbf{w}^\\top E(x_j))\n$$\nwhere $\\mathbf{w}$ is a weight vector to learn.\nOnce the feature vectors are constructed for the question and all the related paragraphs, the reader needs to predict the probabilities of each position in a paragraph to be the start and the end of an answer span, $p_\\text{start}(i_s)$ and $p_\\text{end}(i_s)$, respectively. Across all the paragraphs, the optimal span is returned as the final answer with maximum $p_\\text{start}(i_s)  \\times p_\\text{end}(i_e) $.\n$$\n\\begin{aligned}\np_\\text{start}(i_s) \\propto \\exp(\\mathbf{z}_{i_s} \\mathbf{W}_s \\mathbf{x}) \\\\ \np_\\text{end}(i_e) \\propto \\exp(\\mathbf{z}_{i_e} \\mathbf{W}_e \\mathbf{x}) \\\\\n\\text{ s.t. } i_s \\leq i_e \\leq i_s + 15\n\\end{aligned}\n$$\nwhere $\\mathbf{W}_s$ and $\\mathbf{W}_e$ are learned parameters.\nBERT-universe\n#\nFollowing the success of\nBERT\n(\nDevlin et al., 2018\n), many QA models develop the machine comprehension component based on BERT. Let’s define the BERT model as a function that can take one or multiple strings (concatenated by\n[SEP]\n) as input and outputs a set of BERT encoding vectors for the special\n[CLS]\ntoken and every input token:\n$$\n\\text{BERT}(s_1, s_2, \\dots) = [\\mathbf{h}^\\texttt{[CLS]}, \\mathbf{h}^{(1)}, \\mathbf{h}^{(2)}, \\dots]\n$$\nwhere $\\mathbf{h}^\\texttt{[CLS]}$ is the embedding vector for the special\n[CLS]\ntoken and $\\mathbf{h}^{(i)}$ is the embedding vector for the $i$-th token.\nTo use BERT for reading comprehension, it learns two additional weights, $\\mathbf{W}_s$ and $\\mathbf{W}_e$, and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_s)$ and $\\text{softmax}(\\mathbf{h}^{(i)}\\mathbf{W}_e)$ define two probability distributions of start and end position of the predicted span per token.\nBERTserini\n(\nYang et al., 2019\n) utilizes a pre-trained BERT model to work as the reader. Their experiments showed that\nfine-tuning\npretrained BERT with SQuAD is sufficient to achieve high accuracy in identifying answer spans.\nHow BERT is used to solve question-answering tasks. (Image source:\nDevlin et al., 2018\n)\nThe key difference of the BERTserini reader from the original BERT is: to allow comparison and aggregation of results from different segments, the final softmax layer over different answer spans is removed. The pre-trained BERT model is fine-tuned on the training set of SQuAD, where all inputs to the reader are padded to 384 tokens with the learning rate 3e-5.\nWhen ranking all the extracted answer spans, the retriever score (BM25) and the reader score (probability of token being the start position $\\times$ probability of the same token being the end position ) are combined via linear interpolation.\nThe original BERT normalizes the probability distributions of start and end position per token for every passage independently. Differently, the\nMulti-passage BERT\n(\nWang et al., 2019\n) normalizes answer scores across all the retrieved passages of one question\nglobally\n. Precisely, multi-passage BERT removes the final normalization layer per passage in BERT for QA (same as in BERTserini) and then adds a global\nsoftmax\nover all the word positions of all the passages. Global normalization makes the reader model more stable while pin-pointing answers from a large number of passages.\nIn addition, multi-passage BERT implemented an independent\npassage ranker\nmodel via another BERT model and the rank score for $(x, z)$ is generated by a\nsoftmax\nover the representation vectors of the first\n[CLS]\ntoken. The passage ranker brings in extra 2% improvements. Similar idea of re-ranking passages with BERT was discussed in\nNogueira & Cho, 2019\n, too.\nInterestingly,\nWang et al., 2019\nfound that\nexplicit inter-sentence matching\ndoes not seem to be critical for RC tasks with BERT; check the original paper for how the experiments were designed. One possible reason is that the multi-head self-attention layers in BERT has already embedded the inter-sentence matching.\nEnd-to-end Joint Training\n#\nThe retriever and reader components can be jointly trained. This section covers R^3, ORQA, REALM and DPR. There are a lot of common designs, such as BERT-based dense vectors for retrieval and the loss function on maximizing the marginal likelihood of obtaining true answers.\nThe retriever and reader models in the\nR^3\n(“Reinforced Ranker-Reader”;\nWang, et al., 2017\n) QA system are jointly trained via\nreinforcement learning\n. (Note that to keep the term consistent between papers in this section, the “ranker” model in the original R^3 paper is referred to as the “retriever” model here.) Both components are variants of\nMatch-LSTM\n, which relies on an attention mechanism to compute word similarities between the passage and question sequences.\nHow does the Match-LSTM module work?\nGiven a question $\\mathbf{X}$ of $d_x$ words and a passage $\\mathbf{Z}$ of $d_z$ words, both representations use fixed\nGlove\nword embeddings,\n$$\n\\begin{aligned}\n\\mathbf{H}^x &= \\text{BiLSTM}(\\mathbf{X}) \\in \\mathbb{R}^{l \\times d_x} \\\\\n\\mathbf{H}^z &= \\text{BiLSTM}(\\mathbf{Z}) \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{G} &= \\text{softmax}((\\mathbf{W}^g \\mathbf{H}^x + \\mathbf{b}^g \\otimes \\mathbf{e}_{d_x})^\\top \\mathbf{H}^z) \\in \\mathbb{R}^{d_x \\times d_z} & \\text{; an attention matrix}\\\\\n\\bar{\\mathbf{H}}^x &= \\mathbf{H}^x \\mathbf{G} \\in \\mathbb{R}^{l \\times d_z} \\\\\n\\mathbf{M} &= \\text{ReLU} \\Big( \\mathbf{W}^m \\begin{bmatrix}\n\\mathbf{H}^z \\\\\n\\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z \\odot \\bar{\\mathbf{H}}^x \\\\\n\\mathbf{H}^z - \\bar{\\mathbf{H}}^x\n\\end{bmatrix} \\Big) \\in \\mathbb{R}^{2l \\times d_z} \\\\\n\\mathbf{H}^m &= \\text{BiLSTM}(M) \\in \\mathbb{R}^{l \\times d_z}\n\\end{aligned}\n$$\nwhere $l$ is the hidden dimension of the bidirectional LSTM module. $\\mathbf{W}^g \\in \\mathbb{R}^{l\\times l}$, $\\mathbf{b}^g \\in \\mathbb{R}^l$, and $\\mathbf{W}^m \\in \\mathbb{R}^{2l \\times 4l}$ are parameters to learn. The operator $\\otimes \\mathbf{e}_{d_x}$ is the outer product to repeat the column vector $\\mathbf{b}^g$ $d_x$ times.\nThe ranker and reader components share the same Match-LSTM module with two separate prediction heads in the last layer, resulting in $\\mathbf{H}^\\text{rank}$ and $\\mathbf{H}^\\text{reader}$.\nThe overview of R^3 (reinforced ranker-reader) architecture. Both components share the same Match-LSTM module. (Image source:\nWang, et al., 2017\n)\nThe retriever runs a max-pooling operation per passage and then aggregates to output a probability of each passage entailing the answer.\n$$\n\\begin{aligned}\n\\mathbf{u}_i &= \\text{max-pooling}(\\mathbf{H}^\\text{rank}_i) \\in \\mathbb{R}^l \\\\\n\\mathbf{C} &= \\text{tanh}(\\mathbf{W}^c[\\mathbf{u}_1;\\dots;\\mathbf{u}_N] + \\mathbf{b}^c \\otimes \\mathbf{e}_N) \\in \\mathbb{R}^{l \\times n} \\\\\n\\gamma &= \\text{softmax}(\\mathbf{w}^c \\mathbf{C}) \\in \\mathbb{R}^n\n\\end{aligned}\n$$\nFinally, the retriever is viewed as a\npolicy\nto output action to sample a passage according to predicted $\\gamma$,\n$$\n\\pi(z \\vert x; \\theta^\\gamma) = \\gamma_z\n$$\nThe reader predicts the start position $\\beta^s$ and the end position $\\beta^e$ of the answer span. Two positions are computed in the same way, with independent parameters to learn. There are $V$ words in all the passages involved.\n$$\n\\begin{aligned}\n\\mathbf{H}^\\text{read} &= [\\mathbf{H}^\\text{read}_\\tau; \\mathbf{H}^\\text{read}_{\\text{neg}_1}; \\dots; \\mathbf{H}^\\text{read}_{\\text{neg}_n}] \\\\\n\\mathbf{F}^s &= \\text{tanh}(\\mathbf{W}^s \\mathbf{H}^\\text{read} + \\mathbf{b}^s \\otimes \\mathbf{e}_V) \\quad\n\\beta^s = \\text{softmax}(\\mathbf{w}^s \\mathbf{F}^s) \\in \\mathbb{R}^V \\\\\n\\mathbf{F}^e &= \\text{tanh}(\\mathbf{W}^e \\mathbf{H}^\\text{read} + \\mathbf{b}^e \\otimes \\mathbf{e}_V) \\quad\n\\beta^e = \\text{softmax}(\\mathbf{w}^e \\mathbf{F}^e) \\in \\mathbb{R}^V \\\\\nL(y \\vert z, x) &= -\\log(\\beta^s_{y_z^s})-\\log(\\beta^e_{y_z^e})\n\\end{aligned}\n$$\nwhere $y$ is the ground-truth answer and the passage $z$ is sampled by the retriever. $\\beta^s_{y_z^s}$ and $\\beta^s_{y_z^e}$ represent the probabilities of the start and end positions of $y$ in passage $z$.\nThe training objective for the end-to-end R^3 QA system is to minimize the negative log-likelihood of obtaining the correct answer $y$ given a question $x$,\n$$\n\\begin{aligned}\n\\mathcal{J}(\\theta) &= -\\mathbb{E}_{z\\sim\\pi(.\\vert x)} [L(y \\vert z, x)] \\\\\n\\nabla \\mathcal{J}(\\theta) \n&= - \\nabla_\\theta \\sum_z \\pi(z \\vert x) L(y \\vert z, x) \\\\\n&= - \\sum_z \\big( L(y \\vert z, x) \\nabla_\\theta\\pi(z \\vert x) + \\pi(z \\vert x) \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&= - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\color{red}{L(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)} + \\nabla_\\theta L(y \\vert z, x) \\big) \\\\\n&\\approx - \\mathbb{E}_{z\\sim\\pi(.\\vert x)} \\big( \\underbrace{\\color{red}{R(y \\vert z, x)\\nabla_\\theta\\log\\pi(z \\vert x)}}_\\text{REINFORCE} + \\nabla_\\theta L(y \\vert z, x) \\big)\n\\end{aligned}\n$$\nEssentially in training, given a passage $z$ sampled by the retriever, the reader is trained by gradient descent while the retriever is trained by\nREINFORCE\nusing $L(y \\vert z, x)$ as the reward function. However, $L(y \\vert z, x)$ is not bounded and may introduce a lot of variance. The paper replaces the reward with a customized scoring function by comparing the ground truth $y$ and the answer extracted by the reader $\\hat{y}$:\n$$\nR(y, \\hat{y} \\vert z) = \\begin{cases}\n2 & \\text{if } y = \\hat{y}\\\\\nf1(y, \\hat{y}) & \\text{if } y \\cap \\hat{y} = \\varnothing \\\\\n-1 & \\text{otherwise}\n\\end{cases}\n$$\nThe workflow of R^3 training process. (Image source:\nacl2020-openqa-tutorial/slides/part4\n)\nORQA\n(“Open-Retrieval Question-Answering”;\nLee et al., 2019\n) jointly learns a retriever + reader QA model to optimize marginal log-likelihood of obtaining correct answers in a supervised manner. No explicit “black-box” IR system is involved. Instead, it is capable of retrieving any text in an open corpus. During training, ORQA does not need ground-truth context passages (i.e. reading comprehension datasets) but only needs (question, answer) string pairs. Both retriever and reader components are based on BERT, but not shared.\nAn illustration of the retriever component in ORQA. (Image source: replotted based on one slide in\nacl2020-openqa-tutorial/slides/part5\n)\nAll the evidence blocks are ranked by a retrieval score, defined as the inner product of BERT embedding vectors of the\n[CLS]\ntoken of the question $x$ and the evidence block $z$. Note that the encoders for questions and context are independent.\n$$\n\\begin{aligned}\nh_x &= \\mathbf{W}_x \\text{BERT}_x(x)^{\\mathtt{[CLS]}} \\\\\nh_z &= \\mathbf{W}_z \\text{BERT}_z(z)^{\\mathtt{[CLS]}} \\\\\nS_\\text{retr}(z, x) &= h_x^\\top h_z\n\\end{aligned}\n$$\nThe retriever module is pretrained with\nInverse Cloze Task (ICT)\n, which is to predict the context given a sentence, opposite to the standard\nCloze Task\n. The ICT objective is to maximize the retrieval score of the correct context $z$ given a random sentence $x$:\n$$\nL_\\text{ICT} = p_\\text{early}(z \\vert x) = \\frac{\\exp(S_\\text{retr}(z, x))}{\\sum_{z'\\in\\text{BATCH}(\\mathcal{Z})} \\exp(S_\\text{retr}(z', x))}\n$$\nwhere $\\text{BATCH}(\\mathcal{Z})$ is the set of evidence blocks in the same batch used as sampled negatives.\nAfter such pretraining, the BERT retriever is expected to have representations good enough for evidence retrieval. Only the question encoder needs to be fine-tuned for answer extraction. In other words, the evidence block encoder (i.e., $\\mathbf{W}_z$ and $\\text{BERT}_z$) is fixed and thus all the evidence block encodings can be pre-computed with support for\nfast Maximum Inner Product Search (MIPS)\n.\nAn illustration of the reader component in ORQA. (Image source:\nacl2020-openqa-tutorial/slides/part5\n)\nThe reader follows the same design as in the original\nBERT RC\nexperiments. It learns in a supervised manner, while the parameters of the evidence block encoder are fixed and all other parameters are fine-tuned. Given a question $x$ and a gold answer string $y$, the reader loss contains two parts:\n$$\n\\mathcal{L}(x, y) = \\mathcal{L}_\\text{early}(x, y) + \\mathcal{L}_\\text{full}(x, y)\n$$\n(1) Find all correct text spans within top $k$ evidence blocks and optimize for the marginal likelihood of a text span $s$ that matches the true answer $y$:\n$$\n\\begin{aligned}\nh_s &= \\text{BERT}_R(x, y)^{(\\text{START}(s))} \\\\\nh_e &= \\text{BERT}_R(x, y)^{(\\text{END}(s))} \\\\\nS_\\text{read}(z, s, x) &= \\text{MLP}([h_s; h_e]) \\\\\np(z, s \\vert x) &= \\frac{\\exp(S_\\text{read}(z, s, x))}{\\sum_{z'\\in\\text{TOP}(k)} \\sum_{s'\\in z'} \\exp(S_\\text{read}(z', s', x))} \\\\\nL_\\text{full}(x, y) &= - \\log \\sum_{\\substack{z \\in \\text{TOP}(k)\\\\ s \\in z}} \\sum_{y=\\text{TEXT}(s)} p(z, s \\vert x)\n\\end{aligned}\n$$\nwhere $y=\\text{TEXT}(s)$ indicates whether the answer $y$ matches the text span $s$. $\\text{TOP}(k)$ is the top $k$ retrieved blocks according to $S_\\text{retr}(z, x)$. The paper sets $k=5$.\n(2) At the early stage of learning, when the retriever is not strong enough, it is possible none of the top $k$ blocks contains the answer. To avoid such sparse learning signals, ORQA considers a larger set of $c$ evidence blocks for more aggressive learning. The paper has $c=5000$.\n$$\nL_\\text{early}(x, y)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} p_\\text{early}(z\\vert x)\n= -\\log \\sum_{\\substack{z\\in \\text{TOP}(c)\\\\y\\in\\text{TEXT}(z)}} \\frac{\\exp(S_\\text{retr}(z, x)}{\\sum_{z'\\in\\text{TOP}(c)} \\exp(S_\\text{retr}(z', x)}\n$$\nSome issues in SQuAD dataset were discussed in the ORQA paper:\n\" The notable drop between development and test accuracy for SQuAD is a reflection of an artifact in the dataset—its 100k questions are derived from only 536 documents. Therefore, good retrieval targets are highly correlated between training examples, violating the IID assumption, and making it unsuitable for learned retrieval. We strongly suggest that those who are interested in end-to-end open-domain QA models no longer train and evaluate with SQuAD for this reason.\"\nREALM\n(“Retrieval-Augmented Language Model pre-training”;\nGuu et al., 2020\n) also jointly trains retriever + reader by optimizing the marginal likelihood of obtaining the true answer:\n$$\np(y \\vert x) \n= \\sum_{z \\in \\mathcal{Z}} \\underbrace{p(y \\vert x, z)}_\\text{reader} \\underbrace{p(z \\vert x)}_\\text{retriever}\n\\approx \\sum_{z \\in \\text{TOP}_k(\\mathcal{Z})} p(y \\vert x, z) p(z \\vert x)\n$$\nREALM is first unsupervised pre-trained with salient spans masking and then fine-tuned with QA data. (Image source:\nGuu et al., 2020\n).\nREALM computes two probabilities, $p(z \\vert x)$ and $p(y \\vert x, z)$, same as ORQA. However, different from ICT in ORQA, REALM upgrades the unsupervised pre-training step with several new design decisions, leading towards better retrievals. REALM pre-trains the model with Wikipedia or CC-News corpus.\nUse\nsalient span masking\n. Named entities and dates are identified. Then one of these “salient spans” is selected and masked. Salient span masking is a special case of MLM and works out well for QA tasks.\nAdd an\nempty null document\n. Because not every question demands a context document.\nNo trivial retrieval. The context document should not be same as the selected sentence with a masked span.\nApply the same ICT loss as in ORQA to encourage learning when the retrieval quality is still poor at the early stage of training.\n“Among all systems, the most direct comparison with REALM is ORQA (Lee et al., 2019), where the fine-tuning setup, hyperparameters and training data are identical. The improvement of REALM over ORQA is purely due to better pre-training methods.” — from REALM paper.\nBoth unsupervised pre-training and supervised fine-tuning optimize the same log-likelihood $\\log p(y \\vert x)$. Because the parameters of the retriever encoder for evidence documents are also updated in the process, the index for MIPS is changing. REALM asynchronously refreshes the index with the updated encoder parameters every several hundred training steps.\nBalachandran, et al. (2021)\nfound that REALM is significantly undertrained and REALM++ achieves great EM accuracy improvement (3-5%) by scaling up the model training with larger batch size and more retrieved documents for the reader to process.\nDPR\n(“Dense Passage Retriever”;\nKarpukhin et al., 2020\n,\ncode\n) argues that ICT pre-training could be too computationally expensive and the ORQA’s context encoder might be sub-optimal because it is not fine-tuned with question-answer pairs. DPR aims to resolve these two issues by only training a dense dual-encoder architecture for retrieval only from a small number of Q/A pairs, without any pre-training.\nSame as previous work, DPR uses the dot-product (L2 distance or cosine similarity also works) of BERT representations as retrieval score. The loss function for training the dual-encoder is the NLL of the positive passage, which essentially takes the same formulation as\nICT loss\nof ORQA. Note that both of them consider other passages in the same batch as the negative samples, named\nin-batch negative sampling\n. The main difference is that DPR relies on supervised QA data, while ORQA trains with ICT on unsupervised corpus. At the inference time, DPR uses\nFAISS\nto run fast MIPS.\nDPR did a set of comparison experiments involving several different types of negatives:\nRandom: any random passage from the corpus;\nBM25: top passages returned by BM25 which don’t contain the answer but match most question tokens;\nIn-batch negative sampling (“gold”): positive passages paired with other questions which appear in the training set.\nDPR found that using gold passages from the same mini-batch and one negative passage with high BM25 score works the best. To further improve the retrieval results, DPR also explored a setting where a BM25 score and a dense embedding retrieval score are linearly combined to serve as a new ranking function.\nOpen-book QA: Retriever-Generator\n#\nCompared to the retriever-reader approach, the retriever-generator also has 2 stages but the second stage is to generate free text directly to answer the question rather than to extract start/end position in a retrieved passage. Some paper also refer to this as\nGenerative question answering\n.\nThe retriever + generator QA framework combines a document retrieval system with a general language model.\nA pretrained LM has a great capacity of memorizing knowledge in its parameters, as shown above. However, they cannot easily modify or expand their memory, cannot straightforwardly provide insights into their predictions, and may produce non-existent illusion.\nPetroni et al. (2020)\nstudied how the retrieved relevant context can help a generative language model produce better answers. They found:\nAugmenting queries with relevant contexts dramatically improves the pretrained LM on unsupervised machine reading capabilities.\nAn off-the-shelf IR system is sufficient for BERT to match the performance of a supervised ODQA baseline;\nBERT’s\nNSP\npre-training strategy is a highly effective unsupervised mechanism in dealing with noisy and irrelevant contexts.\nThey pair the BERT model with different types of context, including adversarial (unrelated context), retrieved (by BM25), and generative (by an autoregressive language model of 1.4N parameters, trained on CC-NEWS). The model is found to be robust to adversarial context, but only when the question and the context are provided as two segments (e.g. separated by\n[SEP]\n). One hypothesis is related to NSP task: “BERT might learn to not condition across segments for masked token prediction if the NSP score is low, thereby implicitly detecting irrelevant and noisy contexts.”\nRAG\n(“Retrieval-Augmented Generation”;\nLewis et al., 2020\n) combines pre-trained parametric (language model) and non-parametric memory (external knowledge index) together for language generation. RAG can be fine-tuned on any seq2seq task, whereby both the retriever and the sequence generator are jointly learned. They found that unconstrained generation outperforms previous extractive approaches.\nRAG consists of a retriever model $p_\\eta(z \\vert x)$ and a generator model $p_\\theta(y_i \\vert x, z, y_{1:i-1})$:\nThe retriever uses the input sequence $x$ to retrieve text passages $z$, implemented as a\nDPR\nretriever. $\\log p_\\eta(z \\vert x) \\propto E_z(z)^\\top E_x(x)$.\nThe generator uses $z$ as additional context when generating the target sequence $y$, where the context and the question are simply concatenated.\nDepending on whether using the same or different retrieved documents for each token generation, there are two versions of RAG:\n$$\n\\begin{aligned}\np_\\text{RAG-seq}(y \\vert x) &= \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z \\vert x) \\prod_i^N p_\\theta(y_i \\vert x, z, y_{1:i-1}) \\\\\np_\\text{RAG-token}(y \\vert x) &= \\prod_i^N \\sum_{z \\in \\text{TOP}_k(p_\\eta(.\\vert x))} p_\\eta(z_i\\vert x) p_\\theta(y_i \\vert x, z_i, y_{1:i-1})\n\\end{aligned}\n$$\nThe retriever + generator in RAG is jointly trained to minimize the NLL loss, $\\mathcal{L}_\\text{RAG} = \\sum_j -\\log p(y_j \\vert x_j)$. Updating the passage encoder $E_z(.)$ is expensive as it requires the model to re-index the documents for fast MIPS. RAG does not find fine-tuning $E_z(.)$ necessary (like in\nORQA\n) and only updates the query encoder + generator.\nAn illustration of retrieval-augmented generation (RAG) architecture. (Image source:\nLewis et al., 2020\n)\nAt decoding/test time, RAG-token can be evaluated via a\nbeam search\n. RAG-seq cannot be broken down into a set of per-token likelihood, so it runs beam search for each candidate document $z$ and picks the one with optimal $p_\\theta(y_i \\vert x, z, y_{1:i-1})$.\nThe\nFusion-in-Decoder\napproach, proposed by\nIzacard & Grave (2020)\nis also based on a pre-trained T5. It works similar to RAG but differently for how the context is integrated into the decoder.\nRetrieve top $k$ related passage of 100 words each, using BM25 or DPR.\nEach retrieved passage and its title are concatenated with the question using special tokens like\nquestion:\n,\ntitle:\nand\ncontext:\nto indicate the content differences.\nEach retrieved passage is processed independently and later combined in the decoder. Processing passages independently in the encoder allows us to parallelize the computation. OTOH, processing them jointly encourages better aggregation of multiple pieces of evidence. The aggregation part is missing in extractive approaches.\nNote that they did fine-tune the pretrained LM independently for each dataset.\nClosed-book QA: Generative Language Model\n#\nBig language models have been pre-trained on a large collection of unsupervised textual corpus. Given enough parameters, these models are able to memorize some factual knowledge within parameter weights. Therefore, we can use these models to do question-answering without explicit context, just like in a closed-book exam. The pre-trained language models produce\nfree text\nto respond to questions, no explicit reading comprehension.\nThe amount of computation used for training big language models of different sizes is getting big. (Image source:\nBrown et al., 2020\n).\nRoberts et al. (2020)\nmeasured the practical utility of a language model by fine-tuning a pre-trained model to answer questions without access to any external context or knowledge. They fine-tuned the\nT5\nlanguage model (same architecture as the original Transformer) to answer questions without inputting any additional information or context. Such setup enforces the language model to answer questions based on “knowledge” that it internalized during pre-training.\nT5 is first pre-trained with salient span masking and then fine-tuned for each QA dataset to produce answers in free text. (Image source:\nRoberts et al. 2020\n)\nThe original T5 models were pre-trained on a multi-task mixture including an unsupervised\n“masked language modeling”\n(MLM) tasks on the C4 (“Colossal Clean Crawled Corpus”) dataset as well as fine-tuned altogether with supervised translation, summarization, classification, and reading comprehension tasks.\nRoberts, et al. (2020)\ntook a pre-trained T5 model and continued pre-training with\nsalient span masking\nover Wikipedia corpus, which has been found to substantially boost the performance for ODQA. Then they fine-tuned the model for each QA datasets independently.\nWith a pre-trained T5 language model +  continue pre-training with salient spans masking + fine-tuning for each QA dataset,\nIt can attain competitive results in open-domain question answering without access to external knowledge.\nA larger model can obtain better performance. For example, a T5 with 11B parameters is able to match the performance with\nDPR\nwith 3 BERT-base models, each with 330M parameters.\nInterestingly, fine-tuning is not strictly necessary. GPT3 (\nBrown et al., 2020\n) has been evaluated on the closed book question answering task\nwithout any gradient updates or fine-tuning\n. During evaluation, the few-shot, one-shot and zero-shot settings here only refer to how many demonstrations are provided as context in the text input:\n“few-shot learning”: GPT3 is allowed to take as many demonstrations as what can fit into the model’s context window (typically 10 to 100).\n“one-shot learning”: only one demonstration is provided.\n“zero-shot learning”: no demonstrations are allowed and only an instruction in natural language is given to the model.\nThe performance grows with the model size. On the TriviaQA dataset, GPT3 evaluation with demonstrations can match or exceed the performance of SOTA baseline with fine-tuning.\nGPT3's performance on TriviaQA grows smoothly with the model size. More demonstrations lead to better performance. (Image source:\nBrown et al., 2020\n).\nCheck out this cool example in OpenAI API\nplayground viewer\n. The model is able to answer factal questions in short answer and not to make up things when the model does not know the answer. I added the last two questions and asked the model to respond with\nA:\n. The API is still in beta version, so you might need to\napply\nto get on the wait list.\nQ: Who is Batman?\nA: Batman is a fictional comic book character.\n##\nQ: What is torsalplexity?\nA: ?\n##\nQ: What is Devz9?\nA: ?\n##\nQ: Who is George Lucas?\nA: George Lucas is American film director and producer famous for creating Star Wars.\n##\nQ: What is the capital of California?\nA: Sacramento.\n##\nQ: What orbits the Earth?\nA: The Moon.\n##\nQ: Who is Fred Rickerson?\nA: ?\n##\nQ: What is an atom?\nA: An atom is a tiny particle that makes up everything.\n##\nQ: Who is Alvan Muntz?\nA: ?\n##\nQ: What is Kozar-09?\nA: ?\n##\nQ: How many moons does Mars have?\nA: Two, Phobos and Deimos.\n##\nQ: What is COVID-19?\nA: ?\n##\nQ: What is H1N1?\nA: H1N1 is a strain of influenza.\nRelated Techniques\n#\nFast Maximum Inner Product Search (MIPS)\n#\nMIPS (maximum inner product search) is a crucial component in many open-domain question answering models. In retriever + reader/generator framework, a large number of passages from the knowledge source are encoded and stored in a memory. A retrieval model is able to query the memory to identify the top relevant passages which have the maximum inner product with the question’s embedding.\nWe need fast MIPS because the number of precomputed passage representations can be gigantic. There are several ways to achieve fast MIPS at run time, such as\nasymmetric LSH\n,\ndata-dependent hashing\n,  and\nFAISS\n.\nLanguage Model Pre-training\n#\nTwo pre-training tasks are especially helpful for QA tasks, as we have discussed above.\nInverse Cloze Task\n(proposed by\nORQA\n): The goal of\nCloze Task\nis to predict masked-out text based on its context. The prediction of Inverse Cloze Task (ICT) is in the reverse direction, aiming to predict the context given a sentence. In the context of QA tasks, a random sentence can be treated as a pseudo-question, and its context can be treated as pseudo-evidence.\nSalient Spans Masking\n(proposed by\nREALM\n): Salient span masking is a special case for MLM task in language model training. First, we find\nsalient spans\nby using a tagger to identify named entities and a regular expression to identify dates. Then one of the detected salient spans is selected and masked. The task is to predict this masked salient span.\nSummary\n#\nModel\nRetriever\nReader / Generator\nPre-training / Fine-tuning\nEnd2end\nDrQA\nTF-IDF\nBi-directional LSTM\n–\nNo\nBERTserini\nAserini + BM25\nBERT without softmax layer\nFine-tune with SQuAD\nNo\nMulti-passage BERT\nElasticSearch + BM25\nMulti-passage BERT + Passage ranker\nNo\nR^3\nClassic IR + Match-LSTM\nMatch-LSTM\nYes\nORQA\nDot product of BERT embeddings\nBERT-RC\nInverse cloze task\nYes\nREALM\nDot product of BERT embeddings\nBERT-RC\nSalient span masking\nYes\nDPR\nDot product of BERT embeddings\nBERT-RC\nsupervised training with QA pairs\nYes\nDenSPI\nClassic + Neural IR\n–\nYes\nT5 + SSM\n–\nT5\nSSM on\nCommonCrawl\ndata + Fine-tuning on QA data\nYes\nGPT3\n–\nGPT3\nNSP on\nCommonCrawl\ndata\nYes\nRAG\nDPR retriever\nBART\nYes\nFusion-in-Decoder\nBM25 / DPR retriever\nTranformer\nNo\nA comparison of performance of several QA models on common QA datasets. On TriviaQA, two columns of results are reported, on the open domain test set (left) and on the hidden test set (right). (Image source:\nIzacard & Grave, 2020\n).\nCitation\n#\nCited as:\nWeng, Lilian. (Oct 2020). How to build an open-domain question answering system? Lil’Log. https://lilianweng.github.io/posts/2020-10-29-odqa/.\nOr\n@article{weng2020odqa,\n  title   = \"How to Build an Open-Domain Question Answering System?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Oct\"\n  url     = \"https://lilianweng.github.io/posts/2020-10-29-odqa/\"\n}\nAppendix: QA Datasets\n#\nSQuAD 2.0\n: the Stanford QA dataset.\nRACE\n: a reading comprehension dataset collected from English Examinations that are created for middle school and high school students.\nTREC QA\n: the TREC QA collections.\nMS MARCO\n: a QA dataset featuring 100,000 real Bing questions and a human generated answer.\nCuratedTREC\n: based on the benchmarks from the TREC QA tasks that have been curated by\nBaudis & Sedivy (2015)\n.\nGoogle Natural Questions\n:  contains real user questions issued to Google search, and answers found from Wikipedia by annotators.\nWebQuestions\n: designed for knowledge-base QA with answers restricted to Freebase entities.\nWikiQA\n: Bing query logs were used as the source of questions. Each question is then linked to a Wikipedia page that potentially contains the answer.\nWikiMovies\n: contains movie-related questions from the OMDb and MovieLens databases and where the questions can be answered using Wikipedia pages.\nWikiReading\n: to predict textual values from the structured knowledge base Wikidata by reading the text of the corresponding Wikipedia articles.\nTriviaQA\n: a reading comprehension dataset containing 95K question-answer pairs authored by trivia enthusiasts and independently gathered multiple evidence documents per question.\nJeopardy! Questions\n: contains 200,000+\nJeopardy!\nquestions.\nDeepMind Q&A Dataset\n: question/answer pairs from CNN and Daily Mail articles.\nbAbi\n: a rich collection of datasets for text understanding by Facebook.\nFEVER\n: for fact extraction and verification.\nSearchQA\n: question-answer pairs were crawled from from\nJ! Archive\n, and then augmented with text snippets from Google.\nQuasar-T\n: a collection of open-domain trivia questions and their answers obtained from various internet sources.\nQuiz bowl\n: contains data from a trivia competition called quiz bowl.\nAmbigNQ\n: ambiguous questions selected from NQ-OPEN dataset.\nQA-Overlap\n: a collections of overlapped answers/questions between train and test set for Natural Questions, TriviaQA, and WebQuestions.\nReferences\n#\n[1] Danqi Chen & Scott Yih.\n“ACL2020 Tutorial: Open-Domain Question Answering”\nJuly 2020.\n[2] Danqi Chen, et al.\n“Reading Wikipedia to Answer Open-Domain Questions”\nACL 2017. |\ncode\n[3] Shuohang Wang, et al.\n“R^3: Reinforced Ranker-Reader for Open-Domain Question Answering”\nAAAI 2018.\n[4] Jimmy Lin.\n“The neural hype and comparisons against weak baselines.”\nACM SIGIR Forum. Vol. 52. No. 2. 2019.\n[5] Wei Yang, et al.\n“End-to-End Open-Domain Question Answering with BERTserini”\nNAACL 2019.\n[6] Christopher Clark & Matt Gardner.\n“Simple and Effective Multi-Paragraph Reading Comprehension.”\narXiv:1710.10723 (2017).\n[7] Rodrigo Nogueira & Kyunghyun Cho.\n“Passage Re-ranking with BERT.”\narXiv preprint arXiv:1901.04085 (2019). |\ncode\n[8] Zhiguo Wang, et al.\n“Multi-passage BERT: A globally normalized BERT model for open-domain question answering.”\nEMNLP 2019.\n[9] Minjoon Seo et al.\n“Real-time open-domain question answering with dense-sparse phrase index.”\nACL 2019.\n[10] Kenton Lee, et al.\n“Latent Retrieval for Weakly Supervised Open Domain Question Answering”\nACL 2019.\n[11] Kelvin Guu, et al.\n“REALM: Retrieval-Augmented Language Model Pre-Training”\narXiv:2002.08909 (2020).\n[12] Vladimir Karpukhin et al.\n“Dense passage retrieval for open-domain question answering.”\n. EMNLP 2020. |\ncode\n[13] Patrick Lewis et al.\n“Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”\narXiv:2005.11401 (2020).\n[14] Adam Roberts, et al.\n“How Much Knowledge Can You Pack Into the Parameters of a Language Model?”\nEMNLP 2020.\n[15] Tom Brown, et al.\n“Language models are few-shot learners.”\narXiv:2005.14165 (2020).\n[16] Fabio Petroni, et al.\n“How Context Affects Language Models’ Factual Predictions”\nAKBC 2020.\n[17] Gautier Izacard & Edouard Grave.\n“Leveraging passage retrieval with generative models for open domain question answering.”\narXiv:2007.01282 (2020).\n[18]\n“Dive into deep learning: Beam search”\n[19] Patrick Lewis, et al.\n“Question and Answer Test-Train Overlap in Open-Domain Question Answering Datasets”\narXiv:2008.02637 (2020). |\ndata\n[20] Hervé Jegou, et al.\n“Faiss: A library for efficient similarity search”\nMar 2017.\n[21] Vidhisha Balachandran, et al.\n“Simple and Efficient ways to Improve REALM.”\narXiv:2104.08710 (2021).",
            "metadata": {
              "title": "How to Build an Open-Domain Question Answering System? | Lil'Log",
              "description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "keywords": "nlp, language-model, attention, transformer",
              "author": "Lilian Weng",
              "og:title": "How to Build an Open-Domain Question Answering System?",
              "og:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
              "twitter:card": "summary",
              "twitter:title": "How to Build an Open-Domain Question Answering System?",
              "twitter:description": "[Updated on 2020-11-12: add an example on closed-book factual QA using OpenAI API (beta).\nA model that can answer any question with regard to factual knowledge can lead to many useful and practical applications, such as working as a chatbot or an AI assistant🤖. In this post, we will review several common approaches for building such an open-domain question answering system.",
              "article:section": "posts",
              "article:published_time": "2020-10-29T00:00:00+00:00",
              "article:modified_time": "2020-10-29T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/2cf34df8cd69/code/body-000.txt",
                "chars": 105,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-001.txt",
                "chars": 656,
                "language": "text"
              },
              {
                "file": "attachments/2cf34df8cd69/code/body-002.txt",
                "chars": 263,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "bytes": 661245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7efefadad7e7dd1bd368.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-summary.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "bytes": 173461,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ef8c4099815df32d696d.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retriever-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "bytes": 192230,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-a2c96b21ecb7e2fe5261.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERTserini-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "bytes": 180723,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-9d359913e38042c21f68.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/DenSPI-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "bytes": 131727,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-658614a9a3e7c1d7b935.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/BERT-RC.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "bytes": 337530,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-eaf24c5188513fae50ed.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-arch.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "bytes": 124437,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-ff31b70ac499e0b32939.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/R^3-reward-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "bytes": 865287,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-2e1a4cd54853b0630bf6.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-retriever.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "bytes": 553919,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-7826a791054014f6fcfb.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/ORQA-reader.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "bytes": 260572,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-d37427b8abf7df28ba56.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/REALM-train.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "bytes": 198348,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-1debd5c40323ec83577c.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-retiever-generator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "bytes": 290218,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-76ae01d2ac36750aac13.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/RAG.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "bytes": 145311,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-cb02352f1fcc5796b966.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/LM-compute.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "bytes": 201245,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-4a06ae2c872925f426c9.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/T5_SSM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "bytes": 329545,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-592734de78cf202658cc.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/GPT3-triviaqa.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "bytes": 244182,
                "reused": false,
                "local_path": "attachments/2cf34df8cd69/images/body-f4f90d0aeb9507c08585.png",
                "src": "https://lilianweng.github.io/posts/2020-10-29-odqa/QA-results.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2008.02637",
                "label": "Lewis, et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/QA-Overlap",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.00051",
                "label": "Chen et al., 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DrQA",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tf%E2%80%93idf",
                "label": "TF-IDF",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Vector_space_model",
                "label": "vector space model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1902.01718",
                "label": "Yang et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/castorini/anserini",
                "label": "Anserini",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Okapi_BM25",
                "label": "BM25",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1908.08167",
                "label": "Wang et al., 2019",
                "type": "a"
              },
              {
                "href": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "label": "Deerwester et al., 1990",
                "type": "a"
              },
              {
                "href": "https://www.aclweb.org/anthology/W11-0329/",
                "label": "Yih, et al., 2011",
                "type": "a"
              },
              {
                "href": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "label": "Lim, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.05807",
                "label": "Seo et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "Glove",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "Devlin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.10723",
                "label": "globally",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.04085",
                "label": "Nogueira & Cho, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.00023",
                "label": "Wang, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.08849",
                "label": "Match-LSTM",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part4-retriever-reader.pdf",
                "label": "acl2020-openqa-tutorial/slides/part4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.00300",
                "label": "Lee et al., 2019",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial/blob/master/slides/part5-dense-retriever-e2e-training.pdf",
                "label": "acl2020-openqa-tutorial/slides/part5",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Cloze Task",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08909",
                "label": "Guu et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.08710",
                "label": "Balachandran, et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004.04906",
                "label": "Karpukhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/DPR",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.04611",
                "label": "Petroni et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.11401",
                "label": "Lewis et al., 2020",
                "type": "a"
              },
              {
                "href": "https://d2l.ai/chapter_recurrent-modern/beam-search.html",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.01282",
                "label": "Izacard & Grave (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.08910",
                "label": "Roberts et al. (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "T5",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/playground/p/HMoho4552EHXrPLbmOIxpX4X",
                "label": "playground viewer",
                "type": "a"
              },
              {
                "href": "https://beta.openai.com/",
                "label": "apply",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "label": "asymmetric LSH",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1501.01062",
                "label": "data-dependent hashing",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/the-data/get-started/",
                "label": "CommonCrawl",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "BART",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD 2.0",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/qa.html",
                "label": "TREC QA",
                "type": "a"
              },
              {
                "href": "https://microsoft.github.io/msmarco/",
                "label": "MS MARCO",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-curated",
                "label": "CuratedTREC",
                "type": "a"
              },
              {
                "href": "https://link.springer.com/chapter/10.1007%2F978-3-319-24027-5_20",
                "label": "Baudis & Sedivy (2015)",
                "type": "a"
              },
              {
                "href": "https://ai.google.com/research/NaturalQuestions/dataset",
                "label": "Google Natural Questions",
                "type": "a"
              },
              {
                "href": "https://github.com/brmson/dataset-factoid-webquestions",
                "label": "WebQuestions",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/publication/wikiqa-a-challenge-dataset-for-open-domain-question-answering/",
                "label": "WikiQA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "WikiMovies",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research-datasets/wiki-reading",
                "label": "WikiReading",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/triviaqa/",
                "label": "TriviaQA",
                "type": "a"
              },
              {
                "href": "https://www.kaggle.com/tunguz/200000-jeopardy-questions",
                "label": "Jeopardy! Questions",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jeopardy!",
                "label": "Jeopardy!",
                "type": "a"
              },
              {
                "href": "https://cs.nyu.edu/~kcho/DMQA/",
                "label": "DeepMind Q&A Dataset",
                "type": "a"
              },
              {
                "href": "https://fever.ai/data.html",
                "label": "FEVER",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4ir-searchQA",
                "label": "SearchQA",
                "type": "a"
              },
              {
                "href": "https://j-archive.com/",
                "label": "J! Archive",
                "type": "a"
              },
              {
                "href": "https://github.com/bdhingra/quasar",
                "label": "Quasar-T",
                "type": "a"
              },
              {
                "href": "https://people.cs.umass.edu/~miyyer/qblearn/index.html",
                "label": "Quiz bowl",
                "type": "a"
              },
              {
                "href": "https://nlp.cs.washington.edu/ambigqa/",
                "label": "AmbigNQ",
                "type": "a"
              },
              {
                "href": "https://github.com/danqi/acl2020-openqa-tutorial",
                "label": "“ACL2020 Tutorial: Open-Domain Question Answering”",
                "type": "a"
              },
              {
                "href": "https://github.com/nyu-dl/dl4marco-bert",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://engineering.fb.com/2017/03/29/data-infrastructure/faiss-a-library-for-efficient-similarity-search/",
                "label": "“Faiss: A library for efficient similarity search”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:28Z",
            "source_url": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2008.02637",
                "bytes": 146376,
                "reused": false,
                "local_path": "papers/repair/8ad962c997b08e996dd4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00051",
                "bytes": 2048034,
                "reused": false,
                "local_path": "papers/repair/d0f7a3fcc176ba86400e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1902.01718",
                "bytes": 1306033,
                "reused": false,
                "local_path": "papers/repair/5601bffbfa0b981b6331.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1908.08167",
                "bytes": 259305,
                "reused": false,
                "local_path": "papers/repair/fa52b7dcb76039375378.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf",
                "content_type": "text/html; charset=UTF-8",
                "retried_at": "2026-10-20T17:40:15Z"
              },
              {
                "status": "ok",
                "url": "https://sigir.org/wp-content/uploads/2019/01/p040.pdf",
                "bytes": 134597,
                "reused": false,
                "local_path": "papers/repair/4ab646693162802f854c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.05807",
                "bytes": 359767,
                "reused": false,
                "local_path": "papers/repair/747eb29b4590aa97c069.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.10723",
                "bytes": 452153,
                "reused": false,
                "local_path": "papers/repair/28189a7ac5e78a81e437.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.04085",
                "bytes": 179659,
                "reused": false,
                "local_path": "papers/repair/05b68ab5e80214473436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.00023",
                "bytes": 467789,
                "reused": false,
                "local_path": "papers/repair/2b555bf087dc301d5ab3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.08849",
                "bytes": 560057,
                "reused": false,
                "local_path": "papers/repair/4a818c3029a76aba9073.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part4-retriever-reader.pdf",
                "bytes": 7788557,
                "reused": false,
                "local_path": "papers/repair/8edd53d3acc87ec95877.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.00300",
                "bytes": 324074,
                "reused": false,
                "local_path": "papers/repair/21d0f741ef22e8382844.pdf"
              },
              {
                "status": "ok",
                "url": "https://raw.githubusercontent.com/danqi/acl2020-openqa-tutorial/master/slides/part5-dense-retriever-e2e-training.pdf",
                "bytes": 5923321,
                "reused": false,
                "local_path": "papers/repair/09e19d59295cafdb35c6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08909",
                "bytes": 419037,
                "reused": false,
                "local_path": "papers/repair/9325ba1ac58281154385.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.08710",
                "bytes": 314281,
                "reused": false,
                "local_path": "papers/repair/4afe57efbece847b61fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2004.04906",
                "bytes": 383508,
                "reused": true,
                "local_path": "papers/repair/8b76986dbe24871ab2c9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.04611",
                "bytes": 599811,
                "reused": false,
                "local_path": "papers/repair/d1464f0dd0e30968c8ab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.11401",
                "bytes": 885323,
                "reused": true,
                "local_path": "papers/repair/fc8d32f196e0f0c27ffb.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.01282",
                "bytes": 326612,
                "reused": false,
                "local_path": "papers/repair/63195f1903a8ee821e29.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.08910",
                "bytes": 310594,
                "reused": false,
                "local_path": "papers/repair/4f3639d8e3ec9d8f612f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5329-asymmetric-lsh-alsh-for-sublinear-time-maximum-inner-product-search-mips.pdf",
                "bytes": 429326,
                "reused": false,
                "local_path": "papers/repair/615a9235abb8f6f533bd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1501.01062",
                "bytes": 849475,
                "reused": false,
                "local_path": "papers/repair/63f32442dc6c96976afe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 46975,
            "expected_body_images": 16,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "invalid_file_type",
            "raw_html": "attachments/2cf34df8cd69/pages/source.html",
            "local_html": "attachments/2cf34df8cd69/pages/article.html",
            "body_base_path": "attachments/2cf34df8cd69/pages/",
            "body_markdown_path": "attachments/2cf34df8cd69/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
          "status": "ok",
          "article_id": "4ceb83900555",
          "local_path": "series-follow/1601/repair/e7cc4652c4afc9c11bf9.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
              "bytes": 205910,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2795fb5ace8ffbc1b24d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
              "bytes": 483584,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1ad2438e764ecf66f44b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
              "bytes": 88034,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c8c63c3f68a56e1637ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
              "bytes": 791396,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cfd79c5354e69b23974e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
              "bytes": 464686,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3c61bc54c452df857d49.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
              "bytes": 412094,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/896ff9901d3559eccc2a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
              "bytes": 208079,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a68ed63975ef71160d3c.png"
            }
          ],
          "article": {
            "id": "4ceb83900555",
            "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "bytes": 205910,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-2795fb5ace8ffbc1b24d.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/sim2real-transfer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "bytes": 483584,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-1ad2438e764ecf66f44b.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/DR.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "bytes": 88034,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-c8c63c3f68a56e1637ef.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/learning-to-simulate.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "bytes": 791396,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-cfd79c5354e69b23974e.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/simopt.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "bytes": 464686,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-3c61bc54c452df857d49.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/RCAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "bytes": 412094,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-896ff9901d3559eccc2a.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/deception-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "bytes": 208079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/4ceb83900555/images/body-a68ed63975ef71160d3c.png",
                "src": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/ADR.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=DKe8FumoD4E",
                "src": "https://www.youtube.com/embed/DKe8FumoD4E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/4ceb83900555/videos/repair-DKe8FumoD4E.mp4",
                "bytes": 37082109,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "434.721000",
                "reused": false
              }
            ],
            "body_markdown": "In Robotics, one of the hardest problems is how to make your model transfer to the real world. Due to the sample inefficiency of deep RL algorithms and the cost of data collection on real robots, we often need to train models in a simulator which theoretically provides an infinite amount of data. However, the reality gap between the simulator and the physical world often leads to failure when working with physical robots. The gap is triggered by an inconsistency between physical parameters (i.e. friction, kp, damping, mass, density) and, more fatally, the incorrect physical modeling (i.e. collision between soft surfaces).\nTo close the sim2real gap, we need to improve the simulator and make it closer to reality. A couple of approaches:\nSystem identification\nSystem identification\nis to build a mathematical model for a physical system; in the context of RL, the mathematical model is the simulator. To make the simulator more realistic, careful calibration is necessary.\nUnfortunately, calibration is expensive. Furthermore, many physical parameters of the same machine might vary significantly due to temperature, humidity, positioning or its wear-and-tear in time.\nDomain adaptation\nDomain adaptation (DA)\nrefers to a set of transfer learning techniques developed to update the data distribution in sim to match the real one through a mapping or regularization enforced by the task model.\nMany DA models, especially for image classification or end-to-end image-based RL task, are built on adversarial loss or\nGAN\n.\nDomain randomization\nWith\ndomain randomization (DR)\n, we are able to create a variety of simulated environments with randomized properties and train a model that works across all of them.\nLikely this model can adapt to the real-world environment, as the real system is expected to be one sample in that rich distribution of training variations.\nBoth DA and DR are unsupervised. Compared to DA which requires a decent amount of real data samples to capture the distribution, DR may need\nonly a little or no\nreal data. DR is the focus of this post.\nConceptual illustrations of three approaches for sim2real transfer.\nWhat is Domain Randomization?\n#\nTo make the definition more general, let us call the environment that we have full access to (i.e. simulator)\nsource domain\nand the environment that we would like to transfer the model to\ntarget domain\n(i.e. physical world). Training happens in the source domain. We can control a set of $N$ randomization parameters in the source domain $e_\\xi$ with a configuration $\\xi$, sampled from a randomization space, $\\xi \\in \\Xi \\subset \\mathbb{R}^N$.\nDuring policy training, episodes are collected from source domain with randomization applied. Thus the policy is exposed to a variety of environments and learns to generalize. The policy parameter $\\theta$ is trained to maximize the expected reward $R(.)$ average across a distribution of configurations:\n$$\n\\theta^* = \\arg\\max_\\theta \\mathbb{E}_{\\xi \\sim \\Xi} [\\mathbb{E}_{\\pi_\\theta, \\tau \\sim e_\\xi} [R(\\tau)]]\n$$\nwhere $\\tau_\\xi$ is a trajectory collected in source domain randomized with $\\xi$. In a way,\n“discrepancies between the source and target domains are modeled as variability in the source domain.”\n(quote from\nPeng et al. 2018\n).\nUniform Domain Randomization\n#\nIn the original form of DR (\nTobin et al, 2017\n;\nSadeghi et al. 2016\n), each randomization parameter $\\xi_i$ is bounded by an interval, $\\xi_i \\in [\\xi_i^\\text{low}, \\xi_i^\\text{high}], i=1,\\dots,N$ and each parameter is uniformly sampled within the range.\nThe randomization parameters can control appearances of the scene, including but not limited to the followings (see Fig. 2). A model trained on simulated and randomized images is able to transfer to real non-randomized images.\nPosition, shape, and color of objects,\nMaterial texture,\nLighting condition,\nRandom noise added to images,\nPosition, orientation, and field of view of the camera in the simulator.\nImages captured in the training environment are randomized. (Image source:\nTobin et al, 2017\n)\nPhysical dynamics in the simulator can also be randomized (\nPeng et al. 2018\n). Studies have showed that a\nrecurrent\npolicy can adapt to different physical dynamics including the partially observable reality. A set of physical dynamics features include but are not limited to:\nMass and dimensions of objects,\nMass and dimensions of robot bodies,\nDamping, kp, friction of the joints,\nGains for the PID controller (P term),\nJoint limit,\nAction delay,\nObservation noise.\nWith visual and dynamics DR, at OpenAI Robotics, we were able to learn a policy that works on real dexterous robot hand (\nOpenAI, 2018\n). Our manipulation task is to teach the robot hand to rotate an object continously to achieve 50 successive random target orientations. The sim2real gap in this task is very large, due to (a) a high number of simultaneous contacts between the robot and the object and (b) imperfect simulation of object collision and other motions. At first, the policy could barely survive for more than 5 seconds without dropping the object. But with the help of DR, the policy evolved to work surprisingly well in reality eventually.\nWhy does Domain Randomization Work?\n#\nNow you may ask, why does domain randomization work so well? The idea sounds really simple. Here are two non-exclusive explanations I found most convincing.\nDR as Optimization\n#\nOne idea (\nVuong, et al, 2019\n) is to view learning randomization parameters in DR as a\nbilevel optimization\n. Assuming we have access to the real environment $e_\\text{real}$ and the randomization config is sampled from a distribution parameterized by $\\phi$, $\\xi \\sim P_\\phi(\\xi)$, we would like to learn a distribution on which a policy $\\pi_\\theta$ is trained on can achieve maximal performance in $e_\\text{real}$:\n$$\n\\begin{aligned}\n&\\phi^* = \\arg\\min_{\\phi} \\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real}) \\\\\n\\text{where } &\\theta^*(\\phi) = \\arg\\min_\\theta \\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)}[\\mathcal{L}(\\pi_\\theta; e_\\xi)]\n\\end{aligned}\n$$\nwhere $\\mathcal{L}(\\pi; e)$ is the loss function of policy $\\pi$ evaluated in the environment $e$.\nAlthough randomization ranges are hand-picked in uniform DR, it often involves domain knowledge and a couple rounds of trial-and-error adjustment based on the transfer performance. Essentially this is a manual optimization process on tuning $\\phi$ for the optimal $\\mathcal{L}(\\pi_{\\theta^*(\\phi)}; e_\\text{real})$.\nGuided domain randomization in the next section is largely inspired by this view, aiming to do bilevel optimization and learn the best parameter distribution automatically.\nDR as Meta-Learning\n#\nIn our learning dexterity project (\nOpenAI, 2018\n), we trained an LSTM policy to generalize across different environmental dynamics. We observed that once a robot achieved the first rotation, the time it needed for the following successes was much shorter. Also, a FF policy without memory was found not able to transfer to a physical robot. Both are evidence of the policy dynamically learning and adapting to a new environment.\nIn some ways, domain randomization composes a collection of different tasks. Memory in the recurrent network empowers the policy to achieve\nmeta-learning\nacross tasks and further work on a real-world setting.\nGuided Domain Randomization\n#\nThe vanilla DR assumes no access to the real data, and thus the randomization config is sampled as broadly and uniformly as possible in sim, hoping that the real environment could be covered under this broad distribution. It is reasonable to think of a more sophisticated strategy — replacing uniform sampling with guidance from\ntask performance\n,\nreal data\n, or\nsimulator\n.\nOne motivation for guided DR is to save computation resources by avoiding training models in unrealistic environments. Another is to avoid infeasible solutions that might arise from overly wide randomization distributions and thus might hinder successful policy learning.\nOptimization for Task Performance\n#\nSay we train a family of policies with different randomization parameters $\\xi \\sim P_\\phi(\\xi)$, where $P_\\xi$ is the distribution for $\\xi$ parameterized by $\\phi$. Later we decide to try every one of them on the downstream task in the target domain (i.e. control a robot in reality or evaluate on a validation set) to collect feedback. This feedback tells us how good a configuration $\\xi$ is and provides signals for optimizing $\\phi$.\nInspired by\nNAS\n,\nAutoAugment\n(\nCubuk, et al. 2018\n) frames the problem of learning best data augmentation operations (i.e.  shearing, rotation, invert, etc.) for image classification as an RL problem. Note that AutoAugment is not proposed for sim2real transfer, but falls in the bucket of DR guided by task performance. Individual augmentation configuration is tested on the evaluation set and the performance improvement is used as a reward to train a PPO policy. This policy outputs different augmentation strategies for different datasets; for example, for CIFAR-10 AutoAugment mostly  picks color-based transformations, while ImageNet prefers geometric based.\nRuiz (2019)\nconsidered the\ntask feedback\nas\nreward\nin RL problem and proposed a RL-based method, named “learning to simulate”, for adjusting $\\xi$. A policy is trained to predict $\\xi$ using performance metrics on the validation data of the main task as rewards, which is modeled as a multivariate Gaussian. Overall the idea is similar to AutoAugment, applying NAS on data generation. According to their experiments, even if the main task model is not converged, it still can provide a reasonable signal to the data generation policy.\nAn overview of the \"learning to simulate\" approach. (Image source:\nRuiz (2019)\n)\nEvolutionary algorithm is another way to go, where the\nfeedback\nis treated as\nfitness\nfor guiding evolution (\nYu et al, 2019\n). In this study, they used\nCMA-ES\n(covariance matrix adaptation evolution strategy) while fitness is the performance of a $\\xi$-conditional policy in target environment. In the appendix, they compared CMA-ES with other ways of modeling the dynamics of $\\xi$, including Bayesian optimization or a neural network. The main claim was those methods are not as stable or sample efficient as CMA-ES. Interestly, when modeling $P(\\xi)$ as a neural network, LSTM is found to notably outperform FF.\nSome believe that sim2real gap is a combination of appearance gap and content gap; i.e. most GAN-inspired DA models focus on appearance gap.\nMeta-Sim\n(\nKar, et al. 2019\n) aims to close the content gap by generating task-specific synthetic datasets. Meta-Sim uses self-driving car training as an example and thus the scene could be very complicated. In this case, the synthetic scenes are parameterized by a hierarchy of objects with properties (i.e., location, color) as well as relationships between objects. The hierarchy is specified by a probabilistic scene grammar akin to structure domain randomization (\nSDR\n;\nPrakash et al., 2018\n) and it is assumed to be known beforehand. A model $G$ is trained to augment the distribution of scene properties $s$ by following:\nLearn the prior first: pre-train $G$ to learn the identity function $G(s) = s$.\nMinimize MMD loss between the real and sim data distributions. This involves backpropagation through non-differentiable renderer. The paper computes it numerically by perturbing the attributes of $G(s)$.\nMinimize REINFORCE task loss when trained on synthetic data but evaluated on real data. Again, very similar to AutoAugment.\nUnfortunately, this family of methods are not suitable for sim2real case. Either an RL policy or an EA model requires a large number of real samples. And it is really expensive to include real-time feedback collection on a physical robot into the training loop. Whether you want to trade less computation resource for real data collection would depend on your task.\nMatch Real Data Distribution\n#\nUsing real data to guide domain randomization feels a lot like doing system identification or DA. The core idea behind DA is to improve the synthetic data to match the real data distribution. In the case of real-data-guided DR, we would like to learn the randomization parameters $\\xi$ that bring the state distribution in simulator close to the state distribution in the real world.\nThe\nSimOpt\nmodel (\nChebotar et al, 2019\n) is trained under an initial randomization distribution $P_\\phi(\\xi)$ first, getting a policy $\\pi_{\\theta, P_\\phi}$. Then this policy is deployed on both simulator and physical robot to collect trajectories $\\tau_\\xi$ and $\\tau_\\text{real}$ respectively. The optimization objective is to minimize the discrepancy between sim and real trajectories:\n$$\n\\phi^* = \\arg\\min_{\\phi}\\mathbb{E}_{\\xi \\sim P_\\phi(\\xi)} [\\mathbb{E}_{\\pi_{\\theta, P_\\phi}} [D(\\tau_\\text{sim}, \\tau_\\text{real})]]\n$$\nwhere $D(.)$ is a trajectory-based discrepancy measure. Like the “Learning to simulate” paper, SimOpt also has to solve the tricky problem of how to propagate gradient through non-differentiable simulator. It used a method called\nrelative entropy policy search\n, see paper for more details.\nAn overview of the SimOpt framework. (Image source:\nChebotar et al, 2019\n)\nRCAN\n(\nJames et al., 2019\n), short for “Randomized-to-Canonical Adaptation Networks”, is a nice combination of DA and DR for end-to-end RL tasks. An image-conditional GAN (\ncGAN\n) is trained in sim to translate a domain-randomized image into a non-randomized version (aka “canonical version”). Later the same model is used to translate real images into corresponding simulated version so that the agent would consume consistent observation as what it has encountered in training. Still, the underlying assumption is that the distribution of domain-randomized sim images is broad enough to cover real-world samples.\nRCAN is an image-conditional generator that can convert a domain-randomized or real image into its corresponding non-randomized simulator version. (Image source:\nJames et al., 2019\n)\nThe RL model is trained end-to-end in a simulator to do vision-based robot arm grasping. Randomization is applied at each timestep, including the position of tray divider, objects to grasp, random textures, as well as the position, direction, and color of the lighting. The canonical version is the default simulator look. RCAN is trying to learn a generator\n$G$: randomized image $\\to$ {canonical image, segmentation, depth}\nwhere segmentation masks and depth images are used as auxiliary tasks. RCAN had a better zero-shot transfer compared to uniform DR, although both were shown to be worse than the model trained on only real images. Conceptually, RCAN operates in a reverse direction of\nGraspGAN\nwhich translates synthetic images into real ones by domain adaptation.\nGuided by Data in Simulator\n#\nNetwork-driven domain randomization (\nZakharov et al., 2019\n), also known as\nDeceptionNet\n,  is motivated by learning which randomizations are actually useful to bridge the domain gap for image classification tasks.\nRandomization is applied through a set of deception modules with encoder-decoder architecture. The deception modules are specifically designed to transform images; such as change backgrounds, add distortion, change lightings, etc. The other recognition network handles the main task by running classification on transformed images.\nThe training involves two steps:\nWith the recognition network fixed,\nmaximize the difference\nbetween the prediction and the labels by applying reversed gradients during backpropagation.  So that the deception module can learn the most confusing tricks.\nWith the deception modules fixed, train the recognition network with input images altered.\nHow DeceptionNet works. (Image source:\nZakharov et al., 2019\n)\nThe feedback for training deception modules is provided by the downstream classifier. But rather than trying to maximize the task performance like\nthe section\nabove, the randomization modules aim to create harder cases. One big disadvantage is you need to manually design different deception modules for different datasets or tasks, making it not easily scalable. Given the fact that it is zero-shot, the results are still worse than SOTA DA methods on MNIST and LineMOD.\nSimilarly, Active domain randomization (\nADR\n;\nMehta et al., 2019\n) also relies on sim data to create harder training samples. ADR searches for the\nmost informative\nenvironment variations within the given randomization ranges, where the\ninformativeness\nis measured as the discrepancies of policy rollouts in randomized and reference (original, non-randomized) environment instances. Sounds a bit like\nSimOpt\n? Well, noted that SimOpt measures the discrepancy between sim and real rollouts, while ADR measures between randomized and non-randomized sim, avoiding the expensive real data collection part.\nHow active domain randomization (ADR) works. (Image source:\nMehta et al., 2019\n)\nPrecisely the training happens as follows:\nGiven a policy, run it on both reference and randomized envs and collect two sets of trajectories respectively.\nTrain a discriminator model to tell whether a rollout trajectory is randomized apart from reference run. The predicted $\\log p$ (probability of being randomized) is used as reward. The more different randomized and reference rollouts, the easier the prediction, the higher the reward.\nThe intuition is that if an environment is easy, the same policy agent can produce similar trajectories as in the reference one. Then the model should reward and explore hard environments by encouraging different behaviors.\nThe reward by discriminator is fed into\nStein Variational Policy Gradient\n(\nSVPG\n) particles, outputting a diverse set of randomization configurations.\nThe idea of ADR is very appealing with two small concerns. The similarity between trajectories might not be a good way to measure the env difficulty when running a stochastic policy. The sim2real results look unfortunately not as exciting, but the paper pointed out the win being ADR explores a smaller range of randomization parameters.\nCited as:\n@article{weng2019DR,\n  title   = \"Domain Randomization for Sim2Real Transfer\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-05-05-domain-randomization/\"\n}\nOverall, after reading this post, I hope you like domain randomization as much as I do :).\nReferences\n#\n[1] Josh Tobin, et al.\n“Domain randomization for transferring deep neural networks from simulation to the real world.”\nIROS, 2017.\n[2] Fereshteh Sadeghi and Sergey Levine.\n“CAD2RL: Real single-image flight without a single real image.”\narXiv:1611.04201 (2016).\n[3] Xue Bin Peng, et al.\n“Sim-to-real transfer of robotic control with dynamics randomization.”\nICRA, 2018.\n[4] Nataniel Ruiz, et al.\n“Learning to Simulate.”\nICLR 2019\n[5] OpenAI.\n“Learning Dexterous In-Hand Manipulation.”\narXiv:1808.00177 (2018).\n[6] OpenAI Blog.\n“Learning dexterity”\nJuly 30, 2018.\n[7] Quan Vuong, et al.\n“How to pick the domain randomization parameters for sim-to-real transfer of reinforcement learning policies?.”\narXiv:1903.11774 (2019).\n[8] Ekin D. Cubuk, et al.\n“AutoAugment: Learning augmentation policies from data.”\narXiv:1805.09501 (2018).\n[9] Wenhao Yu et al.\n“Policy Transfer with Strategy Optimization.”\nICLR 2019\n[10] Yevgen Chebotar et al.\n“Closing the Sim-to-Real Loop: Adapting Simulation Randomization with Real World Experience.”\nArxiv: 1810.05687 (2019).\n[11] Stephen James et al.\n“Sim-to-real via sim-to-sim: Data-efficient robotic grasping via randomized-to-canonical adaptation networks”\nCVPR 2019.\n[12] Bhairav Mehta et al.\n“Active Domain Randomization”\narXiv:1904.04762\n[13] Sergey Zakharov,et al.\n“DeceptionNet: Network-Driven Domain Randomization.”\narXiv:1904.02750 (2019).\n[14] Amlan Kar, et al.\n“Meta-Sim: Learning to Generate Synthetic Datasets.”\narXiv:1904.11621 (2019).\n[15] Aayush Prakash, et al.\n“Structured Domain Randomization: Bridging the Reality Gap by Context-Aware Synthetic Data.”\narXiv:1810.10093 (2018).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:23Z",
            "title": "Domain Randomization for Sim2Real Transfer | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/4ceb83900555/code/body-000.txt",
                "chars": 247,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.06537",
                "bytes": 2845918,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6324fd866141c7ac81b8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ee4f3b9eabf9f86e46ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201.pdf",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/02a398f494ca43a2a527.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.00177",
                "bytes": 4590851,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2d8f25b91674702104bf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1903.11774",
                "bytes": 105818,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/456e2e12a35a28b26012.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.09501",
                "bytes": 1138440,
                "reused": true,
                "local_path": "papers/repair/9a0542ec64439d672cc9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.02513",
                "bytes": 4665551,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/dfcff6ef3a5e91c549e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.11621",
                "bytes": 8958676,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bc0e2f30c9a21cc6e1d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.10093",
                "bytes": 6349645,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/27ba817b06ce2c0c5b10.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.05687",
                "bytes": 5492359,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5666402555506394cf09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.07252",
                "bytes": 11102844,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/26f2a2363d7689f5c25a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.07004",
                "bytes": 9323587,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/4ca4d0d250c09511b628.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1709.07857",
                "bytes": 6383296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/87d69e708982a5473230.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.02750",
                "bytes": 1752490,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f677145e4aa91af88479.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.04762",
                "bytes": 1973875,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7ab63dc695e0b6ed4be5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.02399",
                "bytes": 1321151,
                "reused": true,
                "local_path": "papers/repair/dd42530ceff4594ef267.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06907.pdf",
                "bytes": 4066798,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/18370e0f757f8e708185.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04201",
                "bytes": 9269949,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/fb94fedd3ee15e2dbb9d.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20048,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/4ceb83900555/pages/source.html",
            "local_html": "attachments/4ceb83900555/pages/article.html",
            "body_base_path": "attachments/4ceb83900555/pages/",
            "body_markdown_path": "attachments/4ceb83900555/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.06537",
                "label": "Peng et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06907",
                "label": "Tobin et al, 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1611.04201.pdf",
                "label": "Sadeghi et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.00177",
                "label": "OpenAI, 2018",
                "type": "a"
              },
              {
                "href": "https://www.youtube.com/embed/DKe8FumoD4E",
                "label": "",
                "type": "iframe"
              },
              {
                "href": "https://arxiv.org/abs/1903.11774",
                "label": "Vuong, et al, 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "meta-learning",
                "type": "a"
              },
              {
                "href": "https://ai.google/research/pubs/pub45826",
                "label": "NAS",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.09501",
                "label": "Cubuk, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.02513",
                "label": "Ruiz (2019)",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=H1g6osRcFQ",
                "label": "Yu et al, 2019",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/CMA-ES",
                "label": "CMA-ES",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.11621",
                "label": "Kar, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.10093",
                "label": "Prakash et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.05687",
                "label": "Chebotar et al, 2019",
                "type": "a"
              },
              {
                "href": "https://www.aaai.org/ocs/index.php/AAAI/AAAI10/paper/viewFile/1851/2264",
                "label": "relative entropy policy search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.07252",
                "label": "James et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.07004",
                "label": "cGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1709.07857",
                "label": "GraspGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.02750",
                "label": "Zakharov et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.04762",
                "label": "Mehta et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.02399",
                "label": "SVPG",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06907.pdf",
                "label": "“Domain randomization for transferring deep neural networks from simulation to the real world.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04201",
                "label": "“CAD2RL: Real single-image flight without a single real image.”",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=HJgkx2Aqt7",
                "label": "“Learning to Simulate.”",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/learning-dexterity/",
                "label": "“Learning dexterity”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
          "status": "ok",
          "article_id": "475f6d363978",
          "local_path": "series-follow/1601/repair/878d50dab98b4b51cc5c.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
              "bytes": 176077,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/22a9e6438726d336ffe1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
              "bytes": 852559,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a036ff1cba89bd8ca177.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
              "bytes": 189886,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/18722c930cf5c497d7b4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
              "bytes": 234856,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/68fbdff3da3a7b692d3a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
              "bytes": 405820,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/41e54ee7ec562394ded4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
              "bytes": 147376,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d6536618f786cd88a98d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
              "bytes": 82152,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e6b375e7ba5a5bff8ba1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
              "bytes": 157138,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f21c72c925e425e2c413.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
              "bytes": 227348,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/20cc8fbcc63711039176.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
              "bytes": 307054,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/844cb0884d62492c8431.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
              "bytes": 380120,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2beee1783718ce1e1233.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
              "bytes": 136228,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/841034ba340426dcc42f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
              "bytes": 403536,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/608e700d91e7d97d213c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
              "bytes": 359761,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/740a0454d4525705f3c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
              "bytes": 100940,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c04d9fc97a4006715831.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
              "bytes": 138999,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ebfcd764d9e484649bd7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
              "bytes": 266480,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ea47ad327c3e525d7680.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
              "bytes": 247091,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4bfe6aecad730ed414c3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
              "bytes": 128766,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dc1c1909a9278b076020.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
              "bytes": 352267,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f40298ff01af8fc9e4dc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
              "bytes": 127977,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2453003154b5219dd230.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
              "bytes": 89862,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/94f6d5d4f164d466c4fb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
              "bytes": 144054,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/827f8fb6a1866bbd0478.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
              "bytes": 191620,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f86a63f93973014347b7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
              "bytes": 582897,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/52ae3de20af990c921e3.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Neural Architecture Search",
            "keywords": "NAS,架构搜索,自动ML",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "publish_date": "2020-08",
            "corpus_stage": "预训练/SFT",
            "notes": "神经架构搜索综述",
            "id": "475f6d363978",
            "collected_at": "2026-10-02T14:13:15",
            "title": "Neural Architecture Search | Lil'Log",
            "body_markdown": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.\nAutomatically learning and evolving network topologies is not a new idea (\nStanley & Miikkulainen, 2002\n). In recent years, the pioneering work by\nZoph & Le 2017\nand\nBaker et al. 2017\nhas attracted a lot of attention into the field of Neural Architecture Search (NAS), leading to many interesting ideas for better, faster and more cost-efficient NAS methods.\nAs I started looking into NAS, I found this nice survey very helpful by\nElsken, et al 2019\n. They characterize NAS as a system with three major components, which is clean & concise, and also commonly adopted in other NAS papers.\nSearch space\n: The NAS search space defines a set of operations (e.g. convolution, fully-connected, pooling) and how operations can be connected to form valid network architectures. The design of search space usually involves human expertise, as well as unavoidably human biases.\nSearch algorithm\n: A NAS search algorithm samples a population of network architecture candidates. It receives the child model performance metrics as rewards (e.g. high accuracy, low latency) and optimizes to generate high-performance architecture candidates.\nEvaluation strategy\n: We need to measure, estimate, or predict the performance of a large number of proposed child models in order to obtain feedback for the search algorithm to learn. The process of candidate evaluation could be very expensive and many new methods have been proposed to save time or computation resources.\nThree main components of Neural Architecture Search (NAS) models.  (Image source:\nElsken, et al. 2019\nwith customized annotation in red)\nSearch Space\n#\nThe NAS search space defines a set of basic network operations and how operations can be connected to construct valid network architectures.\nSequential Layer-wise Operations\n#\nThe most naive way to design the search space for neural network architectures is to depict network topologies, either CNN or RNN, with a list of\nsequential layer-wise operations\n, as seen in the early work of\nZoph & Le 2017\n&\nBaker et al. 2017\n. The serialization of network representation requires a decent amount of expert knowledge, since each operation is associated with different layer-specific parameters and such associations need to be hardcoded. For example, after predicting a\nconv\nop, the model should output kernel size, stride size, etc; or after predicting an\nFC\nop, we need to see the number of units as the next prediction.\n(Top) A sequential representation of CNN. (Bottom) A sequential representation of the tree structure of a recurrent cell. (Image source:\nZoph & Le 2017\n)\nTo make sure the generated architecture is valid, additional rules might be needed (\nZoph & Le 2017\n):\nIf a layer is not connected to any input layer then it is used as the input layer;\nAt the final layer, take all layer outputs that have not been connected and concatenate them;\nIf one layer has many input layers, then all input layers are concatenated in the depth dimension;\nIf input layers to be concatenated have different sizes, we pad the small layers with zeros so that the concatenated layers have the same sizes.\nThe skip connection can be predicted as well, using an\nattention\n-style mechanism. At layer $i$ , an anchor point is added with $i−1$ content-based sigmoids to indicate which of the previous layers to be connected. Each sigmoid takes as input the hidden states of the current node $h_i$ and $i-1$ previous nodes $h_j, j=1, \\dots, i-1$ .\n$$\nP(\\text{Layer j is an input to layer i}) = \\text{sigmoid}(v^\\top \\tanh(\\mathbf{W}_\\text{prev} h_j + \\mathbf{W}_\\text{curr} h_i))\n$$\nThe sequential search space has a lot of representation power, but it is very large and consumes a ton of computation resources to exhaustively cover the search space. In the experiments by\nZoph & Le 2017\n, they were running 800 GPUs in parallel for 28 days and\nBaker et al. 2017\nrestricted the search space to contain at most 2\nFC\nlayers.\nCell-based Representation\n#\nInspired by the design of using repeated modules in successful vision model architectures (e.g. Inception, ResNet), the\nNASNet search space\n(\nZoph et al. 2018\n) defines the architecture of a conv net as the same cell getting repeated multiple times and each cell contains several operations predicted by the NAS algorithm. A well-designed cell module enables transferability between datasets. It is also easy to scale down or up the model size by adjusting the number of cell repeats.\nPrecisely, the NASNet search space learns two types of cells for network construction:\nNormal Cell\n: The input and output feature maps have the same dimension.\nReduction Cell\n: The output feature map has its width and height reduced by half.\nThe NASNet search space constrains the architecture as a repeated stack of cells. The cell architecture is optimized via NAS algorithms. (Image source:\nZoph et al. 2018\n)\nThe predictions for each cell are grouped into $B$ blocks ($B=5$ in the NASNet paper), where each block has 5 prediction steps made by 5 distinct softmax classifiers corresponding to discrete choices of the elements of a block. Note that the NASNet search space does not have residual connections between cells and the model only learns skip connections on their own within blocks.\n(a) Each cell consists of $B$ blocks and each block is predicted by 5 discrete decisions. (b) An concrete example of what operations can be chosen in each decision step.\nDuring the experiments, they discovered that a modified version of\nDropPath\n, named\nScheduledDropPath\n, significantly improves the final performance of NASNet experiments. DropPath stochastically drops out paths (i.e. edges with operations attached in NASNet) with a fixed probability. ScheduledDropPath is DropPath with a linearly increasing probability of path dropping during training time.\nElsken, et al (2019)\npoint out three major advantages of the NASNet search space:\nThe search space size is reduced drastically;\nThe\nmotif\n-based architecture can be more easily transferred to different datasets.\nIt demonstrates a strong proof of a useful design pattern of repeatedly stacking modules in architecture engineering. For example, we can build strong models by stacking residual blocks in CNN or stacking multi-headed attention blocks in Transformer.\nHierarchical Structure\n#\nTo take advantage of already discovered well-designed network\nmotifs\n, the NAS search space can be constrained as a hierarchical structure, as in\nHierarchical NAS\n(\nHNAS\n; (\nLiu et al 2017\n)). It starts with a small set of primitives, including individual operations like convolution operation, pooling, identity, etc. Then small sub-graphs (or “motifs”) that consist of primitive operations are recursively used to form higher-level computation graphs.\nA computation motif at level $\\ell=1, \\dots, L$ can be represented by $(G^{(\\ell)}, \\mathcal{O}^{(\\ell)})$, where:\n$\\mathcal{O}^{(\\ell)}$ is a set of operations, $\\mathcal{O}^{(\\ell)} = \\{ o^{(\\ell)}_1, o^{(\\ell)}_2, \\dots \\}$\n$G^{(\\ell)}$ is an adjacency matrix, where the entry $G_{ij}=k$ indicates that operation $o^{(\\ell)}_k$ is placed between node $i$ and $j$. The node indices follow\ntopological ordering\nin DAG, where the index $1$ is the source and the maximal index is the sink node.\n(Top) Three level-1 primitive operations are composed into a level-2 motif. (Bottom) Three level-2 motifs are plugged into a base network structure and assembled into a level-3 motif. (Image source:\nLiu et al 2017\n)\nTo build a network according to the hierarchical structure, we start from the lowest level $\\ell=1$ and recursively define the $m$-th motif operation at level $\\ell$ as\n$$\no^{(\\ell)}_m = \\text{assemble}\\Big( G_m^{(\\ell)}, \\mathcal{O}^{(\\ell-1)} \\Big)\n$$\nA hierarchical representation becomes $\\Big( \\big\\{ \\{ G_m^{(\\ell)} \\}_{m=1}^{M_\\ell} \\big\\}_{\\ell=2}^L, \\mathcal{O}^{(1)} \\Big), \\forall \\ell=2, \\dots, L$, where $\\mathcal{O}^{(1)}$ contains a set of primitive operations.\nThe $\\text{assemble}()$ process is equivalent to sequentially compute the feature map of node $i$ by aggregating all the feature maps of its predecessor node $j$ following the topological ordering:\n$$\nx_i = \\text{merge} \\big[ \\{ o^{(\\ell)}_{G^{(\\ell)}_{ij}}(x_j) \\}_{j < i} \\big], i = 2, \\dots, \\vert G^{(\\ell)} \\vert\n$$\nwhere $\\text{merge}[]$ is implemented as depth-wise concatenation in the\npaper\n.\nSame as NASNet, experiments in\nLiu et al (2017)\nfocused on discovering good cell architecture within a predefined “macro” structure with repeated modules. They showed that the power of simple search methods (e.g. random search or evolutionary algorithms) can be substantially enhanced using well-designed search spaces.\nCai et al (2018b)\npropose a tree-structure search space using path-level network transformation. Each node in a tree structure defines an\nallocation\nscheme for splitting inputs for child nodes and a\nmerge\nscheme for combining results from child nodes. The path-level network transformation allows replacing a single layer with a multi-branch motif if its corresponding merge scheme is add or concat.\nAn illustration of transforming a single layer to a tree-structured motif via path-level transformation operations. (Image source:\nCai et al. 2018b\n)\nMemory-bank Representation\n#\nA memory-bank representation of feed-forward networks is proposed by\nBrock et al. (2017)\nin\nSMASH\n. Instead of a graph of operations, they view a neural network as a system with multiple memory blocks which can read and write. Each layer operation is designed to: (1) read from a subset of memory blocks; (2) computes results; finally (3) write the results into another subset of blocks. For example, in a sequential model, a single memory block would get read and overwritten consistently.\nMemory-bank representation of several popular network architecture blocks. (Image source:\nBrock et al. 2017\n)\nSearch Algorithms\n#\nNAS search algorithms sample a population of child networks. It receives the child models’ performance metrics as rewards and learns to generate high-performance architecture candidates. You may a lot in common with the field of hyperparameter search.\nRandom Search\n#\nRandom search is the most naive baseline. It samples a valid architecture candidate from the search space\nat random\nand no learning model is involved. Random search has proved to be quite useful in hyperparameter search (\nBergstra & Bengio 2012\n). With a well-designed search space, random search could be a very challenging baseline to beat.\nReinforcement Learning\n#\nThe initial design of\nNAS\n(\nZoph & Le 2017\n) involves a RL-based controller for proposing child model architectures for evaluation. The controller is implemented as a RNN, outputting a variable-length sequence of tokens used for configuring a network architecture.\nA high level overview of NAS, containing a RNN controller and a pipeline for evaluating child models. (Image source:\nZoph & Le 2017\n)\nThe controller is trained as a\nRL task\nusing\nREINFORCE\n.\nAction space\n: The action space is a list of tokens for defining a child network predicted by the controller (See more in the above\nsection\n). The controller outputs\naction\n, $a_{1:T}$, where $T$ is the total number of tokens.\nReward\n: The accuracy of a child network that can be achieved at convergence is the reward for training the controller, $R$.\nLoss\n: NAS optimizes the controller parameters $\\theta$ with a REINFORCE loss. We want to maximize the expected reward (high accuracy) with the gradient as follows. The nice thing here with policy gradient is that it works even when the reward is non-differentiable.\n$$\n\\nabla_{\\theta} J(\\theta) = \\sum_{t=1}^T \\mathbb{E}[\\nabla_{\\theta} \\log P(a_t \\vert a_{1:(t-1)}; \\theta) R ]\n$$\nMetaQNN\n(\nBaker et al. 2017\n) trains an agent to sequentially choose CNN layers using\nQ-learning\nwith an\n$\\epsilon$-greedy\nexploration strategy and experience replay. The reward is the validation accuracy as well.\n$$\nQ^{(t+1)}(s_t,  a_t) = (1 - \\alpha)Q^{(t)}(s_t, a_t) + \\alpha (R_t + \\gamma \\max_{a \\in \\mathcal{A}} Q^{(t)}(s_{t+1},  a'))\n$$\nwhere a state $s_t$ is a tuple of layer operation and related parameters. An action $a$ determines the connectivity between operations. The Q-value is proportional to how confident we are in two connected operations leading to high accuracy.\nOverview of MetaQNN - designing CNN models with Q-Learning. (Image source:\nBaker et al. 2017\n)\nEvolutionary Algorithms\n#\nNEAT\n(short for\nNeuroEvolution of Augmenting Topologies\n) is an approach for evolving neural network topologies with\ngenetic algorithm (GA)\n, proposed by\nStanley & Miikkulainen\nin 2002. NEAT evolves both connection weights and network topology together. Each gene encodes the full information for configuring a network, including node weights and edges. The population grows by applying mutation of both weights and connections, as well as crossover between two parent genes. For more in neuroevolution, please refer to the in-depth\nsurvey\nby Stanley et al. (2019).\nMutations in the NEAT algorithm. (Image source: Fig 3 & 4 in\nStanley & Miikkulainen, 2002\n)\nReal et al. (2018)\nadopt the evolutionary algorithms (EA) as a way to search for high-performance network architectures, named\nAmoebaNet\n. They apply the\ntournament selection\nmethod, which at each iteration picks a best candidate out of a random set of samples and places its mutated offspring back into the population. When the tournament size is $1$, it is equivalent to random selection.\nAmoebaNet modified the tournament selection to favor\nyounger\ngenotypes and always discard the oldest models within each cycle. Such an approach, named\naging evolution\n, allows AmoebaNet to cover and explore more search space, rather than to narrow down on good performance models too early.\nPrecisely, in every cycle of the tournament selection with aging regularization (See Figure 11):\nSample $S$ models from the population and the one with highest accuracy is chosen as\nparent\n.\nA\nchild\nmodel is produced by mutating\nparent\n.\nThen the child model is trained, evaluated and added back into the population.\nThe oldest model is removed from the population.\nThe algorithm of aging evolution. (Image source:\nReal et al. 2018\n)\nTwo types of mutations are applied:\nHidden state mutation\n: randomly chooses a pairwise combination and rewires a random end such that there is no loop in the graph.\nOperation mutation\n: randomly replaces an existing operation with a random one.\nTwo types of mutations in AmoebaNet. (Image source:\nReal et al. 2018\n)\nIn their experiments, EA and RL work equally well in terms of the final validation accuracy, but EA has better anytime performance and is able to find smaller models. Here using EA in NAS is still expensive in terms of computation, as each experiment took 7 days with 450 GPUs.\nHNAS\n(\nLiu et al 2017\n) also employs the evolutionary algorithms (the original tournament selection) as their search strategy. In the\nhierarchical structure\nsearch space, each edge is an operation. Thus genotype mutation in their experiments is applied by replacing a random edge with a different operation. The replacement set includes an\nnone\nop, so it can alter, remove and add an edge. The initial set of genotypes is created by applying a large number of random mutations on “trivial” motifs (all identity mappings).\nProgressive Decision Process\n#\nConstructing a model architecture is a sequential process. Every additional operator or layer brings extra complexity. If we guide the search model to start the investigation from simple models and gradually evolve to more complex architectures, it is like to introduce\n“curriculum”\ninto the search model’s learning process.\nProgressive NAS\n(\nPNAS\n;\nLiu, et al 2018\n) frames the problem of NAS as a progressive procedure for searching models of increasing complexity. Instead of RL or EA, PNAS adopts a Sequential Model-based Bayesian Optimization (SMBO) as the search strategy. PNAS works similar to A* search, as it searches for models from simple to hard while simultaneously learning a surrogate function to guide the search.\nA* search algorithm\n(“best-first search”) is a popular algorithm for path finding. The problem is framed as finding a path of smallest cost from a specific starting node to a given target node in a weighted graph. At each iteration, A* finds a path to extend by minimizing: $f(n)=g(n)+h(n)$, where $n$ is the next node, $g(n)$ is the cost from start to $n$, and $h(n)$ is the heuristic function that estimates the minimum cost of going from node $n$ to the goal.\nPNAS uses the\nNASNet\nsearch space. Each block is specified as a 5-element tuple and PNAS only considers the element-wise addition as the step 5 combination operator, no concatenation. Differently, instead of setting the number of blocks $B$ at a fixed number, PNAS starts with $B=1$, a model with only one block in a cell, and gradually increases $B$.\nThe performance on a validation set is used as feedback to train a\nsurrogate\nmodel for\npredicting\nthe performance of novel architectures. With this predictor, we can thus decide which models should be prioritized to be evaluated next. Since the performance predictor should be able to handle various-sized inputs, accuracy, and sample-efficient, they ended up using an RNN model.\nThe algorithm of Progressive NAS. (Image source:\nLiu, et al 2018\n)\nGradient descent\n#\nUsing gradient descent to update the architecture search model requires an effort to make the process of choosing discrete operations differentiable. These approaches usually combine the learning of both architecture parameters and network weights together into one model. See more in the\nsection\non the\n“one-shot”\napproach.\nEvaluation Strategy\n#\nWe need to measure, estimate or predict the performance of every child model in order to obtain feedback for optimizing the search algorithm. The process of candidate evaluation could be very expensive and many new evaluation methods have been proposed to save time or computation. When evaluating a child model, we mostly care about its performance measured as accuracy on a validation set. Recent work has started looking into other factors of a model, such as model size and latency, as certain devices may have limitations on memory or demand fast response time.\nTraining from Scratch\n#\nThe most naive approach is to train every child network independently from scratch until\nconvergence\nand then measure its accuracy on a validation set (\nZoph & Le 2017\n). It provides solid performance numbers, but one complete train-converge-evaluate loop only generates a single data sample for training the RL controller (let alone RL is known to be sample-inefficient in general). Thus it is very expensive in terms of computation consumption.\nProxy Task Performance\n#\nThere are several approaches for using a proxy task performance as the performance estimator of a child network, which is generally cheaper and faster to calculate:\nTrain on a smaller dataset.\nTrain for fewer epochs.\nTrain and evaluate a down-scaled model in the search stage. For example, once a cell structure is learned, we can play with the number of cell repeats or scale up the number of filters (\nZoph et al. 2018\n).\nPredict the learning curve.\nBaker et al (2018)\nmodel the prediction of validation accuracies as a time-series regression problem. The features for the regression model ($\\nu$-support vector machine regressions; $\\nu$-SVR) include the early sequences of accuracy per epoch, architecture parameters, and hyperparameters.\nParameter Sharing\n#\nInstead of training every child model independently from scratch. You may ask, ok, what if we fabricate dependency between them and find a way to reuse weights? Some researchers succeeded to make such approaches work.\nInspired by\nNet2net\ntransformation,\nCai et al (2017)\nproposed\nEfficient Architecture Search\n(\nEAS\n). EAS sets up an RL agent, known as a meta-controller, to predict function-preserving network transformation so as to grow the network depth or layer width. Because the network is growing incrementally, the weights of previously validated networks can be\nreused\nfor further exploration. With inherited weights, newly constructed networks only need some light-weighted training.\nA meta-controller learns to generate\nnetwork transformation actions\ngiven the current network architecture, which is specified with a variable-length string. In order to handle architecture configuration of a variable length, the meta-controller is implemented as a bi-directional recurrent network. Multiple actor networks output different transformation decisions:\nNet2WiderNet\noperation allows to replace a layer with a wider layer, meaning more units for fully-connected layers, or more filters for convolutional layers, while preserving the functionality.\nNet2DeeperNet\noperation allows to insert a new layer that is initialized as adding an identity mapping between two layers so as to preserve the functionality.\nOverview of the RL based meta-controller in Efficient Architecture Search (NAS). After encoding the architecture configuration, it outputs net2net transformation actions through two separate actor networks. (Image source:\nCai et al 2017\n)\nWith similar motivation,\nEfficient NAS\n(\nENAS\n;\nPham et al. 2018\n) speeds up NAS (i.e. 1000x less) by aggressively sharing parameters among child models. The core motivation behind ENAS is the observation that all of the sampled architecture graphs can be viewed as\nsub-graphs\nof a larger\nsupergraph\n. All the child networks are sharing weights of this supergraph.\n(Left) The graph represents the entire search space for a 4-node recurrent cell, but only connections in red are active. (Middle) An example of how the left active sub-graph can be translated into a child model architecture. (Right) The network parameters produced by an RNN controller for the architecture in the middle. (Image source:\nPham et al. 2018\n)\nENAS alternates between training the shared model weights $\\omega$ and training the controller $\\theta$:\nThe parameters of the controller LSTM $\\theta$ are trained with\nREINFORCE\n, where the reward $R(\\mathbf{m}, \\omega)$ is computed on the validation set.\nThe shared parameters of the child models $\\omega$ are trained with standard supervised learning loss. Note that different operators associated with the same node in the supergraph would have their own distinct parameters.\nPrediction-Based\n#\nA routine child model evaluation loop is to update model weights via standard gradient descent. SMASH (\nBrock et al. 2017\n) proposes a different and interesting idea:\nCan we predict the model weights directly based on the network architecture parameters?\nThey employ a\nHyperNet\n(\nHa et al 2016\n) to directly generate the weights of a model conditioned on an encoding of its architecture configuration. Then the model with HyperNet-generated weights is validated directly. Note that we don’t need extra training for every child model but we do need to train the HyperNet.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nThe correlation between model performance with SMASH-generated weights and true validation errors suggests that predicted weights can be used for model comparison, to some extent. We do need a HyperNet of large enough capacity, as the correlation would be corrupted if the HyperNet model is too small compared to the child model size.\nThe algorithm of SMASH. (Image source:\nBrock et al. 2017\n)\nSMASH can be viewed as another way to implement the idea of\nparameter sharing\n. One problem of SMASH as pointed out by\nPham et al. (2018)\nis: The usage of HyperNet restricts the weights of SMASH child models to a\nlow-rank space\n, because weights are generated via tensor products. In comparison,\nENAS\nhas no such restrictions.\nOne-Shot Approach: Search + Evaluation\n#\nRunning search & evaluation independently for a large population of child models is expensive. We have seen promising approaches like\nBrock et al. (2017)\nor\nPham et al. (2018)\n, where training a single model is enough for emulating any child model in the search space.\nThe\none-shot\narchitecture search extends the idea of weight sharing and further combines the learning of architecture generation together with weight parameters. The following approaches all treat child architectures as different sub-graphs of a supergraph with shared weights between common edges in the supergraph.\nBender et al (2018)\nconstruct a single large over-parameterized network, known as the\nOne-Shot model\n, such that it contains every possible operation in the search space. With\nScheduledDropPath\n(the dropout rate is increased over time, which is $r^{1/k}$ at the end of training, where $0 < r < 1$ is a hyperparam and $k$ is the number of incoming paths) and some carefully designed tricks (e.g. ghost batch normalization, L2 regularization only on the active architecture), the training of such a giant model can be stabilized enough and used for evaluating any child model sampled from the supergraph.\nThe architecture of the One-Shot model in\nBender et al 2018\n. Each cell has $N$ choice blocks and each choice block can select up to 2 operations. Solid edges are used in every architecture, where dash lines are optional. (Image source:\nBender et al 2018\n)\nOnce the one-shot model is trained, it is used for evaluating the performance of many different architectures sampled at random by zeroing out or removing some operations. This sampling process can be replaced by RL or evolution.\nThey observed that the difference between the accuracy measured with the one-shot model and the accuracy of the same architecture after a small fine-tuning could be very large. Their hypothesis is that the one-shot model automatically learns to focus on the\nmost useful\noperations in the network and comes to\nrely on\nthese operations when they are available. Thus zeroing out useful operations lead to big reduction in model accuracy, while removing less important components only causes a small impact — Therefore, we see a larger variance in scores when using the one-shot model for evaluation.\nA stratified sample of models with different one-shot model accuracy versus their true validation accuracy as stand-alone models. (Image source:\nBender et al 2018\n)\nClearly designing such a search graph is not a trivial task, but it demonstrates a strong potential with the one-shot approach. It works well with only gradient descent and no additional algorithm like RL or EA is a must.\nSome believe that one main cause for inefficiency in NAS is to treat the architecture search as a\nblack-box optimization\nand thus we fall into methods like RL, evolution, SMBO, etc. If we shift to rely on standard gradient descent, we could potentially make the search process more effectively. As a result,\nLiu et al (2019)\npropose\nDifferentiable Architecture Search\n(\nDARTS\n). DARTS introduces a continuous relaxation on each path in the search supergraph, making it possible to jointly train architecture parameters and weights via gradient descent.\nLet’s use the directed acyclic graph (DAG) representation here. A cell is a DAG consisting of a topologically ordered sequence of $N$ nodes. Each node has a latent representation $x_i$ to be learned. Each edge $(i, j)$ is tied to some operation $o^{(i,j)} \\in \\mathcal{O}$ that transforms $x_j$ to compose $x_i$:\n$$\nx_i = \\sum_{j < i} o^{(i,j)}(x_j)\n$$\nTo make the search space continuous, DARTS relaxes the categorical choice of a particular operation as a softmax over all the operations and the task of architecture search is reduced to learn a set of mixing probabilities $\\alpha = \\{ \\alpha^{(i,j)} \\}$.\n$$\n\\bar{o}^{(i,j)}(x) = \\sum_{o\\in\\mathcal{O}} \\frac{\\exp(\\alpha_{ij}^o)}{\\sum_{o'\\in\\mathcal{O}} \\exp(\\alpha^{o'}_{ij})} o(x)\n$$\nwhere $\\alpha_{ij}$ is a vector of dimension $\\vert \\mathcal{O} \\vert$, containing weights between nodes $i$ and $j$ over different operations.\nThe bilevel optimization exists as we want to optimize both the network weights $w$ and the architecture representation $\\alpha$:\n$$\n\\begin{aligned}\n\\min_\\alpha & \\mathcal{L}_\\text{validate} (w^*(\\alpha), \\alpha) \\\\\n\\text{s.t.} & w^*(\\alpha) = \\arg\\min_w \\mathcal{L}_\\text{train} (w, \\alpha)\n\\end{aligned}\n$$\nAt step $k$, given the current architecture parameters $\\alpha_{k−1}$, we first optimize weights $w_k$ by moving $w_{k−1}$ in the direction of minimizing the training loss $\\mathcal{L}_\\text{train}(w_{k−1}, \\alpha_{k−1})$ with a learning rate $\\xi$. Next, while keeping the newly updated weights $w_k$ fixed, we update the mixing probabilities so as to minimize the validation loss\nafter a single step of gradient descent w.r.t. the weights\n:\n$$\nJ_\\alpha = \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1})\n$$\nThe motivation here is that we want to find an architecture with a low validation loss when its weights are optimized by gradient descent and the one-step unrolled weights serve as the\nsurrogate\nfor $w^∗(\\alpha)$.\nSide note: Earlier we have seen similar formulation in\nMAML\nwhere the two-step optimization happens between task losses and the meta-learner update, as well as framing\nDomain Randomization\nas a bilevel optimization for better transfer in the real environment.\nAn illustration of how DARTS applies continuous relaxation on edges in DAG supergraph and identifies the final model. (Image source:\nLiu et al 2019\n)\n$$\n\\begin{aligned}\n\\text{Let }w'_k &= w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}) & \\\\\nJ_\\alpha &= \\mathcal{L}_\\text{val}(w_k - \\xi \\nabla_w \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1}), \\alpha_{k-1}) = \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) & \\\\\n\\nabla_\\alpha J_\\alpha \n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\nabla_\\alpha \\alpha_{k-1} + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1})\\nabla_\\alpha w'_k & \\\\& \\text{; multivariable chain rule}\\\\\n&= \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) + \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\big( - \\xi \\color{red}{\\nabla^2_{\\alpha, w} \\mathcal{L}_\\text{train}(w_k, \\alpha_{k-1})} \\big) & \\\\\n&\\approx \\nabla_{\\alpha_{k-1}} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) - \\xi \\nabla_{w'_k} \\mathcal{L}_\\text{val}(w'_k, \\alpha_{k-1}) \\color{red}{\\frac{\\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^+, \\alpha_{k-1}) - \\nabla_\\alpha \\mathcal{L}_\\text{train}(w_k^-, \\alpha_{k-1}) }{2\\epsilon}} & \\\\\n& \\text{; apply numerical differentiation approximation}\n\\end{aligned}\n$$\nwhere the red part is using numerical differentiation approximation where $w_k^+ = w_k + \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$ and $w_k^- = w_k - \\epsilon \\nabla_{w’_k} \\mathcal{L}_\\text{val}(w’_k, \\alpha_{k-1})$.\nThe algorithm overview of DARTS. (Image source:\nLiu et al 2019\n)\nAs another idea similar to DARTS, Stochastic NAS (\nXie et al., 2019\n) applies a continuous relaxation by employing the concrete distribution (CONCRETE = CONtinuous relaxations of disCRETE random variables;\nMaddison et al 2017\n) and reparametrization tricks. The goal is same as DARTS, to make the discrete distribution differentiable and thus enable optimization by gradient descent.\nDARTS is able to greatly reduce the cost of GPU hours. Their experiments for searching for CNN cells have $N=7$ and only took 1.5 days with a single GPU. However, it suffers from the high GPU memory consumption issue due to its continuous representation of network architecture. In order to fit the model into the memory of a single GPU, they picked a small $N$.\nTo constrain the GPU memory consumption,\nProxylessNAS\n(\nCai et al., 2019\n) views NAS as a path-level pruning process in DAG and binarizes the architecture parameters to force only one path to be active between two nodes at a time. The probabilities for an edge being either masked out or not are then learned by sampling a few binarized architectures and using\nBinaryConnect\n(\nCourbariaux et al., 2015\n) to update the corresponding probabilities. ProxylessNAS demonstrates a strong connection between NAS and model compression. By using path-level compression, it is able to save memory consumption by one order of magnitude.\nLet’s continue with the graph representation. In a DAG adjacency matrix $G$ where $G_{ij}$ represents an edge between node $i$ and $j$ and its value can be chosen from the set of $\\vert \\mathcal{O} \\vert$ candidate primitive operations, $\\mathcal{O} = \\{ o_1, \\dots \\}$. The One-Shot model, DARTS and ProxylessNAS all consider each edge as a mixture of operations, $m_\\mathcal{O}$, but with different tweaks.\nIn One-Shot, $m_\\mathcal{O}(x)$ is the sum of all the operations. In DARTS, it is a weighted sum where weights are softmax over a real-valued architecture weighting vector $\\alpha$ of length $\\vert \\mathcal{O} \\vert$. ProxylessNAS transforms the softmax probabilities of $\\alpha$ into a binary gate and uses the binary gate to keep only one operation active at a time.\n$$\n\\begin{aligned}\nm^\\text{one-shot}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} o_i(x) \\\\\nm^\\text{DARTS}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} p_i o_i(x) = \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\exp(\\alpha_i)}{\\sum_j \\exp(\\alpha_j)} o_i(x) \\\\\nm^\\text{binary}_\\mathcal{O}(x) &= \\sum_{i=1}^{\\vert \\mathcal{O} \\vert} g_i o_i(x) = \\begin{cases}\no_1(x) & \\text{with probability }p_1, \\\\\n\\dots &\\\\\no_{\\vert \\mathcal{O} \\vert}(x) & \\text{with probability }p_{\\vert \\mathcal{O} \\vert}\n\\end{cases} \\\\\n\\text{ where } g &= \\text{binarize}(p_1, \\dots, p_N) = \\begin{cases}\n[1, 0, \\dots, 0] & \\text{with probability }p_1, \\\\\n\\dots & \\\\\n[0, 0, \\dots, 1] & \\text{with probability }p_N. \\\\\n\\end{cases}\n\\end{aligned}\n$$\nProxylessNAS has two training steps running alternatively. (Image source:\nCai et al., 2019\n)\nProxylessNAS runs two training steps alternatively:\nWhen training weight parameters $w$, it freezes the architecture parameters $\\alpha$ and stochastically samples binary gates $g$ according to the above $m^\\text{binary}_\\mathcal{O}(x)$. The weight parameters can be updated with standard gradient descent.\nWhen training architecture parameters $\\alpha$, it freezes $w$, resets the binary gates and then updates $\\alpha$ on the validation set. Following the idea of\nBinaryConnect\n,  the gradient w.r.t. architecture parameters can be approximately estimated using $\\partial \\mathcal{L} / \\partial g_i$ in replacement for $\\partial \\mathcal{L} / \\partial p_i$:\n$$\n\\begin{aligned}\n\\frac{\\partial \\mathcal{L}}{\\partial \\alpha_i} \n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial p_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n\\approx \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial p_j}{\\partial \\alpha_i} \n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\partial \\frac{e^{\\alpha_j}}{\\sum_k e^{\\alpha_k}}}{\\partial \\alpha_i} \\\\\n&= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} \\frac{\\sum_k e^{\\alpha_k} (\\mathbf{1}_{i=j} e^{\\alpha_j}) - e^{\\alpha_j} e^{\\alpha_i} }{(\\sum_k e^{\\alpha_k})^2}\n= \\sum_{j=1}^{\\vert \\mathcal{O} \\vert} \\frac{\\partial \\mathcal{L}}{\\partial g_j} p_j (\\mathbf{1}_{i=j} -p_i)\n\\end{aligned}\n$$\nInstead of BinaryConnect, REINFORCE can also be used for parameter updates with the goal for maximizing the reward, while no RNN meta-controller is involved.\nComputing $\\partial \\mathcal{L} / \\partial g_i$ needs to calculate and store $o_i(x)$, which requires $\\vert \\mathcal{O} \\vert$ times GPU memory. To resolve this issue, they factorize the task of choosing one path out of $N$ into multiple binary selection tasks (Intuition: “if a path is the best choice, it should be better than any other path”). At every update step, only two paths are sampled while others are masked. These two selected paths are updated according to the above equation and then scaled properly so that other path weights are unchanged. After this process, one of the sampled paths is enhanced (path weight increases) and the other is attenuated (path weight decreases), while all other paths stay unaltered.\nBesides accuracy, ProxylessNAS also considers\nlatency\nas an important metric to optimize, as different devices might have very different requirements on inference time latency (e.g. GPU, CPU, mobile). To make latency differentiable, they model latency as a continuous function of the network dimensions. The expected latency of a mixed operation can be written as $\\mathbb{E}[\\text{latency}] = \\sum_j p_j F(o_j)$, where $F(.)$ is a latency prediction model:\nAdd a differentiable latency loss into the training of ProxylessNAS.  (Image source:\nCai et al., 2019\n)\nWhat’s the Future?\n#\nSo far we have seen many interesting new ideas on automating the network architecture engineering through neural architecture search and many have achieved very impressive performance. However, it is a bit hard to do inference on\nwhy\nsome architecture work well and how we can develop modules generalizable across tasks rather than being very dataset-specific.\nAs also noted in\nElsken, et al (2019)\n:\n“…, so far it provides little insights into why specific architectures work well and how similar the architectures derived in independent runs would be. Identifying common motifs, providing an understanding why those motifs are important for high performance, and investigating if these motifs generalize over different problems would be desirable.”\nIn the meantime, purely focusing on improvement over validation accuracy might not be enough (\nCai et al., 2019\n). Devices like mobile phones for daily usage in general have limited memory and computation power. While AI applications are on the way to affect our daily life, it is unavoidable to be more\ndevice-specific\n.\nAnother interesting investigation is to consider\nunlabelled dataset\nand\nself-supervised learning\nfor NAS. The size of labelled dataset is always limited and it is not easy to tell whether such a dataset has biases or big deviation from the real world data distribution.\nLiu et al (2020)\ndelve into the question\n“Can we find high-quality neural architecture without human-annotated labels?”\nand proposed a new setup called\nUnsupervised Neural Architecture Search\n(\nUnNAS\n). The quality of the architecture needs to be estimated in an unsupervised fashion during the search phase. The paper experimented with three unsupervised\npretext tasks\n: image rotation prediction, colorization, and solving the jigsaw puzzle.\nThey observed in a set of UnNAS experiments that:\nHigh rank correlation between supervised accuracy and pretext accuracy\non the same dataset\n. Typically the rank correlation is higher than 0.8, regardless of the dataset, the search space, and the pretext task.\nHigh rank correlation between supervised accuracy and pretext accuracy\nacross datasets\n.\nBetter pretext accuracy translates to better supervised accuracy.\nPerformance of UnNAS architecture is comparable to supervised counterparts, though not better yet.\nOne hypothesis is that the architecture quality is correlated with image statistics. Because CIFAR-10 and ImageNet are all on the natural images, they are comparable and the results are transferable. UnNAS could potentially enable a much larger amount of unlabelled data into the search phase which captures image statistics better.\nHyperparameter search is a long-standing topic in the ML community. And NAS automates architecture engineering. Gradually we are trying to automate processes in ML which usually demand a lot of human efforts. Taking even one more step further, is it possible to automatically discover ML algorithms?\nAutoML-Zero\n(\nReal et al 2020\n) investigates this idea. Using\naging evolutionary algorithms\n, AutoML-Zero automatically searches for whole ML algorithms using little restriction on the form with only simple mathematical operations as building blocks.\nIt learns three component functions. Each function only adopts very basic operations.\nSetup\n: initialize memory variables (weights).\nLearn\n: modify memory variables\nPredict\n: make a prediction from an input $x$.\nAlgorithm evaluation on one task (Image source:\nReal et al 2020\n)\nThree types of operations are considered when mutating a parent genotype:\nInsert a random instruction or remove an instruction at a random location in a component function;\nRandomize all the instructions in a component function;\nModify one of the arguments of an instruction by replacing it with a random choice (e.g. “swap the output address” or “change the value of a constant”)\nAn illustration of evolutionary progress on projected binary CIFAR-10 with example code. (Image source:\nReal et al 2020\n)\nAppendix: Summary of NAS Papers\n#\nModel name\nSearch space\nSearch algorithms\nChild model evaluation\nNEAT (2002)\n-\nEvolution (Genetic algorithm)\n-\nNAS (2017)\nSequential layer-wise ops\nRL (REINFORCE)\nTrain from scratch until convergence\nMetaQNN (2017)\nSequential layer-wise ops\nRL (Q-learning with $\\epsilon$-greedy)\nTrain for 20 epochs\nHNAS (2017)\nHierarchical structure\nEvolution (Tournament selection)\nTrain for a fixed number of iterations\nNASNet (2018)\nCell-based\nRL (PPO)\nTrain for 20 epochs\nAmoebaNet (2018)\nNASNet search space\nEvolution (Tournament selection with aging regularization)\nTrain for 25 epochs\nEAS (2018a)\nNetwork transformation\nRL (REINFORCE)\n2-stage training\nPNAS (2018)\nReduced version of NASNet search space\nSMBO; Progressive search for architectures of increasing complexity\nTrain for 20 epochs\nENAS (2018)\nBoth sequential and cell-based search space\nRL (REINFORCE)\nTrain one model with shared weights\nSMASH (2017)\nMemory-bank representation\nRandom search\nHyperNet predicts weights of evaluated architectures.\nOne-Shot (2018)\nAn over-parameterized one-shot model\nRandom search (zero out some paths at random)\nTrain the one-shot model\nDARTS (2019)\nNASNet search space\nGradient descent (Softmax weights over operations)\nProxylessNAS (2019)\nTree structure architecture\nGradient descent (BinaryConnect) or REINFORCE\nSNAS (2019)\nNASNet search space\nGradient descent (concrete distribution)\nCitation\n#\nCited as:\nWeng, Lilian. (Aug 2020). Neural architecture search. Lil’Log. https://lilianweng.github.io/posts/2020-08-06-nas/.\nOr\n@article{weng2020nas,\n  title   = \"Neural Architecture Search\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Aug\",\n  url     = \"https://lilianweng.github.io/posts/2020-08-06-nas/\"\n}\nReference\n#\n[1] Thomas Elsken, Jan Hendrik Metzen, Frank Hutter.\n“Neural Architecture Search: A Survey”\nJMLR 20 (2019) 1-21.\n[2] Kenneth O. Stanley, et al.\n“Designing neural networks through neuroevolution”\nNature Machine Intelligence volume 1, pages 24–35 (2019).\n[3] Kenneth O. Stanley & Risto Miikkulainen.\n“Evolving Neural Networks through Augmenting Topologies”\nEvolutionary Computation 10(2): 99-127 (2002).\n[4] Barret Zoph, Quoc V. Le.\n“Neural architecture search with reinforcement learning”\nICLR 2017.\n[5] Bowen Baker, et al.\n“Designing Neural Network Architectures using Reinforcement Learning”\nICLR 2017.\n[6] Bowen Baker, et al.\n“Accelerating neural architecture search using performance prediction”\nICLR Workshop 2018.\n[7] Barret Zoph, et al.\n“Learning transferable architectures for scalable image recognition”\nCVPR 2018.\n[8] Hanxiao Liu, et al.\n“Hierarchical representations for efficient architecture search.”\nICLR 2018.\n[9] Esteban Real, et al.\n“Regularized Evolution for Image Classifier Architecture Search”\narXiv:1802.01548 (2018).\n[10] Han Cai, et al. [“Efficient architecture search by network transformation”] AAAI 2018a.\n[11] Han Cai, et al.\n“Path-Level Network Transformation for Efficient Architecture Search”\nICML 2018b.\n[12] Han Cai, Ligeng Zhu & Song Han.\n“ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware”\nICLR 2019.\n[13] Chenxi Liu, et al.\n“Progressive neural architecture search”\nECCV 2018.\n[14] Hieu Pham, et al.\n“Efficient neural architecture search via parameter sharing”\nICML 2018.\n[15] Andrew Brock, et al.\n“SMASH: One-shot model architecture search through hypernetworks.”\nICLR 2018.\n[16] Gabriel Bender, et al.\n“Understanding and simplifying one-shot architecture search.”\nICML 2018.\n[17] Hanxiao Liu, Karen Simonyan, Yiming Yang.\n“DARTS: Differentiable Architecture Search”\nICLR 2019.\n[18] Sirui Xie, Hehui Zheng, Chunxiao Liu, Liang Lin.\n“SNAS: Stochastic Neural Architecture Search”\nICLR 2019.\n[19] Chenxi Liu et al.\n“Are Labels Necessary for Neural Architecture Search?”\nECCV 2020.\n[20] Esteban Real, et al.\n“AutoML-Zero: Evolving Machine Learning Algorithms From Scratch”\nICML 2020.",
            "metadata": {
              "title": "Neural Architecture Search | Lil'Log",
              "description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "keywords": "architecture, reinforcement-learning, evolution, auto-ML",
              "author": "Lilian Weng",
              "og:title": "Neural Architecture Search",
              "og:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
              "twitter:card": "summary",
              "twitter:title": "Neural Architecture Search",
              "twitter:description": "Although most popular and successful model architectures are designed by human experts, it doesn’t mean we have explored the entire network architecture space and settled down with the best option. We would have a better chance to find the optimal solution if we adopt a systematic and automatic way of learning high-performance model architectures.",
              "article:section": "posts",
              "article:published_time": "2020-08-06T00:00:00+00:00",
              "article:modified_time": "2020-08-06T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/475f6d363978/code/body-000.txt",
                "chars": 234,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "bytes": 176077,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-22a9e6438726d336ffe1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-high-level.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "bytes": 852559,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-a036ff1cba89bd8ca177.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "bytes": 189886,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-18722c930cf5c497d7b4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NASNet-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "bytes": 234856,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-68fbdff3da3a7b692d3a.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/cell-prediction-steps.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "bytes": 405820,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-41e54ee7ec562394ded4.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/hierarchical-NAS-search-space.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "bytes": 147376,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-d6536618f786cd88a98d.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/path-level-network-transformations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "bytes": 82152,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-e6b375e7ba5a5bff8ba1.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS-memory-bank-view-representation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "bytes": 157138,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f21c72c925e425e2c413.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NAS.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "bytes": 227348,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-20cc8fbcc63711039176.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/MetaQNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "bytes": 307054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-844cb0884d62492c8431.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/NEAT-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "bytes": 380120,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2beee1783718ce1e1233.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolution-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "bytes": 136228,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-841034ba340426dcc42f.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AmoebaNet-mutations.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "bytes": 403536,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-608e700d91e7d97d213c.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/progressive-NAS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "bytes": 359761,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-740a0454d4525705f3c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/EAS-meta-controller.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "bytes": 100940,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-c04d9fc97a4006715831.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/ENAS-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "bytes": 138999,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ebfcd764d9e484649bd7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "bytes": 266480,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-ea47ad327c3e525d7680.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/SMASH-error-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "bytes": 247091,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-4bfe6aecad730ed414c3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "bytes": 128766,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-dc1c1909a9278b076020.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/one-shot-model-accuracy-correlation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "bytes": 352267,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f40298ff01af8fc9e4dc.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "bytes": 127977,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-2453003154b5219dd230.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/DARTS-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "bytes": 89862,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-94f6d5d4f164d466c4fb.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "bytes": 144054,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-827f8fb6a1866bbd0478.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/proxylessNAS-latency.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "bytes": 191620,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-f86a63f93973014347b7.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-evaluation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "bytes": 582897,
                "reused": false,
                "local_path": "attachments/475f6d363978/images/body-52ae3de20af990c921e3.png",
                "src": "https://lilianweng.github.io/posts/2020-08-06-nas/AutoML-zero-progress.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "label": "Stanley & Miikkulainen, 2002",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.01578",
                "label": "Zoph & Le 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.02167",
                "label": "Baker et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.05377",
                "label": "Elsken, et al 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.07012",
                "label": "Zoph et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.07648",
                "label": "DropPath",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Network_motif",
                "label": "motif",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1711.00436",
                "label": "Liu et al 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Topological_sorting",
                "label": "topological ordering",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.02639",
                "label": "Cai et al (2018b)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.05344",
                "label": "Brock et al. (2017)",
                "type": "a"
              },
              {
                "href": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "label": "Bergstra & Bengio 2012",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-04-08-policy-gradient/",
                "label": "REINFORCE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "Q-learning",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$\\epsilon$-greedy",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Genetic_algorithm",
                "label": "genetic algorithm (GA)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/s42256-018-0006-z",
                "label": "survey",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.01548",
                "label": "Real et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Tournament_selection",
                "label": "tournament selection",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
                "label": "",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
                "label": "“curriculum”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1712.00559",
                "label": "Liu, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/A*_search_algorithm",
                "label": "A* search algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.10823",
                "label": "Baker et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.05641",
                "label": "Net2net",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04873",
                "label": "Cai et al (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03268",
                "label": "Pham et al. 2018",
                "type": "a"
              },
              {
                "href": "https://blog.otoro.net/2016/09/28/hyper-networks/",
                "label": "HyperNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.09106",
                "label": "Ha et al 2016",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "label": "Bender et al (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.09055",
                "label": "Liu et al (2019)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-11-30-meta-learning/",
                "label": "MAML",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-05-05-domain-randomization/",
                "label": "Domain Randomization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.09926",
                "label": "Xie et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.00712",
                "label": "Maddison et al 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.00332",
                "label": "Cai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.00363",
                "label": "Courbariaux et al., 2015",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.12056",
                "label": "Liu et al (2020)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.03384",
                "label": "Real et al 2020",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v80/bender18a.html",
                "label": "One-Shot (2018)",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:31Z",
            "source_url": "https://lilianweng.github.io/posts/2020-08-06-nas/",
            "papers": [
              {
                "status": "ok",
                "url": "http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf",
                "bytes": 455683,
                "reused": false,
                "local_path": "papers/repair/805499a4b371ca736e62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.01578",
                "bytes": 733204,
                "reused": false,
                "local_path": "papers/repair/a111656177a4c8876b48.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.02167",
                "bytes": 2766423,
                "reused": false,
                "local_path": "papers/repair/760094c3d304751da217.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.05377",
                "bytes": 513920,
                "reused": false,
                "local_path": "papers/repair/97142d15c75389ec1783.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.07012",
                "bytes": 8223935,
                "reused": false,
                "local_path": "papers/repair/263d4aa0ef18300727e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.07648",
                "bytes": 301203,
                "reused": false,
                "local_path": "papers/repair/3c2d2df24de01e01fbd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.00436",
                "bytes": 625718,
                "reused": false,
                "local_path": "papers/repair/eb6cf4cb96b16ab6e4ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.02639",
                "bytes": 4382572,
                "reused": false,
                "local_path": "papers/repair/680796c56d03bb0724c3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.05344",
                "bytes": 3204919,
                "reused": false,
                "local_path": "papers/repair/e88c3d4c693981e49fce.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf",
                "bytes": 728274,
                "reused": false,
                "local_path": "papers/repair/8a459dcd765c190d80b7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.01548",
                "bytes": 719617,
                "reused": false,
                "local_path": "papers/repair/65805c891aedf369ff37.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1712.00559",
                "bytes": 1201540,
                "reused": false,
                "local_path": "papers/repair/609e6dc18e9ec4f12c8e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.10823",
                "bytes": 696064,
                "reused": false,
                "local_path": "papers/repair/0fe98a08286c39292e71.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05641",
                "bytes": 514031,
                "reused": false,
                "local_path": "papers/repair/92e6dc487fb58180dcc6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04873",
                "bytes": 1963936,
                "reused": false,
                "local_path": "papers/repair/ed8c0c59198f186976bc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03268",
                "bytes": 437408,
                "reused": false,
                "local_path": "papers/repair/385bdb4f3e6008bec0cf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.09106",
                "bytes": 3125291,
                "reused": false,
                "local_path": "papers/repair/9a50e3e16a9ac5be3fd1.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v80/bender18a/bender18a.pdf",
                "bytes": 608254,
                "reused": false,
                "local_path": "papers/repair/3a859646e6c029ea003e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.09055",
                "bytes": 636787,
                "reused": false,
                "local_path": "papers/repair/40e69415044afc05d599.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.09926",
                "bytes": 711882,
                "reused": false,
                "local_path": "papers/repair/35befec5995034ad4bfd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.00712",
                "bytes": 858710,
                "reused": false,
                "local_path": "papers/repair/27fa0ebf79e9f6aa3132.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.00332",
                "bytes": 2325253,
                "reused": false,
                "local_path": "papers/repair/61f9a157fe986680a3a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.00363",
                "bytes": 1297364,
                "reused": false,
                "local_path": "papers/repair/1bc5305341828713b8ed.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.12056",
                "bytes": 1315976,
                "reused": false,
                "local_path": "papers/repair/05573f22fe71d2abefb7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.03384",
                "bytes": 1781766,
                "reused": false,
                "local_path": "papers/repair/daabc7af10551ec97ee1.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 44902,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/475f6d363978/pages/source.html",
            "local_html": "attachments/475f6d363978/pages/article.html",
            "body_base_path": "attachments/475f6d363978/pages/",
            "body_markdown_path": "attachments/475f6d363978/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
          "status": "partial",
          "article_id": "607baf97b999",
          "local_path": "series-follow/1601/repair/98f025266fe083b5aa56.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
              "bytes": 929637,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5e717a51b0a5329fa972.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
              "bytes": 268193,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bcfb5637b30440671005.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
              "bytes": 183059,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7365015a0a10cc69acd8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
              "bytes": 473871,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9d994d94aa3f953655fe.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
              "bytes": 244780,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4b7c5a8a25f1aef4e33a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
              "bytes": 269806,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7ad146452781a398f651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
              "bytes": 1588495,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2208e66f87d45609e14a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
              "bytes": 516917,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e495e282eb1d3f3e9144.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
              "bytes": 51037,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8a0f9752f056eb917bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
              "bytes": 272909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b96d2353529c40b14aef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
              "bytes": 100122,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e2ee524fbebc06b6e190.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
              "bytes": 227696,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5d14984c36bf66c73897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
              "bytes": 87898,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/08c8fd1e0c80108aa470.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
              "bytes": 415583,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c58896fcdd52fc06c2a0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
              "bytes": 253294,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7970b3c999effb6f02b6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
              "bytes": 88113,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/85fc2d78dbd4ba853f15.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
              "bytes": 282592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/dd77dfe447995839038a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
              "bytes": 384564,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3be7c9763f11993ba7a6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
              "bytes": 76634,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e529afcc9a2bd0fb2fae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
              "bytes": 180008,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8045a59ac9bcdcc697fc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
              "bytes": 258219,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c0273e122159d4c19386.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
              "bytes": 88004,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8bf9b1628b286eb863de.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
              "bytes": 138525,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/76b71f8459361bdc98c5.png"
            }
          ],
          "article": {
            "id": "607baf97b999",
            "url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2019-01-31-lm/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "bytes": 929637,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5e717a51b0a5329fa972.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/elmo-and-bert.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "bytes": 268193,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-bcfb5637b30440671005.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/nmt-recap.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "bytes": 183059,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7365015a0a10cc69acd8.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CoVe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "bytes": 473871,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-9d994d94aa3f953655fe.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELMo-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "bytes": 244780,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-4b7c5a8a25f1aef4e33a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "bytes": 269806,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7ad146452781a398f651.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/CVT-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "bytes": 1588495,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-2208e66f87d45609e14a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ULMFiT.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "bytes": 516917,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e495e282eb1d3f3e9144.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/OpenAI-GPT-transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "bytes": 51037,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8a0f9752f056eb917bbf.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-classification.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "bytes": 272909,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-b96d2353529c40b14aef.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "bytes": 100122,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e2ee524fbebc06b6e190.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/transformer-encoder-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "bytes": 227696,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-5d14984c36bf66c73897.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/language-model-comparison.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "bytes": 87898,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-08c8fd1e0c80108aa470.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-input-embedding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "bytes": 415583,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c58896fcdd52fc06c2a0.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BERT-downstream-tasks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "bytes": 253294,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-7970b3c999effb6f02b6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/T5.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "bytes": 88113,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-85fc2d78dbd4ba853f15.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-train-data.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "bytes": 282592,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-dd77dfe447995839038a.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/GPT3-eval.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "bytes": 384564,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-3be7c9763f11993ba7a6.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-two-stream-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "bytes": 76634,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-e529afcc9a2bd0fb2fae.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/XLNet-glue.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "bytes": 180008,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8045a59ac9bcdcc697fc.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "bytes": 258219,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-c0273e122159d4c19386.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/BART-perf.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "bytes": 88004,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-8bf9b1628b286eb863de.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-overview.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "bytes": 138525,
                "reused": true,
                "local_path": "attachments/607baf97b999/images/body-76b71f8459361bdc98c5.png",
                "src": "https://lilianweng.github.io/posts/2019-01-31-lm/ELECTRA-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "src": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/607baf97b999/videos/repair-l5einDQ-Ttc.mp4",
                "bytes": 19398754,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "139.221000",
                "reused": false
              }
            ],
            "body_markdown": "[Updated on 2019-02-14: add\nULMFiT\nand\nGPT-2\n.]\n[Updated on 2020-02-29: add\nALBERT\n.]\n[Updated on 2020-10-25: add\nRoBERTa\n.]\n[Updated on 2020-12-13: add\nT5\n.]\n[Updated on 2020-12-30: add\nGPT-3\n.]\n[Updated on 2021-11-13: add\nXLNet\n,\nBART\nand\nELECTRA\n; Also updated the\nSummary\nsection.]\nI guess they are Elmo & Bert? (Image source:\nhere\n)\nWe have seen amazing progress in NLP in 2018. Large-scale pre-trained language modes like\nOpenAI GPT\nand\nBERT\nhave achieved great performance on a variety of language tasks using generic model architectures. The idea is similar to how ImageNet classification pre-training helps many vision tasks (*). Even better than vision classification pre-training, this simple and powerful approach in NLP does not require labeled data for pre-training, allowing us to experiment with increased training scale, up to our very limit.\n(*) He et al. (2018)\nfound\nthat pre-training might not be necessary for image segmentation task.\nIn my previous NLP\npost on word embedding\n, the introduced embeddings are not context-specific — they are learned based on word concurrency but not sequential context. So in two sentences, “\nI am eating an apple\n” and “\nI have an Apple phone\n”, two “apple” words refer to very different things but they would still share the same word embedding vector.\nDespite this, early adoption of word embeddings in problem-solving is to use them as additional features for an existing task-specific model and in a way the improvement is bounded.\nIn this post, we will discuss how various approaches were proposed to make embeddings dependent on context, and to make them easier and cheaper to be applied to downstream tasks in general form.\nCoVe\n#\nCoVe\n(\nMcCann et al. 2017\n), short for\nContextual Word Vectors\n, is a type of word embeddings learned by an encoder in an\nattentional seq-to-seq\nmachine translation model.\nDifferent from traditional word embeddings introduced\nhere\n, CoVe word representations are functions of the entire input sentence.\nNMT Recap\n#\nHere the Neural Machine Translation (\nNMT\n) model is composed of a standard, two-layer, bidirectional LSTM encoder and an attentional two-layer unidirectional LSTM decoder. It is pre-trained on the English-German translation task. The encoder learns and optimizes the embedding vectors of English words in order to translate them to German. With the intuition that the encoder should capture high-level semantic and syntactic meanings before transforming words into another language, the encoder output is used to provide contextualized word embeddings for various downstream language tasks.\nThe NMT base model used in CoVe.\nA sequence of $n$ words in source language (English): $x = [x_1, \\dots, x_n]$.\nA sequence of $m$ words in target language (German): $y = [y_1, \\dots, y_m]$.\nThe\nGloVe\nvectors of source words: $\\text{GloVe}(x)$.\nRandomly initialized embedding vectors of target words: $z = [z_1, \\dots, z_m]$.\nThe biLSTM encoder outputs a sequence of hidden states: $h = [h_1, \\dots, h_n] = \\text{biLSTM}(\\text{GloVe}(x))$ and $h_t = [\\overrightarrow{h}_t; \\overleftarrow{h}_t]$ where the forward LSTM computes $\\overrightarrow{h}_t = \\text{LSTM}(x_t, \\overrightarrow{h}_{t-1})$ and the backward computation gives us $\\overleftarrow{h}_t = \\text{LSTM}(x_t, \\overleftarrow{h}_{t-1})$.\nThe attentional decoder outputs a distribution over words: $p(y_t \\mid H, y_1, \\dots, y_{t-1})$ where $H$ is a stack of hidden states $\\{h\\}$ along the time dimension:\n$$\n\\begin{aligned}\n\\text{decoder hidden state: } s_t &= \\text{LSTM}([z_{t-1}; \\tilde{h}_{t-1}], s_{t-1}) \\\\\n\\text{attention weights: } \\alpha_t &= \\text{softmax}(H(W_1 s_t + b_1)) \\\\\n\\text{context-adjusted hidden state: } \\tilde{h}_t &= \\tanh(W_2[H^\\top\\alpha_t;s_t] + b_2) \\\\\n\\text{decoder output: } p(y_t\\mid H, y_1, \\dots, y_{t-1}) &= \\text{softmax}(W_\\text{out} \\tilde{h}_t + b_\\text{out})\n\\end{aligned}\n$$\nUse CoVe in Downstream Tasks\n#\nThe hidden states of NMT encoder are defined as\ncontext vectors\nfor other language tasks:\n$$\n\\text{CoVe}(x) = \\text{biLSTM}(\\text{GloVe}(x))\n$$\nThe paper proposed to use the concatenation of GloVe and CoVe for question-answering and classification tasks. GloVe learns from the ratios of global word co-occurrences, so it has no sentence context, while CoVe is generated by processing text sequences is able to capture the contextual information.\n$$\nv = [\\text{GloVe}(x); \\text{CoVe}(x)]\n$$\nGiven a downstream task, we first generate the concatenation of GloVe + CoVe vectors of input words and then feed them into the task-specific models as additional features.\nThe CoVe embeddings are generated by an encoder trained for machine translation task. The encoder can be plugged into any downstream task-specific model. (Image source:\noriginal paper\n)\nSummary\n: The limitation of CoVe is obvious: (1) pre-training is bounded by available datasets on the supervised translation task; (2) the contribution of CoVe to the final performance is constrained by the task-specific model architecture.\nIn the following sections, we will see that ELMo overcomes issue (1) by unsupervised pre-training and OpenAI GPT & BERT further overcome both problems by unsupervised pre-training + using generative model architecture for different downstream tasks.\nELMo\n#\nELMo\n, short for\nEmbeddings from Language Model\n(\nPeters, et al, 2018\n) learns contextualized word representation by pre-training a language model in an\nunsupervised\nway.\nBidirectional Language Model\n#\nThe bidirectional Language Model (\nbiLM\n) is the foundation for ELMo. While the input is a sequence of $n$ tokens, $(x_1, \\dots, x_n)$, the language model learns to predict the probability of next token given the history.\nIn the forward pass, the history contains words before the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_1, \\dots, x_{i-1})\n$$\nIn the backward pass, the history contains words after the target token,\n$$\np(x_1, \\dots, x_n) = \\prod_{i=1}^n p(x_i \\mid x_{i+1}, \\dots, x_n)\n$$\nThe predictions in both directions are modeled by multi-layer LSTMs with hidden states $\\overrightarrow{\\mathbf{h}}_{i,\\ell}$ and $\\overleftarrow{\\mathbf{h}}_{i,\\ell}$ for input token $x_i$ at the layer level $\\ell=1,\\dots,L$.\nThe final layer’s hidden state $\\mathbf{h}_{i,L} = [\\overrightarrow{\\mathbf{h}}_{i,L}; \\overleftarrow{\\mathbf{h}}_{i,L}]$ is used to output the probabilities over tokens after softmax normalization. They share the embedding layer and the softmax layer, parameterized by $\\Theta_e$ and $\\Theta_s$ respectively.\nThe biLSTM base model of ELMo. (Image source: recreated based on the figure in [\"Neural Networks, Types, and Functional Programming\"](http://colah.github.io/posts/2015-09-NN-Types-FP/) by Christopher Olah.)\nThe model is trained to minimize the negative log likelihood (= maximize the log likelihood for true words) in both directions:\n$$\n\\begin{aligned}\n\\mathcal{L} = - \\sum_{i=1}^n \\Big( \n\\log p(x_i \\mid x_1, \\dots, x_{i-1}; \\Theta_e, \\overrightarrow{\\Theta}_\\text{LSTM}, \\Theta_s) + \\\\\n\\log p(x_i \\mid x_{i+1}, \\dots, x_n; \\Theta_e, \\overleftarrow{\\Theta}_\\text{LSTM}, \\Theta_s) \\Big)\n\\end{aligned}\n$$\nELMo Representations\n#\nOn top of a $L$-layer biLM, ELMo stacks all the hidden states across layers together by learning a task-specific linear combination. The hidden state representation for the token $x_i$ contains $2L+1$ vectors:\n$$\nR_i = \\{ \\mathbf{h}_{i,\\ell} \\mid \\ell = 0, \\dots, L \\}\n$$\nwhere $\\mathbf{h}_{0, \\ell}$ is the embedding layer output and $\\mathbf{h}_{i, \\ell} = [\\overrightarrow{\\mathbf{h}}_{i,\\ell}; \\overleftarrow{\\mathbf{h}}_{i,\\ell}]$.\nThe weights, $\\mathbf{s}^\\text{task}$, in the linear combination are learned for each end task and normalized by softmax. The scaling factor $\\gamma^\\text{task}$ is used to correct the misalignment between the distribution of biLM hidden states and the distribution of task specific representations.\n$$\nv_i = f(R_i; \\Theta^\\text{task}) = \\gamma^\\text{task} \\sum_{\\ell=0}^L s^\\text{task}_i \\mathbf{h}_{i,\\ell}\n$$\nTo evaluate what kind of information is captured by hidden states across different layers, ELMo is applied on semantic-intensive and syntax-intensive tasks respectively using representations in different layers of biLM:\nSemantic task\n: The\nword sense disambiguation (WSD)\ntask emphasizes the meaning of a word given a context. The biLM top layer is better at this task than the first layer.\nSyntax task\n: The\npart-of-speech\n(POS) tagging\ntask aims to infer the grammatical role of a word in one sentence. A higher accuracy can be achieved by using the biLM first layer than the top layer.\nThe comparison study indicates that syntactic information is better represented at lower layers while semantic information is captured by higher layers. Because different layers tend to carry different type of information,\nstacking them together helps\n.\nUse ELMo in Downstream Tasks\n#\nSimilar to how\nCoVe\ncan help different downstream tasks, ELMo embedding vectors are included in the input or lower levels of task-specific models. Moreover, for some tasks (i.e.,\nSNLI\nand\nSQuAD\n, but not\nSRL\n), adding them into the output level helps too.\nThe improvements brought up by ELMo are largest for tasks with a small supervised dataset. With ELMo, we can also achieve similar performance with much less labeled data.\nSummary\n: The language model pre-training is unsupervised and theoretically the pre-training can be scaled up as much as possible since the unlabeled text corpora are abundant. However, it still has the dependency on task-customized models and thus the improvement is only incremental, while searching for a good model architecture for every task remains non-trivial.\nCross-View Training\n#\nIn ELMo the unsupervised pre-training and task-specific learning happen for two independent models in two separate training stages.\nCross-View Training\n(abbr.\nCVT\n;\nClark et al., 2018\n) combines them into one unified semi-supervised learning procedure where the representation of a biLSTM encoder is improved by both supervised learning with labeled data and unsupervised learning with unlabeled data on auxiliary tasks.\nModel Architecture\n#\nThe model consists of a two-layer bidirectional LSTM encoder and a primary prediction module. During training, the model is fed with labeled and unlabeled data batches alternatively.\nOn\nlabeled examples\n, all the model parameters are updated by standard supervised learning. The loss is the standard cross entropy.\nOn\nunlabeled examples\n, the primary prediction module still can produce a “soft” target, even though we cannot know exactly how accurate they are. In a couple of auxiliary tasks, the predictor only sees and processes a restricted view of the input, such as only using encoder hidden state representation in one direction. The auxiliary task outputs are expected to match the primary prediction target for a full view of input.\nIn this way, the encoder is forced to distill the knowledge of the full context into partial representation. At this stage, the biLSTM encoder is backpropagated but the primary prediction module is\nfixed\n. The loss is to minimize the distance between auxiliary and primary predictions.\nThe overview of semi-supervised language model cross-view training. (Image source:\noriginal paper\n)\nMulti-Task Learning\n#\nWhen training for multiple tasks simultaneously, CVT adds several extra primary prediction models for additional tasks. They all share the same sentence representation encoder.\nDuring supervised training, once one task is randomly selected, parameters in its corresponding predictor and the representation encoder are updated.\nWith unlabeled data samples, the encoder is optimized jointly across all the tasks by minimizing the differences between auxiliary outputs and primary prediction for every task.\nThe multi-task learning encourages better generality of representation and in the meantime produces a nice side-product: all-tasks-labeled examples from unlabeled data. They are precious data labels considering that cross-task labels are useful but fairly rare.\nUse CVT in Downstream Tasks\n#\nTheoretically the primary prediction module can take any form, generic or task-specific design. The examples presented in the CVT paper include both cases.\nIn sequential tagging tasks (classification for every token) like\nNER\nor\nPOS\ntagging, the predictor module contains two fully connected layers and a softmax layer on the output to produce a probability distribution over class labels.\nFor each token $\\mathbf{x}_i$, we take the corresponding hidden states in two layers, $\\mathbf{h}_1^{(i)}$ and $\\mathbf{h}_2^{(i)}$:\n$$\n\\begin{aligned}\np_\\theta(y_i \\mid \\mathbf{x}_i) \n&= \\text{NN}(\\mathbf{h}^{(i)}) \\\\\n&= \\text{NN}([\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) \\\\\n&= \\text{softmax} \\big( \\mathbf{W}\\cdot\\text{ReLU}(\\mathbf{W'}\\cdot[\\mathbf{h}_1^{(i)}; \\mathbf{h}_2^{(i)}]) + \\mathbf{b} \\big)\n\\end{aligned}\n$$\nThe auxiliary tasks are only fed with forward or backward LSTM state in the first layer. Because they only observe partial context, either on the left or right, they have to learn like a language model, trying to predict the next token given the context. The\nfwd\nand\nbwd\nauxiliary tasks only take one direction. The\nfuture\nand\npast\ntasks take one step further in forward and backward direction, respectively.\n$$\n\\begin{aligned}\np_\\theta^\\text{fwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{fwd}(\\overrightarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{bwd}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{bwd}(\\overleftarrow{\\mathbf{h}}^{(i)}) \\\\\np_\\theta^\\text{future}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{future}(\\overrightarrow{\\mathbf{h}}^{(i-1)}) \\\\\np_\\theta^\\text{past}(y_i \\mid \\mathbf{x}_i) &= \\text{NN}^\\text{past}(\\overleftarrow{\\mathbf{h}}^{(i+1)})\n\\end{aligned}\n$$\nThe sequential tagging task depends on four auxiliary prediction models, their inputs only involving hidden states in one direction: forward, backward, future and past. (Image source:\noriginal paper\n)\nNote that if the primary prediction module has dropout, the dropout layer works as usual when training with labeled data, but it is not applied when generating “soft” target for auxiliary tasks during training with unlabeled data.\nIn the machine translation task, the primary prediction module is replaced with a standard unidirectional LSTM decoder with attention. There are two auxiliary tasks: (1) apply dropout on the attention weight vector by randomly zeroing out some values; (2) predict the future word in the target sequence. The primary prediction for auxiliary tasks to match is the best predicted target sequence produced by running the fixed primary decoder on the input sequence with\nbeam search\n.\nULMFiT\n#\nThe idea of using generative pretrained LM + task-specific fine-tuning was first explored in ULMFiT (\nHoward & Ruder, 2018\n), directly motivated by the success of using ImageNet pre-training for computer vision tasks. The base model is\nAWD-LSTM\n.\nULMFiT follows three steps to achieve good transfer learning results on downstream language classification tasks:\nGeneral LM pre-training\n: on Wikipedia text.\nTarget task LM fine-tuning\n: ULMFiT proposed two training techniques for stabilizing the fine-tuning process. See below.\nDiscriminative fine-tuning\nis motivated by the fact that different layers of LM capture different types of information (see\ndiscussion\nabove). ULMFiT proposed to tune each layer with different learning rates, $\\{\\eta^1, \\dots, \\eta^\\ell, \\dots, \\eta^L\\}$, where $\\eta$ is the base learning rate for the first layer, $\\eta^\\ell$ is for the $\\ell$-th layer and there are $L$ layers in total.\nSlanted triangular learning rates (STLR)\nrefer to a special learning rate scheduling that first linearly increases the learning rate and then linearly decays it. The increase stage is short so that the model can converge to a parameter space suitable for the task fast, while the decay period is long allowing for better fine-tuning.\nTarget task classifier fine-tuning\n: The pretrained LM is augmented with two standard feed-forward layers and a softmax normalization at the end to predict a target label distribution.\nConcat pooling\nextracts max-polling and mean-pooling over the history of hidden states and concatenates them with the final hidden state.\nGradual unfreezing\nhelps to avoid catastrophic forgetting by gradually unfreezing the model layers starting from the last one. First the last layer is unfrozen and fine-tuned for one epoch. Then the next lower layer is unfrozen. This process is repeated until all the layers are tuned.\nThree training stages of ULMFiT. (Image source:\noriginal paper\n)\nGPT\n#\nFollowing the similar idea of ELMo, OpenAI\nGPT\n, short for\nGenerative Pre-training Transformer\n(\nRadford et al., 2018\n), expands the unsupervised language model to a much larger scale by training on a giant collection of free text corpora. Despite of the similarity, GPT has two major differences from ELMo.\nThe model architectures are different: ELMo uses a shallow concatenation of independently trained left-to-right and right-to-left multi-layer LSTMs, while GPT is a multi-layer transformer decoder.\nThe use of contextualized embeddings in downstream tasks are different: ELMo feeds embeddings into models customized for specific tasks as additional features, while GPT fine-tunes the same base model for all end tasks.\nTransformer Decoder as Language Model\n#\nCompared to the\noriginal transformer\narchitecture, the\ntransformer decoder\nmodel discards the encoder part, so there is only one single input sentence rather than two separate source and target sequences.\nThis model applies multiple transformer blocks over the embeddings of input sequences. Each block contains a masked\nmulti-headed self-attention\nlayer and a\npointwise feed-forward\nlayer. The final output produces a distribution over target tokens after softmax normalization.\nThe transformer decoder model architecture in OpenAI GPT.\nThe loss is the negative log-likelihood, same as\nELMo\n, but without backward computation. Let’s say, the context window of the size $k$ is located before the target word and the loss would look like:\n$$\n\\mathcal{L}_\\text{LM} = -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1})\n$$\nByte Pair Encoding\n#\nByte Pair Encoding\n(\nBPE\n) is used to encode the input sequences. BPE was originally proposed as a data compression algorithm in 1990s and then was adopted to solve the open-vocabulary issue in machine translation, as we can easily run into rare and unknown words when translating into a new language. Motivated by the intuition that rare and unknown words can often be decomposed into multiple subwords, BPE finds the best word segmentation by iteratively and greedily merging frequent pairs of characters.\nSupervised Fine-Tuning\n#\nThe most substantial upgrade that OpenAI GPT proposed is to get rid of the task-specific model and use the pre-trained language model directly!\nLet’s take classification as an example. Say, in the labeled dataset, each input has $n$ tokens, $\\mathbf{x} = (x_1, \\dots, x_n)$, and one label $y$. GPT first processes the input sequence $\\mathbf{x}$ through the pre-trained transformer decoder and the last layer output for the last token $x_n$ is $\\mathbf{h}_L^{(n)}$. Then with only one new trainable weight matrix $\\mathbf{W}_y$, it can predict a distribution over class labels.\n$$\nP(y\\mid x_1, \\dots, x_n) = \\text{softmax}(\\mathbf{h}_L^{(n)}\\mathbf{W}_y)\n$$\nThe loss is to minimize the negative log-likelihood for true labels. In addition, adding the LM loss as an auxiliary loss is found to be beneficial, because:\n(1) it helps accelerate convergence during training and\n(2) it is expected to improve the generalization of the supervised model.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{cls} &= \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log P(y\\mid x_1, \\dots, x_n) = \\sum_{(\\mathbf{x}, y) \\in \\mathcal{D}} \\log \\text{softmax}(\\mathbf{h}_L^{(n)}(\\mathbf{x})\\mathbf{W}_y) \\\\\n\\mathcal{L}_\\text{LM} &= -\\sum_{i} \\log p(x_i\\mid x_{i-k}, \\dots, x_{i-1}) \\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\lambda \\mathcal{L}_\\text{LM}\n\\end{aligned}\n$$\nWith similar designs, no customized model structure is needed for other end tasks (see Fig. 7). If the task input contains multiple sentences, a special delimiter token (\n$\n) is added between each pair of sentences. The embedding for this delimiter token is a new parameter we need to learn, but it should be pretty minimal.\nFor the sentence similarity task, because the ordering does not matter, both orderings are included. For the multiple choice task, the context is paired with every answer candidate.\nTraining objects in slightly modified GPT transformer models for downstream tasks. (Image source:\noriginal paper\n)\nSummary\n: It is super neat and encouraging to see that such a general framework is capable to beat SOTA on most language tasks at that time (June 2018). At the first stage, generative pre-training of a language model can absorb as much free text as possible. Then at the second stage, the model is fine-tuned on specific tasks with a small labeled dataset and a minimal set of new parameters to learn.\nOne limitation of GPT is its uni-directional nature — the model is only trained to predict the future left-to-right context.\nBERT\n#\nBERT\n, short for\nBidirectional Encoder Representations from Transformers\n(\nDevlin, et al., 2019\n) is a direct descendant to\nGPT\n: train a large language model on free text and then fine-tune on specific tasks without customized network architectures.\nCompared to GPT, the largest difference and improvement of BERT is to make training\nbi-directional\n. The model learns to predict both context on the left and right. The paper according to the ablation study claimed that:\n“bidirectional nature of our model is the single most important new contribution”\nPre-training Tasks\n#\nThe model architecture of BERT is a multi-layer bidirectional Transformer encoder.\nRecap of Transformer Encoder model architecture. (Image source:\nTransformer paper\n)\nTo encourage the bi-directional prediction and sentence-level understanding, BERT is trained with two tasks instead of the basic language task (that is, to predict the next token given context).\n*\nTask 1: Mask language model (MLM)\nFrom\nWikipedia\n: “A cloze test (also cloze deletion test) is an exercise, test, or assessment consisting of a portion of language with certain items, words, or signs removed (cloze text), where the participant is asked to replace the missing language item. … The exercise was first described by W.L. Taylor in 1953.”\nIt is unsurprising to believe that a representation that learns the context around a word rather than just after the word is able to better capture its meaning, both syntactically and semantically. BERT encourages the model to do so by training on the\n“mask language model” task\n:\nRandomly mask 15% of tokens in each sequence. Because if we only replace masked tokens with a special placeholder\n[MASK]\n, the special token would never be encountered during fine-tuning. Hence, BERT employed several heuristic tricks:\n(a) with 80% probability, replace the chosen words with\n[MASK]\n;\n(b) with 10% probability, replace with a random word;\n(c) with 10% probability, keep it the same.\nThe model only predicts the missing words, but it has no information on which words have been replaced or which words should be predicted. The output size is only 15% of the input size.\nTask 2: Next sentence prediction\nMotivated by the fact that many downstream tasks involve the understanding of relationships between sentences (i.e.,\nQA\n,\nNLI\n), BERT added another auxiliary task on training a\nbinary classifier\nfor telling whether one sentence is the next sentence of the other:\nSample sentence pairs (A, B) so that:\n(a) 50% of the time, B follows A;\n(b) 50% of the time, B does not follow A.\nThe model processes both sentences and output a binary label indicating whether B is the next sentence of A.\nThe training data for both auxiliary tasks above can be trivially generated from any monolingual corpus. Hence the scale of training is unbounded. The training loss is the sum of the mean masked LM likelihood and mean next sentence prediction likelihood.\nComparison of BERT, OpenAI GPT and ELMo model architectures. (Image source:\noriginal paper\n)\nInput Embedding\n#\nThe input embedding is the sum of three parts:\nWordPiece tokenization embeddings\n: The\nWordPiece\nmodel\nwas originally proposed for Japanese or Korean segmentation problem. Instead of using naturally split English word, they can be further divided into smaller sub-word units so that it is more effective to handle rare or unknown words. Please read\nlinked\npapers\nfor the optimal way to split words if interested.\nSegment embeddings\n: If the input contains two sentences, they have sentence A embeddings and sentence B embeddings respectively and they are separated by a special character\n[SEP]\n; Only sentence A embeddings are used if the input only contains one sentence.\nPosition embeddings\n: Positional embeddings are learned rather than hard-coded.\nBERT input representation. (Image source:\noriginal paper\n)\nNote that the first token is always forced to be\n[CLS]\n— a placeholder that will be used later for prediction in downstream tasks.\nUse BERT in Downstream Tasks\n#\nBERT fine-tuning requires only a few new parameters added, just like OpenAI GPT.\nFor classification tasks, we get the prediction by taking the final hidden state of the special first token\n[CLS]\n, $\\mathbf{h}^\\text{[CLS]}_L$, and multiplying it with a small weight matrix, $\\text{softmax}(\\mathbf{h}^\\text{[CLS]}_L \\mathbf{W}_\\text{cls})$.\nFor\nQA\ntasks like SQuAD, we need to predict the text span in the given paragraph for an given question. BERT predicts two probability distributions of every token, being the start and the end of the text span. Only two new small matrices, $\\mathbf{W}_\\text{s}$ and $\\mathbf{W}_\\text{e}$, are newly learned during fine-tuning and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{s})$ and $\\text{softmax}(\\mathbf{h}^\\text{(i)}_L \\mathbf{W}_\\text{e})$ define two probability distributions.\nOverall the add-on part for end task fine-tuning is very minimal — one or two weight matrices to convert the Transform hidden states to an interpretable format. Check the paper for implementation details for other cases.\nTraining objects in slightly modified BERT models for downstream tasks.  (Image source:\noriginal paper\n)\nA summary table compares differences between fine-tuning of\nOpenAI GPT\nand BERT.\n|              |\nOpenAI GPT\n|\nBERT\n|\n| Special char |\n[SEP]\nand\n[CLS]\nare only introduced at fine-tuning stage. |\n[SEP]\nand\n[CLS]\nand sentence A/B embeddings are learned at the pre-training stage. |\n| Training process | 1M steps, batch size 32k words. | 1M steps, batch size 128k words. |\n| Fine-tuning  | lr = 5e-5 for all fine-tuning tasks. | Use task-specific lr for fine-tuning. |\nALBERT\n#\nALBERT\n(\nLan, et al. 2019\n), short for\nA Lite BERT\n, is a light-weighted version of\nBERT\nmodel. An ALBERT model can be trained 1.7x faster with 18x fewer parameters, compared to a BERT model of similar configuration. ALBERT incorporates three changes as follows: the first two help reduce parameters and memory consumption and hence speed up the training speed, while the third one proposes a more chanllenging training task to replace the next sentence prediction (NSP) objective.\nFactorized Embedding Parameterization\n#\nIn BERT, the WordPiece tokenization embedding size $E$ is configured to be the same as the hidden state size $H$. That is saying, if we want to increase the model size (larger $H$), we need to learn a larger tokenization embedding too, which is expensive because it depends on the vocabulary size ($V$).\nConceptually, because the tokenization embedding is expected to learn\ncontext-independent\nrepresentation and the hidden states are\ncontext-dependent\n, it makes sense to separate the size of the hidden layers from the size of vocabulary embedding. Using factorized embedding parameterization, the large vocabulary embedding matrix of size $V \\times H$ is decomposed into two small matrices of size $V \\times E$ and $E \\times H$. Given $H \\gt E$ or even $H \\gg E$, factorization can result in significant parameter reduction.\nCross-layer Parameter Sharing\n#\nParameter sharing across layers can happen in many ways: (a) only share feed-forward part; (b) only share attention parameters; or (c) share all the parameters. This technique reduces the number of parameters by a ton and does not damage the performance too much.\nSentence-Order Prediction (SOP)\n#\nInterestingly, the\nnext sentence prediction (NSP)\ntask of BERT turned out to be too easy. ALBERT instead adopted a sentence-order prediction (SOP)\nself-supervised\nloss,\nPositive sample: two consecutive segments from the same document.\nNegative sample: same as above, but the segment order is switched.\nFor the NSP task, the model can make reasonable predictions if it is able to detect topics when A and B are from different contexts. In comparison, SOP is harder as it requires the model to fully understand the coherence and ordering between segments.\nGPT-2\n#\nThe\nOpenAI\nGPT-2\nlanguage model is a direct successor to\nGPT\n. GPT-2 has 1.5B parameters, 10x more than the original GPT, and it achieves SOTA results on 7 out of 8 tested language modeling datasets in a\nzero-shot transfer setting\nwithout any task-specific fine-tuning. The pre-training dataset contains 8 million Web pages collected by crawling qualified outbound links from\nReddit\n. Large improvements by OpenAI GPT-2 are specially noticeable on small datasets and datasets used for measuring\nlong-term dependency\n.\nZero-Shot Transfer\n#\nThe pre-training task for GPT-2 is solely language modeling. All the downstream language tasks are framed as predicting conditional probabilities and there is no task-specific fine-tuning.\nText generation is straightforward using LM.\nMachine translation task, for example, English to Chinese, is induced by conditioning LM on pairs of “English sentence = Chinese sentence” and “the target English sentence =” at the end.\nFor example, the conditional probability to predict might look like:\nP(? | I like green apples. = 我喜欢绿苹果。 A cat meows at him. = 一只猫对他喵。It is raining cats and dogs. =\")\nQA task is formatted similar to translation with pairs of questions and answers in the context.\nSummarization task is induced by adding\nTL;DR:\nafter the articles in the context.\nBPE on Byte Sequences\n#\nSame as the original GPT, GPT-2 uses\nBPE\nbut on\nUTF-8\nbyte sequences. Each byte can represent 256 different values in 8 bits, while UTF-8 can use up to 4 bytes for one character, supporting up to $2^{31}$ characters in total. Therefore, with byte sequence representation we only need a vocabulary of size 256 and do not need to worry about pre-processing, tokenization, etc. Despite of the benefit, current byte-level LMs still have non-negligible performance gap with the SOTA word-level LMs.\nBPE merges frequently co-occurred byte pairs in a greedy manner. To prevent it from generating multiple versions of common words (i.e.\ndog.\n,\ndog!\nand\ndog?\nfor the word\ndog\n), GPT-2 prevents BPE from merging characters across categories (thus\ndog\nwould not be merged with punctuations like\n.\n,\n!\nand\n?\n). This tricks help increase the quality of the final byte segmentation.\nUsing the byte sequence representation, GPT-2 is able to assign a probability to any Unicode string, regardless of any pre-processing steps.\nModel Modifications\n#\nCompared to GPT, other than having many more transformer layers and parameters, GPT-2 incorporates only a few architecture modifications:\nLayer normalization\nwas moved to the input of each sub-block, similar to a residual unit of type\n“building block”\n(differently from the original type\n“bottleneck”\n, it has batch normalization applied before weight layers).\nAn additional layer normalization was added after the final self-attention block.\nA modified initialization was constructed as a function of the model depth.\nThe weights of residual layers were initially scaled by a factor of $1/ \\sqrt{N}$ where N is the number of residual layers.\nUse larger vocabulary size and context size.\nRoBERTa\n#\nRoBERTa\n(short for\nR\nobustly\no\nptimized\nBERT\na\npproach;\nLiu, et al. 2019\n) refers to a new receipt for training BERT to achieve better results, as they found that the original BERT model is significantly undertrained. The receipt contains the following learnings:\nTrain for longer with bigger batch size.\nRemove the\nnext sentence prediction (NSP)\ntask.\nUse longer sequences in training data format. The paper found that using individual sentences as inputs hurts downstream performance. Instead we should use multiple sentences sampled contiguously to form longer segments.\nChange the masking pattern dynamically. The original BERT applies masking once during the data preprocessing stage, resulting in a static mask across training epochs. RoBERTa applies masks in 10 different ways across 40 epochs.\nRoBERTa also added a new dataset\nCommonCrawl News\nand further confirmed that pretraining with\nmore data helps\nimprove the performance on downstream tasks. It was trained with the\nBPE on byte sequences\n, same as in\nGPT-2\n. They also found that choices of hyperparameters have a big impact on the model performance.\nT5\n#\nThe language model\nT5\nis short for\n“Text-to-Text Transfer Transformer”\n(\nRaffel et al., 2020\n). The encoder-decoder implementation follows the\noriginal Transformer\narchitecture: tokens → embedding → encoder → decoder → output. T5 adopts the framework “Natural Language Decathlon” (\nMcCann et al., 2018\n), where many common NLP tasks are translated into question-answering over a context. Instead of an explicit QA format, T5 uses short task prefixes to distinguish task intentions and separately fine-tunes the model on every individual task. The text-to-text framework enables easier transfer learning evaluation with the same model on a diverse set of tasks.\nA diagram of T5 task evaluation. The text-to-text framework casts every task into a generic form: feeding input text to predict some target text. (Image source:\nRaffel et al., 2020\n)\nThe model is trained on Web corpus extracted from Apr 2019 with various filters applied. The model is fine-tuned for each downstream task separately via “adapter layers” (add an extra layer for training) or “gradual unfreezing” (see\nULMFiT\n). Both fine-tuning approaches only update partial parameters while keeping the majority of the model parameters unchanged. T5-11B achieved SOTA results on many NLP tasks.\nAs the authors mentioned in the paper “…our goal is not to propose new methods but instead to provide a comprehensive perspective on where the field stands”, the T5 long paper described a lot of training setup and evaluation processes in detail, a good read for people who are interested in training a LM from scratch.\nGPT-3\n#\nGPT-3\n(\nBrown et al., 2020\n) has the same architecture as\nGPT-2\nbut contains 175B parameters, 10x larger than GPT-2 (1.5B). In addition, GPT-3 uses alternating dense and locally banded sparse attention patterns, same as in\nsparse transformer\n. In order to fit such a huge model across multiple GPUs, GPT-3 is trained with partitions along both width and depth dimension. The training data is a filtered version of Common Crawl mixed with a few other high-quality curated datasets. To avoid the contamination that downstream tasks might appear in the training data, the authors attempted to remove all the overlaps with all the studied benchmark dataset from the training dataset. Unfortunately the filtering process is not perfect due to a bug.\nTraining datasets for GPT-3. Note that the occurrence of each dataset during training is not proportional to the dataset size.  (Table source:\nBrown et al., 2020\n)\nFor all the downstream evaluation, GPT-3 is tested in the few-shot setting without any gradient-based fine-tuning. Here the few-shot examples are provided as part of the prompt. GPT-3 achieves strong performance on many NLP datasets, comparable with fine-tuned BERT models.\nThe evaluation performance increases with the model size and the number of examples. (Image source:\nBrown et al., 2020\n)\nXLNet\n#\nThe\nAutoregressive (AR)\nmodel such as GPT and\nautoencoder (AE)\nmodel such as BERT are two most common ways for language modeling. However, each has their own disadvantages: AR does not learn the bidirectional context, which is needed by downstream tasks like reading comprehension and AE assumes masked positions are independent given all other unmasked tokens which oversimplifies the long context dependency.\nXLNet\n(\nYang et al. 2019\n) generalizes the AE method to incorporate the benefits of AR. XLNet proposed the\npermutation language modeling\nobjective. For a text sequence, it samples a factorization order $\\mathbf{z}$ and decomposes the likelihood $p_\\theta(\\mathbf{x})$ according to this factorization order,\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{XLNet} \n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\sum_{t=1}^T \\log p_\\theta (X_{z_t} = x \\mid \\mathbf{x}_{\\mathbf{z}_{<{t}}})\\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{red}{h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}})}) } \\Big] \\\\\n&= - \\mathbb{E}_{\\mathbf{z} \\sim \\mathcal{Z}_T} \\Big[ \\log \\frac{ \\exp(e(x)^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) }{ \\sum_{x'} \\exp(e(x')^\\top \\color{blue}{g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<{t}}}, z_t)}) } \\Big]\n\\end{aligned}\n$$\nwhere $\\mathcal{Z}_T$ is a set of all possible permutation of length $T$;  $z_t$ and $\\mathbf{z}_{<t}$  denote the $t$-th element and the first $t-1$ elements of a permutation $\\mathbf{z} \\in \\mathcal{Z}_T$.\nNote that the naive representation of the hidden state of the context, $h_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}})$ in red, does not depend on which position the model tries to predict, as the permutation breaks the default ordering. Therefore, XLNet re-parameterized it to a function of the target position too, $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ in blue.\nHowever,  two different requirements on  $g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ lead to a two-stream self-attention design to accommodate:\nWhen predicting $x_{z_t}$, it should only encode the position $z_t$ but not the content $x_{z_t}$; otherwise it is trivial. This is wrapped into the “query representation”  $g_{z_t} = g_\\theta (\\mathbf{x}_{\\mathbf{z}_{<t}}, z_t)$ does not encode $x_{z_t}$.\nWhen predicting $x_j$ where $j > t$, it should encode the content $x_{z_t}$ as well to provide the full context. This is the “content representation” $h_{z_t} = h_\\theta(\\mathbf{x}_{\\leq t})$.\nThe illustration of two-stream self-attention mechanism in XLNet. (Image source:\nYang et al. 2019\n)\nConceptually, the two streams of representations are updated as follows,\n$$\n\\begin{aligned}\ng_{z_t}^{(m)} &\\gets \\text{Attention}(Q = g^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{red}{\\mathbf{z}_{<{t}}}}; \\theta) &\\text{(query stream: use }z_t\\text{ but cannot see }x_{z_t}\\text{)}\\\\\nh_{z_t}^{(m)} &\\gets \\text{Attention}(Q = h^{(m-1)}_{z_t}, KV=\\mathbf{h}^{(m-1)}_{\\color{blue}{\\mathbf{z}_{\\leq t}}}; \\theta) &\\text{(content stream: use both }x_{z_t}\\text{ and }x_{z_t}\\text{)}\\\\\n\\end{aligned}\n$$\nGiven the difficulty of optimization in permutation language modeling, XLNet is set to only predict the last chunk of tokens in a factorization order.\nThe name in XLNet actually comes from\nTransformer-XL\n. It incorporates the design of Transformer-XL to extend the attention span by reusing hidden states from previous segments.\nComparison of model performance of XLNet with a couple other language models on GLUE, all single-task, no ensembles. (Image source:\nYang et al. 2019\n)\nBART\n#\nBART\n(\nLewis et al., 2019\n) is a denoising autoencoder to recover the original text from a randomly corrupted version. It combines\nB\nidirectional and\nA\nuto\nR\negressive\nT\nransformer: precisely, jointly training BERT-like bidirectional encoder and GPT-like autoregressive decoder together. The loss is simply just to minimize the negative log-likelihood.\nA schematic comparison of BART with BERT and GPT. (Image source:\nLewis et al., 2019\n)\nThey experimented with a variety of noising transformations, including token masking, token deletion, text infilling (i.e. A randomly sampled text span, which may contain multiple tokens, is replaced with a\n[MASK]\ntoken), sentence permutation, documentation rotation (i.e. A document is rotated to begin with a random token.). The best noising approach they discovered is text infilling and sentence shuffling.\nComparison of different language modeling pre-training objectives. (Image source:\nLewis et al., 2019\n)\nLearnings from their experiments:\nThe performance of pre-training methods varies significantly across downstream tasks.\nToken masking is crucial, as the performance is poor when only sentence permutation or documentation rotation is applied.\nLeft-to-right pre-training improves generation.\nBidirectional encoders are crucial for SQuAD.\nThe pre-training objective is not the only important factor. Architectural improvements such as relative-position embeddings or segment-level recurrence matter too.\nAutoregressive language models perform best on ELI5.\nBART achieves the most consistently strong performance.\nELECTRA\n#\nMost current pre-training large language models demand a lot of computation resources, raising concerns about their cost and accessibility.\nELECTRA\n(“Efficiently Learning an Encoder that Classifies Token Replacements Accurately”;\nClark et al. 2020\n) aims to improve the\npre-training efficiency\n, which frames the language modeling as a discrimination task instead of generation task.\nIllustration of ELECTRA model architecture. (Image source:\nClark et al. 2020\n)\nELECTRA proposes a new pretraining task, called “Replaced Token Detection” (RTD). Let’s randomly sample $k$ positions to be masked. Each selected token in the original text is replaced by a plausible alternative predicted by a small language model, known as the generator $G$. The discriminator $D$ predicts whether each token is original or replaced.\n$$\n\\begin{aligned}\n\\boldsymbol{m} &= [m_1, \\dots, m_k] \\text{ where } m_i \\sim \\text{unif}\\{1, n\\}\\text{ for } i=1, \\dots, k \\\\\n\\boldsymbol{x}^\\text{masked} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\texttt{[MASK]}) \\\\\n\\boldsymbol{x}^\\text{corrupt} &= \\text{REPLACE}(\\boldsymbol{x}, \\boldsymbol{m}, \\tilde{\\boldsymbol{x}}) \\text{ where } \\tilde{x}_t \\sim p_G(x_i \\mid \\boldsymbol{x}^\\text{masked}) \\text{ for } i \\in \\boldsymbol{m} \\\\\n\\end{aligned}\n$$\nThe loss for the generator is the negative log-likelihood just as in other language models. The loss for the discriminator is the cross-entropy. Note that the generator is not adversarially trained to fool the discriminator but simply to optimize the NLL, since their experiments show negative results.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{MLM}(\\mathbf{x}, \\theta_G) &= \\mathbb{E}\\Big(\\sum_{i \\in \\boldsymbol{m}} -\\log p_G (x_i \\mid \\boldsymbol{x}^\\text{masked} )\\Big) \\\\\n\\mathcal{L}_\\text{Disc}(\\mathbf{x}, \\theta_D) &= \\mathbb{E}\\Big( - \\mathbb{1}[x^\\text{corrupt}_t = x_t] \\log D(\\boldsymbol{x}^\\text{corrupt}, t) - \\mathbb{1}[x^\\text{corrupt}_t \\neq x_t] \\log (1 - \\log D(\\boldsymbol{x}^\\text{corrupt}, t))  \\Big)\n\\end{aligned}\n$$\nThey found it more beneficial to only share the embeddings between generator & discriminator while using a small generator (1/4 to 1/2 the discriminator size), rather than sharing all the weights (i.e. two models have to be the same size then). In addition, joint training of the generator and discriminator works better than two-stage training of each alternatively.\nAfter pretraining the generator is discarded and only the ELECTRA discriminator is fine-tuned further for downstream tasks. The following table shows ELECTRA’s performance on the GLUE dev set.\nComparison of ELECTRA with other language models on the GLUE dev set. (Image source:\nClark et al. 2020\n)\nSummary\n#\nBase model\nPretraining Tasks\nCoVe\nseq2seq NMT model\nsupervised learning using translation dataset.\nELMo\ntwo-layer biLSTM\nnext token prediction\nCVT\ntwo-layer biLSTM\nsemi-supervised learning using both labeled and unlabeled datasets\nULMFiT\nAWD-LSTM\nautoregressive pretraining on Wikitext-103\nGPT\nTransformer decoder\nnext token prediction\nBERT\nTransformer encoder\nmask language model + next sentence prediction\nALBERT\nsame as BERT but light-weighted\nmask language model + sentence order prediction\nGPT-2\nTransformer decoder\nnext token prediction\nRoBERTa\nsame as BERT\nmask language model (dynamic masking)\nT5\nTransformer encoder + decoder\npre-trained on a multi-task mixture of unsupervised and supervised tasks and for which each task is converted into a text-to-text format.\nGPT-3\nTransformer decoder\nnext token prediction\nXLNet\nsame as BERT\npermutation language modeling\nBART\nBERT encoder + GPT decoder\nreconstruct text from a noised version\nELECTRA\nsame as BERT\nreplace token detection\nMetric: Perplexity\n#\nPerplexity is often used as an intrinsic evaluation metric for gauging how well a language model can capture the real word distribution conditioned on the context.\nA\nperplexity\nof a discrete proability distribution $p$ is defined as the exponentiation of the entropy:\n$$\n2^{H(p)} = 2^{-\\sum_x p(x) \\log_2 p(x)}\n$$\nGiven a sentence with $N$ words, $s = (w_1, \\dots, w_N)$, the entropy looks as follows, simply assuming that each word has the same frequency, $\\frac{1}{N}$:\n$$\nH(s) = -\\sum_{i=1}^N P(w_i) \\log_2  p(w_i)  = -\\sum_{i=1}^N \\frac{1}{N} \\log_2  p(w_i)\n$$\nThe perplexity for the sentence becomes:\n$$\n\\begin{aligned}\n2^{H(s)} &= 2^{-\\frac{1}{N} \\sum_{i=1}^N \\log_2  p(w_i)}\n= (2^{\\sum_{i=1}^N \\log_2  p(w_i)})^{-\\frac{1}{N}}\n= (p(w_1) \\dots p(w_N))^{-\\frac{1}{N}}\n\\end{aligned}\n$$\nA good language model should predict high word probabilities. Therefore, the smaller perplexity the better.\nCommon Tasks and Datasets\n#\nQuestion-Answering\nSQuAD\n(Stanford Question Answering Dataset): A reading comprehension dataset, consisting of questions posed on a set of Wikipedia articles, where the answer to every question is a span of text.\nRACE\n(ReAding Comprehension from Examinations): A large-scale reading comprehension dataset with more than 28,000 passages and nearly 100,000 questions. The dataset is collected from English examinations in China, which are designed for middle school and high school students.\nSee\nmore QA datasets in a later post\n.\nCommonsense Reasoning\nStory Cloze Test\n: A commonsense reasoning framework for evaluating story understanding and generation. The test requires a system to choose the correct ending to multi-sentence stories from two options.\nSWAG\n(Situations With Adversarial Generations): multiple choices; contains 113k sentence-pair completion examples that evaluate grounded common-sense inference\nNatural Language Inference (NLI)\n: also known as\nText Entailment\n, an exercise to discern in logic whether one sentence can be inferred from another.\nRTE\n(Recognizing Textual Entailment): A set of datasets initiated by text entailment challenges.\nSNLI\n(Stanford Natural Language Inference): A collection of 570k human-written English sentence pairs manually labeled for balanced classification with the labels\nentailment\n,\ncontradiction\n, and\nneutral\n.\nMNLI\n(Multi-Genre NLI): Similar to SNLI, but with a more diverse variety of text styles and topics, collected from transcribed speech, popular fiction, and government reports.\nQNLI\n(Question NLI): Converted from SQuAD dataset to be a binary classification task over pairs of (question, sentence).\nSciTail\n: An entailment dataset created from multiple-choice science exams and web sentences.\nNamed Entity Recognition (NER)\n: labels sequences of words in a text which are the names of things, such as person and company names, or gene and protein names\nCoNLL 2003 NER task\n: consists of newswire from the Reuters, concentrating on four types of named entities: persons, locations, organizations and names of miscellaneous entities.\nOntoNotes 5.0\n: This corpus contains text in English, Arabic and Chinese, tagged with four different entity types (PER, LOC, ORG, MISC).\nReuters Corpus\n: A large collection of Reuters News stories.\nFine-Grained NER (FGN)\nSentiment Analysis\nSST\n(Stanford Sentiment Treebank)\nIMDb\n: A large dataset of movie reviews with binary sentiment classification labels.\nSemantic Role Labeling (SRL)\n: models the predicate-argument structure of a sentence, and is often described as answering “Who did what to whom”.\nCoNLL-2004 & CoNLL-2005\nSentence similarity\n: also known as\nparaphrase detection\nMRPC\n(MicRosoft Paraphrase Corpus): It contains pairs of sentences extracted from news sources on the web, with annotations indicating whether each pair is semantically equivalent.\nQQP\n(Quora Question Pairs)\nSTS Benchmark: Semantic Textual Similarity\nSentence Acceptability\n: a task to annotate sentences for grammatical acceptability.\nCoLA\n(Corpus of Linguistic Acceptability): a binary single-sentence classification task.\nText Chunking\n: To divide a text in syntactically correlated parts of words.\nCoNLL-2000\nPart-of-Speech (POS) Tagging\n: tag parts of speech to each token, such as noun, verb, adjective, etc.\nthe Wall Street Journal portion of the Penn Treebank (Marcus et al., 1993).\nMachine Translation\n:  See\nStandard NLP\npage.\nWMT 2015 English-Czech data (Large)\nWMT 2014 English-German data (Medium)\nIWSLT 2015 English-Vietnamese data (Small)\nCoreference Resolution\n: cluster mentions in text that refer to the same underlying real world entities.\nCoNLL-2012\nLong-range Dependency\nLAMBADA\n(LAnguage Modeling Broadened to Account for Discourse Aspects): A collection of narrative passages extracted from the BookCorpus and the task is to predict the last word, which require at least 50 tokens of context for a human to successfully predict.\nChildren’s Book Test\n: is built from books that are freely available in\nProject Gutenberg\n. The task is to predict the missing word among 10 candidates.\nMulti-task benchmark\nGLUE multi-task benchmark:\nhttps://gluebenchmark.com\ndecaNLP benmark:\nhttps://decanlp.com\nUnsupervised pretraining dataset\nBooks corpus\n: The corpus contains “over 7,000 unique unpublished books from a variety of genres including Adventure, Fantasy, and Romance.”\n1B Word Language Model Benchmark\nEnglish Wikipedia\n: ~2500M words\nCited as:\n@article{weng2019LM,\n  title   = \"Generalized Language Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2019\",\n  url     = \"https://lilianweng.github.io/posts/2019-01-31-lm/\"\n}\nReference\n#\n[1] Bryan McCann, et al.\n“Learned in translation: Contextualized word vectors.”\nNIPS. 2017.\n[2] Kevin Clark et al.\n“Semi-Supervised Sequence Modeling with Cross-View Training.”\nEMNLP 2018.\n[3] Matthew E. Peters, et al.\n“Deep contextualized word representations.”\nNAACL-HLT 2017.\n[4] OpenAI Blog\n“Improving Language Understanding with Unsupervised Learning”\n, June 11, 2018.\n[5] OpenAI Blog\n“Better Language Models and Their Implications.”\nFeb 14, 2019.\n[6] Jeremy Howard and Sebastian Ruder.\n“Universal language model fine-tuning for text classification.”\nACL 2018.\n[7] Alec Radford et al.\n“Improving Language Understanding by Generative Pre-Training”\n. OpenAI Blog, June 11, 2018.\n[8] Jacob Devlin, et al.\n“BERT: Pre-training of deep bidirectional transformers for language understanding.”\narXiv:1810.04805 (2018).\n[9] Mike Schuster, and Kaisuke Nakajima.\n“Japanese and Korean voice search.”\nICASSP. 2012.\n[10] Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation\n[11] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[12] Peter J. Liu, et al.\n“Generating wikipedia by summarizing long sequences.”\nICLR 2018.\n[13] Sebastian Ruder.\n“10 Exciting Ideas of 2018 in NLP”\nDec 2018.\n[14] Alec Radford, et al.\n“Language Models are Unsupervised Multitask Learners.”\n. 2019.\n[15] Rico Sennrich, et al.\n“Neural machine translation of rare words with subword units.”\narXiv preprint arXiv:1508.07909. 2015.\n[16] Zhenzhong Lan, et al.\n“ALBERT: A Lite BERT for Self-supervised Learning of Language Representations.”\narXiv Preprint arXiv:1909.11942 (2019).\n[17] Yinhan Liu, et al.\n“RoBERTa: A Robustly Optimized BERT Pretraining Approach.”\narXiv Preprint arXiv:1907.11692 (2019).\n[18] Tom B Brown, et al.\n“Language Models are Few-Shot Learners”\nNeuriPS 2020.\n[19] Zhilin Yang et al.\n“XLNet: Generalized Autoregressive Pretraining for Language Understanding.”\nNeuriPS 2019.\n[20] Mike Lewis et al.\n“BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension.”\nACL 2020.\n[21] Kevin Clark et al.\n“ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators.”\nICLR 2020.\n[22] Colin Raffel, et al.\n“Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer”\nJMLR 2020.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:17Z",
            "title": "Generalized Language Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/607baf97b999/code/body-000.txt",
                "chars": 214,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1810.04805",
                "bytes": 775166,
                "reused": true,
                "local_path": "papers/repair/33769e0bafc9f0c73baa.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.08883",
                "bytes": 788571,
                "reused": true,
                "local_path": "papers/repair/db0e3c5521e5a1800c77.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.00107",
                "bytes": 446263,
                "reused": true,
                "local_path": "papers/repair/e2c0a99965fb6abdde60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05365",
                "bytes": 425880,
                "reused": true,
                "local_path": "papers/repair/c4dc3d740cad43df1dd2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.08370",
                "bytes": 811545,
                "reused": true,
                "local_path": "papers/repair/459221e6be389ff8d946.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.06146",
                "bytes": 979417,
                "reused": true,
                "local_path": "papers/repair/f99f602eebf2965d0ed0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02182",
                "bytes": 185413,
                "reused": true,
                "local_path": "papers/repair/f2555bb43fcea5781c7c.pdf"
              },
              {
                "status": "http_403",
                "url": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "retried_at": "2026-10-20T18:10:14Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1801.10198",
                "bytes": 1134703,
                "reused": true,
                "local_path": "papers/repair/fe35dee079dad5528221.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.07909",
                "bytes": 193216,
                "reused": true,
                "local_path": "papers/repair/a5d0ca76205630ec8110.pdf"
              },
              {
                "status": "ok",
                "url": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "bytes": 144257,
                "reused": true,
                "local_path": "papers/repair/0eab031e51f81c92fda2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.08144.pdf",
                "bytes": 1688289,
                "reused": true,
                "local_path": "papers/repair/29316aab6d109d3a9ea6.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.11942",
                "bytes": 419105,
                "reused": true,
                "local_path": "papers/repair/9c6f91591bd290ea5163.pdf"
              },
              {
                "status": "download_error",
                "url": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "reason": "ConnectionError: HTTPSConnectionPool(host='d4mucfpksywv.cloudfront.net', port=443): Max retries exceeded with url: /better-language-models/language_models_are_unsupervised_multitask_learners.pdf (C",
                "retried_at": "2026-10-20T22:25:42Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1607.06450",
                "bytes": 612446,
                "reused": true,
                "local_path": "papers/repair/52a2360d9b658baa64ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.05027",
                "bytes": 1166414,
                "reused": true,
                "local_path": "papers/repair/780d6bd86240bf248474.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385",
                "bytes": 819383,
                "reused": true,
                "local_path": "papers/repair/523013cf51110acbfe60.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1907.11692",
                "bytes": 209675,
                "reused": true,
                "local_path": "papers/repair/8acd467c11db68744d3f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10683",
                "bytes": 1190021,
                "reused": true,
                "local_path": "papers/repair/4e0745eb290124ed9e02.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.08730",
                "bytes": 1187133,
                "reused": true,
                "local_path": "papers/repair/e2a98f1a611cef094a63.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2005.14165",
                "bytes": 6768044,
                "reused": true,
                "local_path": "papers/repair/0c1629d8d07d676c2aae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1906.08237",
                "bytes": 761790,
                "reused": true,
                "local_path": "papers/repair/e1dc08bfcdc2d830fa23.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.13461",
                "bytes": 296072,
                "reused": true,
                "local_path": "papers/repair/006bd94b666a1c81bc24.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.10555",
                "bytes": 497999,
                "reused": true,
                "local_path": "papers/repair/95df7a9ffe51e8dc3c44.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 53020,
            "expected_body_images": 23,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_403",
            "raw_html": "attachments/607baf97b999/pages/source.html",
            "local_html": "attachments/607baf97b999/pages/article.html",
            "body_base_path": "attachments/607baf97b999/pages/",
            "body_markdown_path": "attachments/607baf97b999/pages/article.md",
            "links": [
              {
                "href": "https://www.youtube.com/watch?v=l5einDQ-Ttc",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/language-unsupervised/",
                "label": "OpenAI GPT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1810.04805",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.08883",
                "label": "found",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-15-word-embedding/",
                "label": "post on word embedding",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.00107",
                "label": "McCann et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attentional seq-to-seq",
                "type": "a"
              },
              {
                "href": "https://github.com/THUNLP-MT/MT-Reading-List",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05365",
                "label": "Peters, et al, 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Part-of-speech_tagging",
                "label": "part-of-speech",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.08370",
                "label": "Clark et al., 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Beam_search",
                "label": "beam search",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.06146",
                "label": "Howard & Ruder, 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02182",
                "label": "AWD-LSTM",
                "type": "a"
              },
              {
                "href": "https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf",
                "label": "Radford et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "original transformer",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1801.10198",
                "label": "transformer decoder",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.07909",
                "label": "BPE",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Cloze_test",
                "label": "Wikipedia",
                "type": "a"
              },
              {
                "href": "https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf",
                "label": "WordPiece",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1609.08144.pdf",
                "label": "model",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.11942",
                "label": "Lan, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-11-10-self-supervised/",
                "label": "self-supervised",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/better-language-models/",
                "label": "OpenAI",
                "type": "a"
              },
              {
                "href": "https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf",
                "label": "GPT-2",
                "type": "a"
              },
              {
                "href": "https://www.reddit.com/",
                "label": "Reddit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/UTF-8",
                "label": "UTF-8",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1607.06450",
                "label": "Layer normalization",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1603.05027",
                "label": "“building block”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.03385",
                "label": "“bottleneck”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1907.11692",
                "label": "Liu, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://commoncrawl.org/2016/10/news-dataset-available/",
                "label": "CommonCrawl News",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10683",
                "label": "Raffel et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.08730",
                "label": "McCann et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2005.14165",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "sparse transformer",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/2020/hash/1457c0d6bfcb4967418bfb8ac142f64a-Abstract.html",
                "label": "Brown et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1906.08237",
                "label": "Yang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.13461",
                "label": "Lewis et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.10555",
                "label": "Clark et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Perplexity",
                "label": "perplexity",
                "type": "a"
              },
              {
                "href": "https://rajpurkar.github.io/SQuAD-explorer/",
                "label": "SQuAD",
                "type": "a"
              },
              {
                "href": "http://www.qizhexie.com/data/RACE_leaderboard",
                "label": "RACE",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-10-29-odqa/",
                "label": "more QA datasets in a later post",
                "type": "a"
              },
              {
                "href": "http://cs.rochester.edu/nlp/rocstories/",
                "label": "Story Cloze Test",
                "type": "a"
              },
              {
                "href": "https://rowanzellers.com/swag/",
                "label": "SWAG",
                "type": "a"
              },
              {
                "href": "https://aclweb.org/aclwiki/Textual_Entailment_Resource_Pool",
                "label": "RTE",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/snli/",
                "label": "SNLI",
                "type": "a"
              },
              {
                "href": "https://www.nyu.edu/projects/bowman/multinli/",
                "label": "MNLI",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/tasks",
                "label": "QNLI",
                "type": "a"
              },
              {
                "href": "http://data.allenai.org/scitail/",
                "label": "SciTail",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2003/",
                "label": "CoNLL 2003 NER task",
                "type": "a"
              },
              {
                "href": "https://catalog.ldc.upenn.edu/LDC2013T19",
                "label": "OntoNotes 5.0",
                "type": "a"
              },
              {
                "href": "https://trec.nist.gov/data/reuters/reuters.html",
                "label": "Reuters Corpus",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/sentiment/index.html",
                "label": "SST",
                "type": "a"
              },
              {
                "href": "http://ai.stanford.edu/~amaas/data/sentiment/",
                "label": "IMDb",
                "type": "a"
              },
              {
                "href": "http://www.lsi.upc.edu/~srlconll/",
                "label": "CoNLL-2004 & CoNLL-2005",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/download/details.aspx?id=52398",
                "label": "MRPC",
                "type": "a"
              },
              {
                "href": "https://data.quora.com/First-Quora-Dataset-Release-Question-Pairs",
                "label": "QQP",
                "type": "a"
              },
              {
                "href": "https://nyu-mll.github.io/CoLA/",
                "label": "CoLA",
                "type": "a"
              },
              {
                "href": "https://www.clips.uantwerpen.be/conll2000/chunking/",
                "label": "CoNLL-2000",
                "type": "a"
              },
              {
                "href": "https://nlp.stanford.edu/projects/nmt/",
                "label": "Standard NLP",
                "type": "a"
              },
              {
                "href": "http://conll.cemantix.org/2012/data.html",
                "label": "CoNLL-2012",
                "type": "a"
              },
              {
                "href": "http://clic.cimec.unitn.it/lambada/",
                "label": "LAMBADA",
                "type": "a"
              },
              {
                "href": "https://research.fb.com/downloads/babi/",
                "label": "Children’s Book Test",
                "type": "a"
              },
              {
                "href": "https://www.gutenberg.org/",
                "label": "Project Gutenberg",
                "type": "a"
              },
              {
                "href": "https://gluebenchmark.com/",
                "label": "https://gluebenchmark.com",
                "type": "a"
              },
              {
                "href": "https://decanlp.com/",
                "label": "https://decanlp.com",
                "type": "a"
              },
              {
                "href": "https://googlebooks.byu.edu/",
                "label": "Books corpus",
                "type": "a"
              },
              {
                "href": "http://www.statmt.org/lm-benchmark/",
                "label": "1B Word Language Model Benchmark",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wikipedia:Database_download",
                "label": "English Wikipedia",
                "type": "a"
              },
              {
                "href": "http://ruder.io/10-exciting-ideas-of-2018-in-nlp/",
                "label": "“10 Exciting Ideas of 2018 in NLP”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
          "status": "ok",
          "article_id": "95e296d541c5",
          "local_path": "series-follow/1601/repair/0131ab3df6b3801717f6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
              "bytes": 378234,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/42322906964d7eff1651.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
              "bytes": 283407,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f9b6ebe483799e46cae4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
              "bytes": 228747,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0ea74210b7f6fad038ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
              "bytes": 213880,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9dbbde4fd84a2ab2174a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
              "bytes": 499620,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b1980ce4c249a0e87c8a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
              "bytes": 104570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a4dc57fb545108aefd87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
              "bytes": 302909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3165312c8d71a60275e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
              "bytes": 317756,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9c33dac85d8f8acfff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
              "bytes": 836105,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/54a750cb98f126791091.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
              "bytes": 457704,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/822dbc554a0a4c217494.png"
            }
          ],
          "article": {
            "id": "95e296d541c5",
            "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "bytes": 378234,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-42322906964d7eff1651.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/three-generative-models.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "bytes": 283407,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-f9b6ebe483799e46cae4.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/normalizing-flow.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "bytes": 228747,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-0ea74210b7f6fad038ef.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/one-glow-step.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "bytes": 213880,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9dbbde4fd84a2ab2174a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/glow-table.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "bytes": 499620,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-b1980ce4c249a0e87c8a.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MADE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "bytes": 104570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-a4dc57fb545108aefd87.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-rnn-context.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "bytes": 302909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-3165312c8d71a60275e1.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/diagonal-biLSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "bytes": 317756,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-9c33dac85d8f8acfff22.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/pixel-cnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "bytes": 836105,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-54a750cb98f126791091.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/wavenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "bytes": 457704,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/95e296d541c5/images/body-822dbc554a0a4c217494.png",
                "src": "https://lilianweng.github.io/posts/2018-10-13-flow-models/MAF-vs-IAF.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "So far, I’ve written about two types of generative models,\nGAN\nand\nVAE\n. Neither of them explicitly learns the probability density function of real data, $p(\\mathbf{x})$ (where $\\mathbf{x} \\in \\mathcal{D}$) — because it is really hard! Taking the generative model with latent variables as an example, $p(\\mathbf{x}) = \\int p(\\mathbf{x}\\vert\\mathbf{z})p(\\mathbf{z})d\\mathbf{z}$ can hardly be calculated as it is intractable to go through all possible values of the latent code $\\mathbf{z}$.\nFlow-based deep generative models conquer this hard problem with the help of\nnormalizing flows\n, a powerful statistics tool for density estimation. A good estimation of $p(\\mathbf{x})$ makes it possible to efficiently complete many downstream tasks: sample unobserved but realistic new data points (data generation), predict the rareness of future events (density estimation), infer latent variables, fill in incomplete data samples, etc.\nTypes of Generative Models\n#\nHere is a quick summary of the difference between GAN, VAE, and flow-based generative models:\nGenerative adversarial networks: GAN provides a smart solution to model the data generation, an unsupervised learning problem, as a supervised one. The discriminator model learns to distinguish the real data from the fake samples that are produced by the generator model. Two models are trained as they are playing a\nminimax\ngame.\nVariational autoencoders: VAE inexplicitly optimizes the log-likelihood of the data by maximizing the evidence lower bound (ELBO).\nFlow-based generative models: A flow-based generative model is constructed by a sequence of invertible transformations. Unlike other two, the model explicitly learns the data distribution $p(\\mathbf{x})$ and therefore the loss function is simply the negative log-likelihood.\nComparison of three categories of generative models.\nLinear Algebra Basics Recap\n#\nWe should understand two key concepts before getting into the flow-based generative model: the Jacobian determinant and the change of variable rule. Pretty basic, so feel free to skip.\nJacobian Matrix and Determinant\n#\nGiven a function of mapping a $n$-dimensional input vector $\\mathbf{x}$ to a $m$-dimensional output vector, $\\mathbf{f}: \\mathbb{R}^n \\mapsto \\mathbb{R}^m$, the matrix of all first-order partial derivatives of this function is called the\nJacobian matrix\n, $\\mathbf{J}$ where one entry on the i-th row and j-th column is $\\mathbf{J}_{ij} = \\frac{\\partial f_i}{\\partial x_j}$.\n$$\n\\mathbf{J} = \\begin{bmatrix}\n\\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\[6pt]\n\\vdots & \\ddots & \\vdots \\\\[6pt]\n\\frac{\\partial f_m}{\\partial x_1} & \\dots & \\frac{\\partial f_m}{\\partial x_n} \\\\[6pt]\n\\end{bmatrix}\n$$\nThe determinant is one real number computed as a function of all the elements in a squared matrix. Note that the determinant\nonly exists for\nsquare\nmatrices\n. The absolute value of the determinant can be thought of as a measure of\n“how much multiplication by the matrix expands or contracts space”.\nThe determinant of a nxn matrix $M$ is:\n$$\n\\det M = \\det \\begin{bmatrix}\na_{11} & a_{12} & \\dots & a_{1n} \\\\\na_{21} & a_{22} & \\dots & a_{2n} \\\\\n\\vdots & \\vdots & & \\vdots \\\\\na_{n1} & a_{n2} & \\dots & a_{nn} \\\\\n\\end{bmatrix} = \\sum_{j_1 j_2 \\dots j_n} (-1)^{\\tau(j_1 j_2 \\dots j_n)} a_{1j_1} a_{2j_2} \\dots a_{nj_n}\n$$\nwhere the subscript under the summation $j_1 j_2 \\dots j_n$ are all permutations of the set {1, 2, …, n}, so there are $n!$ items in total; $\\tau(.)$ indicates the\nsignature\nof a permutation.\nThe determinant of a square matrix $M$ detects whether it is invertible: If $\\det(M)=0$ then $M$ is not invertible (a\nsingular\nmatrix with linearly dependent rows or columns; or any row or column is all 0); otherwise, if $\\det(M)\\neq 0$, $M$ is invertible.\nThe determinant of the product is equivalent to the product of the determinants: $\\det(AB) = \\det(A)\\det(B)$. (\nproof\n)\nChange of Variable Theorem\n#\nLet’s review the change of variable theorem specifically in the context of probability density estimation, starting with a single variable case.\nGiven a random variable $z$ and its known probability density function $z \\sim \\pi(z)$, we would like to construct a new random variable using a 1-1 mapping function $x = f(z)$. The function $f$ is invertible, so $z=f^{-1}(x)$. Now the question is\nhow to infer the unknown probability density function of the new variable\n, $p(x)$?\n$$\n\\begin{aligned}\n& \\int p(x)dx = \\int \\pi(z)dz = 1 \\scriptstyle{\\text{   ; Definition of probability distribution.}}\\\\\n& p(x) = \\pi(z) \\left\\vert\\frac{dz}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\left\\vert\\frac{d f^{-1}}{dx}\\right\\vert = \\pi(f^{-1}(x)) \\vert (f^{-1})'(x) \\vert\n\\end{aligned}\n$$\nBy definition, the integral $\\int \\pi(z)dz$ is the sum of an infinite number of rectangles of infinitesimal width $\\Delta z$. The height of such a rectangle at position $z$ is the value of the density function $\\pi(z)$. When we substitute the variable, $z = f^{-1}(x)$ yields $\\frac{\\Delta z}{\\Delta x} = (f^{-1}(x))’$ and $\\Delta z =  (f^{-1}(x))’ \\Delta x$. Here $\\vert(f^{-1}(x))’\\vert$ indicates the ratio between the area of rectangles defined in two different coordinate of variables $z$ and $x$ respectively.\nThe multivariable version has a similar format:\n$$\n\\begin{aligned}\n\\mathbf{z} &\\sim \\pi(\\mathbf{z}), \\mathbf{x} = f(\\mathbf{z}), \\mathbf{z} = f^{-1}(\\mathbf{x}) \\\\\np(\\mathbf{x}) \n&= \\pi(\\mathbf{z}) \\left\\vert \\det \\dfrac{d \\mathbf{z}}{d \\mathbf{x}} \\right\\vert  \n= \\pi(f^{-1}(\\mathbf{x})) \\left\\vert \\det \\dfrac{d f^{-1}}{d \\mathbf{x}} \\right\\vert\n\\end{aligned}\n$$\nwhere $\\det \\frac{\\partial f}{\\partial\\mathbf{z}}$ is the Jacobian determinant of the function $f$. The full proof of the multivariate version is out of the scope of this post; ask Google if interested ;)\nWhat is Normalizing Flows?\n#\nBeing able to do good density estimation has direct applications in many machine learning problems, but it is very hard. For example, since we need to run backward propagation in deep learning models, the embedded probability distribution (i.e. posterior $p(\\mathbf{z}\\vert\\mathbf{x})$) is expected to be simple enough to calculate the derivative easily and efficiently. That is why Gaussian distribution is often used in latent variable generative models, even though most of real world distributions are much more complicated than Gaussian.\nHere comes a\nNormalizing Flow\n(NF) model for better and more powerful distribution approximation. A normalizing flow transforms a simple distribution into a complex one by applying a sequence of invertible transformation functions. Flowing through a chain of transformations, we repeatedly substitute the variable for the new one according to the change of variables theorem and eventually obtain a probability distribution of the final target variable.\nIllustration of a normalizing flow model, transforming a simple distribution $p\\_0(\\mathbf{z}\\_0)$ to a complex one $p\\_K(\\mathbf{z}\\_K)$ step by step.\nAs defined in Fig. 2,\n$$\n\\begin{aligned}\n\\mathbf{z}_{i-1} &\\sim p_{i-1}(\\mathbf{z}_{i-1}) \\\\\n\\mathbf{z}_i &= f_i(\\mathbf{z}_{i-1})\\text{, thus }\\mathbf{z}_{i-1} = f_i^{-1}(\\mathbf{z}_i) \\\\\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert\n\\end{aligned}\n$$\nThen let’s convert the equation to be a function of $\\mathbf{z}_i$ so that we can do inference with the base distribution.\n$$\n\\begin{aligned}\np_i(\\mathbf{z}_i) \n&= p_{i-1}(f_i^{-1}(\\mathbf{z}_i)) \\left\\vert \\det\\dfrac{d f_i^{-1}}{d \\mathbf{z}_i} \\right\\vert \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\left\\vert \\det \\color{red}{\\Big(\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\Big)^{-1}} \\right\\vert & \\scriptstyle{\\text{; According to the inverse func theorem.}} \\\\\n&= p_{i-1}(\\mathbf{z}_{i-1}) \\color{red}{\\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert^{-1}} & \\scriptstyle{\\text{; According to a property of Jacobians of invertible func.}} \\\\\n\\log p_i(\\mathbf{z}_i) &= \\log p_{i-1}(\\mathbf{z}_{i-1}) - \\log \\left\\vert \\det \\dfrac{d f_i}{d\\mathbf{z}_{i-1}} \\right\\vert\n\\end{aligned}\n$$\n(*) A note on the\n“inverse function theorem”\n: If $y=f(x)$ and $x=f^{-1}(y)$, we have:\n$$\n\\dfrac{df^{-1}(y)}{dy} = \\dfrac{dx}{dy} = (\\dfrac{dy}{dx})^{-1} = (\\dfrac{df(x)}{dx})^{-1}\n$$\n(*) A note on\n“Jacobians of invertible function”\n: The determinant of the inverse of an invertible matrix is the inverse of the determinant: $\\det(M^{-1}) = (\\det(M))^{-1}$,\nbecause\n$\\det(M)\\det(M^{-1}) = \\det(M \\cdot M^{-1}) = \\det(I) = 1$.\nGiven such a chain of probability density functions, we know the relationship between each pair of consecutive variables. We can expand the equation of the output $\\mathbf{x}$ step by step until tracing back to the initial distribution $\\mathbf{z}_0$.\n$$\n\\begin{aligned}\n\\mathbf{x} = \\mathbf{z}_K &= f_K \\circ f_{K-1} \\circ \\dots \\circ f_1 (\\mathbf{z}_0) \\\\\n\\log p(\\mathbf{x}) = \\log \\pi_K(\\mathbf{z}_K) \n&= \\log \\pi_{K-1}(\\mathbf{z}_{K-1}) - \\log\\left\\vert\\det\\dfrac{d f_K}{d \\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\log \\pi_{K-2}(\\mathbf{z}_{K-2}) - \\log\\left\\vert\\det\\dfrac{d f_{K-1}}{d\\mathbf{z}_{K-2}}\\right\\vert - \\log\\left\\vert\\det\\dfrac{d f_K}{d\\mathbf{z}_{K-1}}\\right\\vert \\\\\n&= \\dots \\\\\n&= \\log \\pi_0(\\mathbf{z}_0) - \\sum_{i=1}^K \\log\\left\\vert\\det\\dfrac{d f_i}{d\\mathbf{z}_{i-1}}\\right\\vert\n\\end{aligned}\n$$\nThe path traversed by the random variables $\\mathbf{z}_i = f_i(\\mathbf{z}_{i-1})$ is the\nflow\nand the full chain formed by the successive distributions $\\pi_i$ is called a\nnormalizing flow\n. Required by the computation in the equation, a transformation function $f_i$ should satisfy two properties:\nIt is easily invertible.\nIts Jacobian determinant is easy to compute.\nModels with Normalizing Flows\n#\nWith normalizing flows in our toolbox, the exact log-likelihood of input data $\\log p(\\mathbf{x})$ becomes tractable. As a result, the training criterion of flow-based generative model is simply the negative log-likelihood (NLL) over the training dataset $\\mathcal{D}$:\n$$\n\\mathcal{L}(\\mathcal{D}) = - \\frac{1}{\\vert\\mathcal{D}\\vert}\\sum_{\\mathbf{x} \\in \\mathcal{D}} \\log p(\\mathbf{x})\n$$\nRealNVP\n#\nThe\nRealNVP\n(Real-valued Non-Volume Preserving;\nDinh et al., 2017\n) model implements a normalizing flow by stacking a sequence of invertible bijective transformation functions. In each bijection $f: \\mathbf{x} \\mapsto \\mathbf{y}$, known as\naffine coupling layer\n,  the input dimensions are split into two parts:\nThe first $d$ dimensions stay same;\nThe second part, $d+1$ to $D$ dimensions, undergo an affine transformation (“scale-and-shift”) and both the scale and shift parameters are functions of the first $d$ dimensions.\n$$\n\\begin{aligned}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{aligned}\n$$\nwhere $s(.)$ and $t(.)$ are\nscale\nand\ntranslation\nfunctions and both map $\\mathbb{R}^d \\mapsto \\mathbb{R}^{D-d}$. The $\\odot$ operation is the element-wise product.\nNow let’s check whether this transformation satisfy two basic properties  for a flow transformation.\nCondition 1\n: “It is easily invertible.”\nYes and it is fairly straightforward.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} \\odot \\exp({s(\\mathbf{x}_{1:d})}) + t(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= (\\mathbf{y}_{d+1:D} - t(\\mathbf{y}_{1:d})) \\odot \\exp(-s(\\mathbf{y}_{1:d}))\n\\end{cases}\n$$\nCondition 2\n: “Its Jacobian determinant is easy to compute.”\nYes. It is not hard to get the Jacobian matrix and determinant of this transformation. The Jacobian is a lower triangular matrix.\n$$\n\\mathbf{J} = \n\\begin{bmatrix}\n  \\mathbb{I}_d & \\mathbf{0}_{d\\times(D-d)} \\\\[5pt]\n  \\frac{\\partial \\mathbf{y}_{d+1:D}}{\\partial \\mathbf{x}_{1:d}} & \\text{diag}(\\exp(s(\\mathbf{x}_{1:d})))\n\\end{bmatrix}\n$$\nHence the determinant is simply the product of terms on the diagonal.\n$$\n\\det(\\mathbf{J}) \n= \\prod_{j=1}^{D-d}\\exp(s(\\mathbf{x}_{1:d}))_j\n= \\exp(\\sum_{j=1}^{D-d} s(\\mathbf{x}_{1:d})_j)\n$$\nSo far, the affine coupling layer looks perfect for constructing a normalizing flow :)\nEven better, since (i) computing $f^-1$ does not require computing the inverse of $s$ or $t$ and (ii) computing the Jacobian determinant does not involve computing the Jacobian of $s$ or $t$, those functions can be\narbitrarily complex\n; i.e. both $s$ and $t$ can be modeled by deep neural networks.\nIn one affine coupling layer, some dimensions (channels) remain unchanged. To make sure all the inputs have a chance to be altered, the model reverses the ordering in each layer so that different components are left unchanged. Following such an alternating pattern, the set of units which remain identical in one transformation layer are always modified in the next. Batch normalization is found to help training models with a very deep stack of coupling layers.\nFurthermore, RealNVP can work in a multi-scale architecture to build a more efficient model for large inputs. The multi-scale architecture applies several “sampling” operations to normal affine layers, including spatial checkerboard pattern masking, squeezing operation, and channel-wise masking. Read the\npaper\nfor more details on the multi-scale architecture.\nNICE\n#\nThe\nNICE\n(Non-linear Independent Component Estimation;\nDinh, et al. 2015\n) model is a predecessor of\nRealNVP\n. The transformation in NICE is the affine coupling layer without the scale term, known as\nadditive coupling layer\n.\n$$\n\\begin{cases}\n\\mathbf{y}_{1:d} &= \\mathbf{x}_{1:d} \\\\ \n\\mathbf{y}_{d+1:D} &= \\mathbf{x}_{d+1:D} + m(\\mathbf{x}_{1:d})\n\\end{cases}\n\\Leftrightarrow \n\\begin{cases}\n\\mathbf{x}_{1:d} &= \\mathbf{y}_{1:d} \\\\ \n\\mathbf{x}_{d+1:D} &= \\mathbf{y}_{d+1:D} - m(\\mathbf{y}_{1:d})\n\\end{cases}\n$$\nGlow\n#\nThe\nGlow\n(\nKingma and Dhariwal, 2018\n) model extends the previous reversible generative models, NICE and RealNVP, and simplifies the architecture by replacing the reverse permutation operation on the channel ordering with invertible 1x1 convolutions.\nOne step of flow in the Glow model. (Image source:\nKingma and Dhariwal, 2018\n)\nThere are three substeps in one step of flow in Glow.\nSubstep 1:\nActivation normalization\n(short for “actnorm”)\nIt performs an affine transformation using a scale and bias parameter per channel, similar to batch normalization, but works for mini-batch size 1. The parameters are trainable but initialized so that the first minibatch of data have mean 0 and standard deviation 1 after actnorm.\nSubstep 2:\nInvertible 1x1 conv\nBetween layers of the RealNVP flow, the ordering of channels is reversed so that all the data dimensions have a chance to be altered. A 1×1 convolution with equal number of input and output channels is\na generalization of any permutation\nof the channel ordering.\nSay, we have an invertible 1x1 convolution of an input $h \\times w \\times c$ tensor $\\mathbf{h}$ with a weight matrix $\\mathbf{W}$ of size $c \\times c$. The output is a $h \\times w \\times c$ tensor, labeled as $f = \\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})$. In order to apply the change of variable rule, we need to compute the Jacobian determinant $\\vert \\det\\partial f / \\partial\\mathbf{h}\\vert$.\nBoth the input and output of 1x1 convolution here can be viewed as a matrix of size $h \\times w$. Each entry $\\mathbf{x}_{ij}$ ($i=1,\\dots,h, j=1,\\dots,w$) in $\\mathbf{h}$ is a vector of $c$ channels and each entry is multiplied by the weight matrix $\\mathbf{W}$ to obtain the corresponding entry $\\mathbf{y}_{ij}$ in the output matrix respectively. The derivative of each entry is $\\partial \\mathbf{x}_{ij} \\mathbf{W} / \\partial\\mathbf{x}_{ij} = \\mathbf{W}$ and there are $h \\times w$ such entries in total:\n$$\n\\log \\left\\vert\\det \\frac{\\partial\\texttt{conv2d}(\\mathbf{h}; \\mathbf{W})}{\\partial\\mathbf{h}}\\right\\vert\n= \\log (\\vert\\det\\mathbf{W}\\vert^{h \\cdot w}\\vert) = h \\cdot w \\cdot \\log \\vert\\det\\mathbf{W}\\vert\n$$\nThe inverse 1x1 convolution depends on the inverse matrix $\\mathbf{W}^{-1}$. Since the weight matrix is relatively small, the amount of computation for the matrix determinant (\ntf.linalg.det\n) and inversion (\ntf.linalg.inv\n) is still under control.\nSubstep 3:\nAffine coupling layer\nThe design is same as in RealNVP.\nThree substeps in one step of flow in Glow. (Image source:\nKingma and Dhariwal, 2018\n)\nModels with Autoregressive Flows\n#\nThe\nautoregressive\nconstraint is a way to model sequential data, $\\mathbf{x} = [x_1, \\dots, x_D]$: each output only depends on the data observed in the past, but not on the future ones. In other words, the probability of observing $x_i$ is conditioned on $x_1, \\dots, x_{i-1}$ and the product of these conditional probabilities gives us the probability of observing the full sequence:\n$$\np(\\mathbf{x}) = \\prod_{i=1}^{D} p(x_i\\vert x_1, \\dots, x_{i-1}) = \\prod_{i=1}^{D} p(x_i\\vert x_{1:i-1})\n$$\nHow to model the conditional density is of your choice. It can be a univariate Gaussian with mean and standard deviation computed as a function of $x_{1:i-1}$, or a multilayer neural network with $x_{1:i-1}$ as the input.\nIf a flow transformation in a normalizing flow is framed as an autoregressive model — each dimension in a vector variable is conditioned on the previous dimensions — this is an\nautoregressive flow\n.\nThis section starts with several classic autoregressive models (MADE, PixelRNN, WaveNet) and then we dive into autoregressive flow models (MAF and IAF).\nMADE\n#\nMADE\n(Masked Autoencoder for Distribution Estimation;\nGermain et al., 2015\n) is a specially designed architecture to enforce the autoregressive property in the autoencoder\nefficiently\n. When using an autoencoder to predict the conditional probabilities, rather than feeding the autoencoder with input of different observation windows $D$ times, MADE removes the contribution from certain hidden units by multiplying binary mask matrices so that each input dimension is reconstructed only from previous dimensions in a\ngiven\nordering in a\nsingle pass\n.\nIn a multilayer fully-connected neural network, say, we have $L$ hidden layers with weight matrices $\\mathbf{W}^1, \\dots, \\mathbf{W}^L$ and an output layer with weight matrix $\\mathbf{V}$. The output $\\hat{\\mathbf{x}}$ has each dimension $\\hat{x}_i = p(x_i\\vert x_{1:i-1})$.\nWithout any mask, the computation through layers looks like the following:\n$$\n\\begin{aligned}\n\\mathbf{h}^0 &= \\mathbf{x} \\\\\n\\mathbf{h}^l &= \\text{activation}^l(\\mathbf{W}^l\\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma(\\mathbf{V}\\mathbf{h}^L + \\mathbf{c})\n\\end{aligned}\n$$\nDemonstration of how MADE works in a three-layer feed-forward neural network. (Image source:\nGermain et al., 2015\n)\nTo zero out some connections between layers, we can simply element-wise multiply every weight matrix by a binary mask matrix. Each hidden node is assigned with a random “connectivity integer” between $1$ and $D-1$; the assigned value for the $k$-th unit in the $l$-th layer is denoted by $m^l_k$. The binary mask matrix is determined by element-wise comparing values of two nodes in two layers.\n$$\n\\begin{aligned}\n\\mathbf{h}^l &= \\text{activation}^l((\\mathbf{W}^l \\color{red}{\\odot \\mathbf{M}^{\\mathbf{W}^l}}) \\mathbf{h}^{l-1} + \\mathbf{b}^l) \\\\\n\\hat{\\mathbf{x}} &= \\sigma((\\mathbf{V} \\color{red}{\\odot \\mathbf{M}^{\\mathbf{V}}}) \\mathbf{h}^L + \\mathbf{c}) \\\\\nM^{\\mathbf{W}^l}_{k', k} \n&= \\mathbf{1}_{m^l_{k'} \\geq m^{l-1}_k} \n= \\begin{cases}\n    1, & \\text{if } m^l_{k'} \\geq m^{l-1}_k\\\\\n    0, & \\text{otherwise}\n\\end{cases} \\\\\nM^{\\mathbf{V}}_{d, k} \n&= \\mathbf{1}_{d \\geq m^L_k} \n= \\begin{cases}\n    1, & \\text{if } d > m^L_k\\\\\n    0, & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nA unit in the current layer can only be connected to other units with equal or smaller numbers in the previous layer and this type of dependency easily propagates through the network up to the output layer. Once the numbers are assigned to all the units and layers, the ordering of input dimensions is fixed and the conditional probability is produced with respect to it.  See a great illustration in To make sure all the hidden units are connected to the input and output layers through some paths, the $m^l_k$ is sampled to be equal or greater than the minimal connectivity integer in the previous layer, $\\min_{k’} m_{k’}^{l-1}$.\nMADE training can be further facilitated by:\nOrder-agnostic training\n: shuffle the input dimensions, so that MADE is able to model any arbitrary ordering; can create an ensemble of autoregressive models at the runtime.\nConnectivity-agnostic training\n: to avoid a model being tied up to a specific connectivity pattern constraints, resample $m^l_k$ for each training minibatch.\nPixelRNN\n#\nPixelRNN (\nOord et al, 2016\n) is a deep generative model for images. The image is generated one pixel at a time and each new pixel is sampled conditional on the pixels that have been seen before.\nLet’s consider an image of size $n \\times n$, $\\mathbf{x} = \\{x_1, \\dots, x_{n^2}\\}$, the model starts generating pixels from the top left corner, from left to right and top to bottom (See Fig. 6).\nThe context for generating one pixel in PixelRNN. (Image source:\nOord et al, 2016\n)\nEvery pixel $x_i$ is sampled from a probability distribution conditional over the the past context: pixels above it or on the left of it when in the same row. The definition of such context looks pretty arbitrary, because how visual\nattention\nis attended to an image is more flexible. Somehow magically a generative model with such a strong assumption works.\nOne implementation that could capture the entire context is the\nDiagonal BiLSTM\n. First, apply the\nskewing\noperation by offsetting each row of the input feature map by one position with respect to the previous row, so that computation for each row can be parallelized. Then the LSTM states are computed with respect to the current pixel and the pixels on the left.\n(a) PixelRNN with diagonal BiLSTM. (b) Skewing operation that offsets each row in the feature map by one with regards to the row above. (Image source:\nOord et al, 2016\n)\n$$\n\\begin{aligned}\n\\lbrack \\mathbf{o}_i, \\mathbf{f}_i, \\mathbf{i}_i, \\mathbf{g}_i \\rbrack &= \\sigma(\\mathbf{K}^{ss} \\circledast \\mathbf{h}_{i-1} + \\mathbf{K}^{is} \\circledast \\mathbf{x}_i) & \\scriptstyle{\\text{; }\\sigma\\scriptstyle{\\text{ is tanh for g, but otherwise sigmoid; }}\\circledast\\scriptstyle{\\text{ is convolution operation.}}} \\\\\n\\mathbf{c}_i &= \\mathbf{f}_i \\odot \\mathbf{c}_{i-1} + \\mathbf{i}_i \\odot \\mathbf{g}_i & \\scriptstyle{\\text{; }}\\odot\\scriptstyle{\\text{ is elementwise product.}}\\\\\n\\mathbf{h}_i &= \\mathbf{o}_i \\odot \\tanh(\\mathbf{c}_i)\n\\end{aligned}\n$$\nwhere $\\circledast$ denotes the convolution operation and $\\odot$ is the element-wise multiplication. The input-to-state component $\\mathbf{K}^{is}$ is a 1x1 convolution, while the state-to-state recurrent component is computed with a column-wise convolution $\\mathbf{K}^{ss}$ with a kernel of size 2x1.\nThe diagonal BiLSTM layers are capable of processing an unbounded context field, but expensive to compute due to the sequential dependency between states. A faster implementation uses multiple convolutional layers without pooling to define a bounded context box. The convolution kernel is masked so that the future context is not seen, similar to\nMADE\n. This convolution version is called\nPixelCNN\n.\nPixelCNN with masked convolution constructed by an elementwise product of a mask tensor and the convolution kernel before applying it. (Image source: http://slazebni.cs.illinois.edu/spring17/lec13_advanced.pdf)\nWaveNet\n#\nWaveNet\n(\nVan Den Oord, et al. 2016\n) is very similar to PixelCNN but applied to 1-D audio signals. WaveNet consists of a stack of\ncausal convolution\nwhich is a convolution operation designed to respect the ordering: the prediction at a certain timestamp can only consume the data observed in the past, no dependency on the future. In PixelCNN, the causal convolution is implemented by masked convolution kernel. The causal convolution in WaveNet is simply to shift the output by a number of timestamps to the future so that the output is aligned with the last input element.\nOne big drawback of convolution layer is a very limited size of receptive field. The output can hardly depend on the input hundreds or thousands of timesteps ago, which can be a crucial requirement for modeling long sequences. WaveNet therefore adopts\ndilated convolution\n(\nanimation\n), where the kernel is applied to an evenly-distributed subset of samples in a much larger receptive field of the input.\nVisualization of WaveNet models with a stack of (top) causal convolution layers and (bottom) dilated convolution layers. (Image source:\nVan Den Oord, et al. 2016\n)\nWaveNet uses the gated activation unit as the non-linear layer, as it is found to work significantly better than ReLU for modeling 1-D audio data. The residual connection is applied after the gated activation.\n$$\n\\mathbf{z} = \\tanh(\\mathbf{W}_{f,k}\\circledast\\mathbf{x})\\odot\\sigma(\\mathbf{W}_{g,k}\\circledast\\mathbf{x})\n$$\nwhere $\\mathbf{W}_{f,k}$ and $\\mathbf{W}_{g,k}$ are convolution filter and gate weight matrix of the $k$-th layer, respectively; both are learnable.\nMasked Autoregressive Flow\n#\nMasked Autoregressive Flow\n(\nMAF\n;\nPapamakarios et al., 2017\n) is a type of normalizing flows, where the transformation layer is built as an autoregressive neural network. MAF is very similar to\nInverse Autoregressive Flow\n(IAF) introduced later. See more discussion on the relationship between MAF and IAF in the next section.\nGiven two random variables, $\\mathbf{z} \\sim \\pi(\\mathbf{z})$ and $\\mathbf{x} \\sim p(\\mathbf{x})$ and the probability density function $\\pi(\\mathbf{z})$ is known, MAF aims to learn $p(\\mathbf{x})$. MAF generates each $x_i$ conditioned on the past dimensions $\\mathbf{x}_{1:i-1}$.\nPrecisely the conditional probability is an affine transformation of $\\mathbf{z}$, where the scale and shift terms are functions of the observed part of $\\mathbf{x}$.\nData generation, producing a new $\\mathbf{x}$:\n$x_i \\sim p(x_i\\vert\\mathbf{x}_{1:i-1}) = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})\\text{, where }\\mathbf{z} \\sim \\pi(\\mathbf{z})$\nDensity estimation, given a known $\\mathbf{x}$:\n$p(\\mathbf{x}) = \\prod_{i=1}^D p(x_i\\vert\\mathbf{x}_{1:i-1})$\nThe generation procedure is sequential, so it is slow by design. While density estimation only needs one pass the network using architecture like\nMADE\n. The transformation function is trivial to inverse and the Jacobian determinant is easy to compute too.\nInverse Autoregressive Flow\n#\nSimilar to MAF,\nInverse autoregressive flow\n(\nIAF\n;\nKingma et al., 2016\n) models the conditional probability of the target variable as an autoregressive model too, but with a reversed flow, thus achieving a much efficient sampling process.\nFirst, let’s reverse the affine transformation in MAF:\n$$\nz_i = \\frac{x_i - \\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} + x_i \\odot \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n$$\nIf let:\n$$\n\\begin{aligned}\n& \\tilde{\\mathbf{x}} = \\mathbf{z}\\text{, }\\tilde{p}(.) = \\pi(.)\\text{, }\\tilde{\\mathbf{x}} \\sim \\tilde{p}(\\tilde{\\mathbf{x}}) \\\\\n& \\tilde{\\mathbf{z}} = \\mathbf{x} \\text{, }\\tilde{\\pi}(.) = p(.)\\text{, }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\\\\\n& \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\mu}_i(\\mathbf{x}_{1:i-1}) = -\\frac{\\mu_i(\\mathbf{x}_{1:i-1})}{\\sigma_i(\\mathbf{x}_{1:i-1})} \\\\\n& \\tilde{\\sigma}(\\tilde{\\mathbf{z}}_{1:i-1}) = \\tilde{\\sigma}(\\mathbf{x}_{1:i-1}) = \\frac{1}{\\sigma_i(\\mathbf{x}_{1:i-1})}\n\\end{aligned}\n$$\nThen we would have,\n$$\n\\tilde{x}_i \\sim p(\\tilde{x}_i\\vert\\tilde{\\mathbf{z}}_{1:i}) = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})\n\\text{, where }\\tilde{\\mathbf{z}} \\sim \\tilde{\\pi}(\\tilde{\\mathbf{z}})\n$$\nIAF intends to estimate the probability density function of $\\tilde{\\mathbf{x}}$ given that $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$ is already known. The inverse flow is an autoregressive affine transformation too, same as in MAF, but the scale and shift terms are autoregressive functions of observed variables from the known distribution $\\tilde{\\pi}(\\tilde{\\mathbf{z}})$. See the comparison between MAF and IAF in\nComparison of MAF and IAF.  The variable with known density is in green while the unknown one is in red.\nComputations of the individual elements $\\tilde{x}_i$ do not depend on each other, so they are easily parallelizable (only one pass using MADE). The density estimation for a known $\\tilde{\\mathbf{x}}$ is not efficient, because we have to recover the value of $\\tilde{z}_i$ in a sequential order, $\\tilde{z}_i = (\\tilde{x}_i - \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})) / \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1})$, thus D times in total.\nBase distribution\nTarget distribution\nModel\nData generation\nDensity estimation\nMAF\n$\\mathbf{z}\\sim\\pi(\\mathbf{z})$\n$\\mathbf{x}\\sim p(\\mathbf{x})$\n$x_i = z_i \\odot \\sigma_i(\\mathbf{x}_{1:i-1}) + \\mu_i(\\mathbf{x}_{1:i-1})$\nSequential; slow\nOne pass; fast\nIAF\n$\\tilde{\\mathbf{z}}\\sim\\tilde{\\pi}(\\tilde{\\mathbf{z}})$\n$\\tilde{\\mathbf{x}}\\sim\\tilde{p}(\\tilde{\\mathbf{x}})$\n$\\tilde{x}_i  = \\tilde{z}_i \\odot \\tilde{\\sigma}_i(\\tilde{\\mathbf{z}}_{1:i-1}) + \\tilde{\\mu}_i(\\tilde{\\mathbf{z}}_{1:i-1})$\nOne pass; fast\nSequential; slow\n———-\n———-\n———-\n———-\n———-\n———-\nVAE + Flows\n#\nIn\nVariational Autoencoder\n, if we want to model the posterior $p(\\mathbf{z}\\vert\\mathbf{x})$ as a more complicated distribution rather than simple Gaussian. Intuitively we can use normalizing flow to transform the base Gaussian for better density approximation. The encoder then would predict a set of scale and shift terms $(\\mu_i, \\sigma_i)$ which are all functions of input $\\mathbf{x}$. Read the\npaper\nfor more details if interested.\nIf you notice mistakes and errors in this post, don’t hesitate to contact me at [lilian dot wengweng at gmail dot com] and I would be very happy to correct them right away!\nSee you in the next post :D\nCited as:\n@article{weng2018flow,\n  title   = \"Flow-based Deep Generative Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-10-13-flow-models/\"\n}\nReference\n#\n[1] Danilo Jimenez Rezende, and Shakir Mohamed.\n“Variational inference with normalizing flows.”\nICML 2015.\n[2]\nNormalizing Flows Tutorial, Part 1: Distributions and Determinants\nby Eric Jang.\n[3]\nNormalizing Flows Tutorial, Part 2: Modern Normalizing Flows\nby Eric Jang.\n[4]\nNormalizing Flows\nby Adam Kosiorek.\n[5] Laurent Dinh, Jascha Sohl-Dickstein, and Samy Bengio.\n“Density estimation using Real NVP.”\nICLR 2017.\n[6] Laurent Dinh, David Krueger, and Yoshua Bengio.\n“NICE: Non-linear independent components estimation.”\nICLR 2015 Workshop track.\n[7] Diederik P. Kingma, and Prafulla Dhariwal.\n“Glow: Generative flow with invertible 1x1 convolutions.”\narXiv:1807.03039 (2018).\n[8] Germain, Mathieu, Karol Gregor, Iain Murray, and Hugo Larochelle.\n“Made: Masked autoencoder for distribution estimation.”\nICML 2015.\n[9] Aaron van den Oord, Nal Kalchbrenner, and Koray Kavukcuoglu.\n“Pixel recurrent neural networks.”\nICML 2016.\n[10] Diederik P. Kingma, et al.\n“Improved variational inference with inverse autoregressive flow.”\nNIPS. 2016.\n[11] George Papamakarios, Iain Murray, and Theo Pavlakou.\n“Masked autoregressive flow for density estimation.”\nNIPS 2017.\n[12] Jianlin Su, and Guang Wu.\n“f-VAEs: Improve VAEs with Conditional Flows.”\narXiv:1809.05861 (2018).\n[13] Van Den Oord, Aaron, et al.\n“WaveNet: A generative model for raw audio.”\nSSW. 2016.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:34Z",
            "title": "Flow-based Deep Generative Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/95e296d541c5/code/body-000.txt",
                "chars": 231,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1505.05770",
                "bytes": 2901553,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c19a421df88d3d936d27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1605.08803",
                "bytes": 6681321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d6519de2f9580e55b379.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.8516",
                "bytes": 1717618,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d7013f82bf2a7683aad3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03039",
                "bytes": 13250301,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/60e8d214f8d5c367d55c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03509",
                "bytes": 489445,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5ef7ea5346faa12be094.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06759",
                "bytes": 3015028,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1d8f65c736afa61a5395.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1609.03499",
                "bytes": 2853802,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/12ed4e68449a6f887358.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.07057",
                "bytes": 1200941,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/298c9ccb8266e330a2f8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04934",
                "bytes": 1454651,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7688fe8fd3ce3cbcf849.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1809.05861",
                "bytes": 9321181,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/8971f265a9c20bb39bab.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 31712,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/95e296d541c5/pages/source.html",
            "local_html": "attachments/95e296d541c5/pages/article.html",
            "body_base_path": "attachments/95e296d541c5/pages/",
            "body_markdown_path": "attachments/95e296d541c5/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-08-12-vae/",
                "label": "VAE",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1505.05770",
                "label": "normalizing flows",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimax",
                "label": "minimax",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parity_of_a_permutation",
                "label": "signature",
                "type": "a"
              },
              {
                "href": "https://proofwiki.org/wiki/Determinant_of_Matrix_Product",
                "label": "proof",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1605.08803",
                "label": "Dinh et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.8516",
                "label": "Dinh, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03039",
                "label": "Kingma and Dhariwal, 2018",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/det",
                "label": "tf.linalg.det",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/linalg/inv",
                "label": "tf.linalg.inv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03509",
                "label": "Germain et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1601.06759",
                "label": "Oord et al, 2016",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "attention",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1609.03499",
                "label": "Van Den Oord, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://github.com/vdumoulin/conv_arithmetic",
                "label": "animation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.07057",
                "label": "Papamakarios et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04934",
                "label": "Kingma et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1809.05861",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf1.html",
                "label": "Normalizing Flows Tutorial, Part 1: Distributions and Determinants",
                "type": "a"
              },
              {
                "href": "https://blog.evjang.com/2018/01/nf2.html",
                "label": "Normalizing Flows Tutorial, Part 2: Modern Normalizing Flows",
                "type": "a"
              },
              {
                "href": "http://akosiorek.github.io/ml/2018/04/03/norm_flows.html",
                "label": "Normalizing Flows",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
          "status": "partial",
          "article_id": "54a9d3380f68",
          "local_path": "series-follow/1601/repair/fd35ae042f354cb3c47d.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
              "bytes": 21634,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0af902d15df97a679d1d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
              "bytes": 54826,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1601/repair/assets/b14e80a69c065fcf923f.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
              "bytes": 89960,
              "reused": false,
              "content_type": "image/gif",
              "local_path": "series-follow/1601/repair/assets/2ff11bc219d2fddbb103.gif"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
              "bytes": 1470472,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/299fa3d9ecac66743b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
              "bytes": 497605,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/35effb374a6c3725fe88.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
              "bytes": 788370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c0e1f225ec0f222e8138.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
              "bytes": 645042,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c3675d62fb7c6784228f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
              "bytes": 31968,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/069c442cc0ce9957e75d.png"
            }
          ],
          "article": {
            "id": "54a9d3380f68",
            "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "bytes": 21634,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-0af902d15df97a679d1d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/convolution-operation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "bytes": 54826,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-b14e80a69c065fcf923f.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_no_padding_no_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "bytes": 89960,
                "reused": false,
                "content_type": "image/gif",
                "local_path": "attachments/54a9d3380f68/images/body-2ff11bc219d2fddbb103.gif",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/numerical_padding_strides.gif",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "bytes": 1470472,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-299fa3d9ecac66743b06.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/alex_net_illustration.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "bytes": 497605,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-35effb374a6c3725fe88.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/residual-block.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "bytes": 788370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c0e1f225ec0f222e8138.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "bytes": 645042,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-c3675d62fb7c6784228f.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/DPM-matching.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "bytes": 31968,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/54a9d3380f68/images/body-069c442cc0ce9957e75d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/overfeat-training.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "Part 1\nof the “Object Detection for Dummies” series introduced: (1) the concept of image gradient vector and how HOG algorithm summarizes the information across all the gradient vectors in one image; (2) how the image segmentation algorithm works to detect regions that potentially contain objects; (3) how the Selective Search algorithm refines the outcomes of image segmentation for better region proposal.\nIn Part 2, we are about to find out more on the classic convolution neural network architectures for image classification. They lay the\nfoundation\nfor further progress on the deep learning models for object detection. Go check\nPart 3\nif you want to learn more on R-CNN and related models.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nCNN for Image Classification\n#\nCNN, short for “\nConvolutional Neural Network\n”, is the go-to solution for computer vision problems in the deep learning world. It was, to some extent,\ninspired\nby how human visual cortex system works.\nConvolution Operation\n#\nI strongly recommend this\nguide\nto convolution arithmetic, which provides a clean and solid explanation with tons of visualizations and examples. Here let’s focus on two-dimensional convolution as we are working with images in this post.\nIn short, convolution operation slides a predefined\nkernel\n(also called “filter”) on top of the input feature map (matrix of image pixels), multiplying and adding the values of the kernel and partial input features to generate the output. The values form an output matrix, as usually, the kernel is much smaller than the input image.\nAn illustration of applying a kernel on the input feature map to generate the output. (Image source:\nRiver Trail documentation\n)\nFigure 2 showcases two real examples of how to convolve a 3x3 kernel over a 5x5 2D matrix of numeric values to generate a 3x3 matrix. By controlling the padding size and the stride length, we can generate an output matrix of a certain size.\nTwo examples of 2D convolution operation: (top) no padding and 1x1 strides; (bottom) 1x1 border zeros padding and 2x2 strides. (Image source:\ndeeplearning.net\n)\nAlexNet (Krizhevsky et al, 2012)\n#\n5 convolution [+ optional max pooling] layers + 2 MLP layers + 1 LR layer\nUse data augmentation techniques to expand the training dataset, such as image translations, horizontal reflections, and patch extractions.\nThe architecture of AlexNet. (Image source:\nlink\n)\nVGG (Simonyan and Zisserman, 2014)\n#\nThe network is considered as “very deep” at its time; 19 layers\nThe architecture is extremely simplified with only 3x3 convolutional layers and 2x2 pooling layers. The stacking of small filters simulates a larger filter with fewer parameters.\nResNet (He et al., 2015)\n#\nThe network is indeed very deep; 152 layers of simple architecture.\nResidual Block\n: Some input of a certain layer can be passed to the component two layers later. Residual blocks are essential for keeping a deep network trainable and eventually work. Without residual blocks, the training loss of a plain network does not monotonically decrease as the number of layers increases due to\nvanishing and exploding gradients\n.\nAn illustration of the residual block of ResNet. In some way, we can say the design of residual blocks is inspired by V4 getting input directly from V1 in the human visual cortex system. (left image source:\nWang et al., 2017\n)\nEvaluation Metrics: mAP\n#\nA common evaluation metric used in many object recognition and detection tasks is “\nmAP\n”, short for “\nmean average precision\n”. It is a number from 0 to 100; higher value is better.\nCombine all detections from all test images to draw a precision-recall curve (PR curve) for each class; The “average precision” (AP) is the area under the PR curve.\nGiven that target objects are in different classes, we first compute AP separately for each class, and then average over classes.\nA detection is a true positive if it has\n“intersection over union” (IoU)\nwith a ground-truth box greater than some threshold (usually 0.5; if so, the metric is “\nmAP@0.5\n”)\nDeformable Parts Model\n#\nThe Deformable Parts Model (DPM) (\nFelzenszwalb et al., 2010\n) recognizes objects with a mixture graphical model (Markov random fields) of deformable parts. The model consists of three major components:\nA coarse\nroot filter\ndefines a detection window that approximately covers an entire object. A filter specifies weights for a region feature vector.\nMultiple\npart filters\nthat cover smaller parts of the object. Parts filters are learned at twice resolution of the root filter.\nA\nspatial model\nfor scoring the locations of part filters relative to the root.\nThe DPM model contains (a) a root filter, (b) multiple part filters at twice the resolution, and (c) a model for scoring the location and deformation of parts.\nThe quality of detecting an object is measured by the score of filters minus the deformation costs. The matching score $f$, in laymen’s terms, is:\n$$\nf(\\text{model}, x) = f(\\beta_\\text{root}, x) + \\sum_{\\beta_\\text{part} \\in \\text{part filters}} \\max_y [f(\\beta_\\text{part}, y) - \\text{cost}(\\beta_\\text{part}, x, y)]\n$$\nin which,\n$x$ is an image with a specified position and scale;\n$y$ is a sub region of $x$.\n$\\beta_\\text{root}$ is the root filter.\n$\\beta_\\text{part}$ is one part filter.\ncost() measures the penalty of the part deviating from its ideal location relative to the root.\nThe basic score model is the dot product between the filter $\\beta$ and the region feature vector $\\Phi(x)$: $f(\\beta, x) = \\beta \\cdot \\Phi(x)$. The feature set $\\Phi(x)$ can be defined by HOG or other similar algorithms.\nA root location with high score detects a region with high chances to contain an object, while the locations of the parts with high scores confirm a recognized object hypothesis. The paper adopted latent SVM to model the classifier.\nThe matching process by DPM. (Image source:\nFelzenszwalb et al., 2010\n)\nThe author later claimed that DPM and CNN models are not two distinct approaches to object recognition. Instead, a DPM model can be formulated as a CNN by unrolling the DPM inference algorithm and mapping each step to an equivalent CNN layer. (Check the details in\nGirshick et al., 2015\n!)\nOverfeat\n#\nOverfeat [\npaper\n][\ncode\n] is a pioneer model of integrating the object detection, localization and classification tasks all into one convolutional neural network. The main idea is to (i) do image classification at different locations on regions of multiple scales of the image in a sliding window fashion, and (ii) predict the bounding box locations with a regressor trained on top of the same convolution layers.\nThe Overfeat model architecture is very similar to\nAlexNet\n. It is trained as follows:\nThe training stages of the Overfeat model. (Image source:\nlink\n)\nTrain a CNN model (similar to AlexNet) on the image classification task.\nThen, we replace the top classifier layers by a regression network and train it to predict object bounding boxes at each spatial location and scale. The regressor is class-specific, each generated for one image class.\nInput: Images with classification and bounding box.\nOutput: $(x_\\text{left}, x_\\text{right}, y_\\text{top}, y_\\text{bottom})$, 4 values in total, representing the coordinates of the bounding box edges.\nLoss: The regressor is trained to minimize $l2$ norm between generated bounding box and the ground truth for each training example.\nAt the detection time,\nPerform classification at each location using the pretrained CNN model.\nPredict object bounding boxes on all classified regions generated by the classifier.\nMerge bounding boxes with sufficient overlap from localization and sufficient confidence of being the same object from the classifier.\nCited as:\n@article{weng2017detection2,\n  title   = \"Object Detection for Dummies Part 2: CNN, DPM and Overfeat\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/\"\n}\nReference\n#\n[1] Vincent Dumoulin and Francesco Visin.\n“A guide to convolution arithmetic for deep learning.”\narXiv preprint arXiv:1603.07285 (2016).\n[2] Haohan Wang, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800 (2017).\n[3] Pedro F. Felzenszwalb, Ross B. Girshick, David McAllester, and Deva Ramanan.\n“Object detection with discriminatively trained part-based models.”\nIEEE transactions on pattern analysis and machine intelligence 32, no. 9 (2010): 1627-1645.\n[4] Ross B. Girshick, Forrest Iandola, Trevor Darrell, and Jitendra Malik.\n“Deformable part models are convolutional neural networks.”\nIn Proc. IEEE Conf. on Computer Vision and Pattern Recognition (CVPR), pp. 437-446. 2015.\n[5] Sermanet, Pierre, David Eigen, Xiang Zhang, Michaël Mathieu, Rob Fergus, and Yann LeCun.\n“OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks”\narXiv preprint arXiv:1312.6229 (2013).",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:42Z",
            "title": "Object Detection for Dummies Part 2: CNN, DPM and Overfeat | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/54a9d3380f68/code/body-000.txt",
                "chars": 276,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1603.07285.pdf",
                "bytes": 913752,
                "reused": true,
                "local_path": "papers/repair/b61fe9cb2654d748de68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1312.6229.pdf",
                "bytes": 937841,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/540d3c26a6305febc0e1.pdf"
              },
              {
                "status": "http_403",
                "url": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "retried_at": "2026-10-20T17:45:41Z"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "bytes": 832728,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/1743cfdd1a25ffae4bbb.pdf"
              },
              {
                "status": "http_202",
                "url": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "retried_at": "2026-10-20T17:45:42Z"
              },
              {
                "status": "ok",
                "url": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "bytes": 6298687,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/417cc548662a22985f80.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 8988,
            "expected_body_images": 8,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_202；http_403",
            "raw_html": "attachments/54a9d3380f68/pages/source.html",
            "local_html": "attachments/54a9d3380f68/pages/article.html",
            "body_base_path": "attachments/54a9d3380f68/pages/",
            "body_markdown_path": "attachments/54a9d3380f68/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/",
                "label": "inspired",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1603.07285.pdf",
                "label": "guide",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "kernel",
                "type": "a"
              },
              {
                "href": "http://intellabs.github.io/RiverTrail/tutorial/",
                "label": "River Trail documentation",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html",
                "label": "deeplearning.net",
                "type": "a"
              },
              {
                "href": "http://vision03.csail.mit.edu/cnn_art/index.html",
                "label": "link",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2015/10/recurrent-neural-networks-tutorial-part-3-backpropagation-through-time-and-vanishing-gradients/",
                "label": "vanishing and exploding gradients",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1312.6229.pdf",
                "label": "Wang et al., 2017",
                "type": "a"
              },
              {
                "href": "http://people.cs.uchicago.edu/~pff/papers/lsvm-pami.pdf",
                "label": "Felzenszwalb et al., 2010",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Girshick_Deformable_Part_Models_2015_CVPR_paper.pdf",
                "label": "Girshick et al., 2015",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/f2c2/fbc35d0541571f54790851de9fcd1adde085.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/sermanet/OverFeat",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://vision.stanford.edu/teaching/cs231b_spring1415/slides/overfeat_eric.pdf",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
          "status": "ok",
          "article_id": "45444954e783",
          "local_path": "series-follow/1601/repair/0adb702ae2c07335adbf.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
              "bytes": 221077,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/aa28a4cc1b3516c1be46.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
              "bytes": 157401,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4199969ec35e7360ae98.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
              "bytes": 101972,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/95c24c614030b59aff01.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
              "bytes": 447186,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c2ebec0990753f6d5a87.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
              "bytes": 736874,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f32623608491cb056216.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
              "bytes": 529052,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/54028801a0ddfc354538.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
              "bytes": 86758,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/501aa5d6dea1582e9385.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
              "bytes": 32150,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7301ab34ef06aa0e487d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
              "bytes": 313647,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bacb4aa725276c994c68.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
              "bytes": 3106088,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f670e3a31b7940e1d8ef.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "From GAN to WGAN",
            "keywords": "GAN,WGAN,生成模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "publish_date": "2017-08",
            "corpus_stage": "预训练/SFT",
            "notes": "GAN到WGAN的演进综述",
            "id": "45444954e783",
            "collected_at": "2026-10-02T14:13:27",
            "title": "From GAN to WGAN | Lil'Log",
            "body_markdown": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in\nKorean\n!]\n[Updated on 2019-04-18: this post is also available on\narXiv\n.]\nGenerative adversarial network\n(GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.\nHere I would like to explain the maths behind the generative adversarial network framework,  why it is hard to be trained, and finally introduce a modified version of GAN intended to solve the training difficulties.\nKullback–Leibler and Jensen–Shannon Divergence\n#\nBefore we start examining GANs closely, let us first review two metrics for quantifying the similarity between two probability distributions.\n(1)\nKL (Kullback–Leibler) divergence\nmeasures how one probability distribution $p$ diverges from a second expected probability distribution $q$.\n$$\nD_{KL}(p \\| q) = \\int_x p(x) \\log \\frac{p(x)}{q(x)} dx\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nIt is noticeable according to the formula that KL divergence is asymmetric. In cases where $p(x)$ is close to zero, but $q(x)$ is significantly non-zero, the $q$’s effect is disregarded. It could cause buggy results when we just want to measure the similarity between two equally important distributions.\n(2)\nJensen–Shannon Divergence\nis another measure of similarity between two probability distributions, bounded by $[0, 1]$. JS divergence is symmetric (yay!) and more smooth. Check this\nQuora post\nif you are interested in reading more about the comparison between KL divergence and JS divergence.\n$$\nD_{JS}(p \\| q) = \\frac{1}{2} D_{KL}(p \\| \\frac{p + q}{2}) + \\frac{1}{2} D_{KL}(q \\| \\frac{p + q}{2})\n$$\nGiven two Gaussian distribution, $p$ with mean=0 and std=1 and $q$ with mean=1 and std=1. The average of two distributions is labelled as $m=(p+q)/2$. KL divergence $D_{KL}$ is asymmetric but JS divergence $D_{JS}$ is symmetric.\nSome believe (\nHuszar, 2015\n) that one reason behind GANs’ big success is switching the loss function from asymmetric KL divergence in traditional maximum-likelihood approach to symmetric JS divergence. We will discuss more on this point in the next section.\nGenerative Adversarial Network (GAN)\n#\nGAN consists of two models:\nA discriminator $D$ estimates the probability of a given sample coming from the real dataset. It works as a critic and is optimized to tell the fake samples from the real ones.\nA generator $G$ outputs synthetic samples given a noise variable input $z$ ($z$ brings in potential output diversity). It is trained to capture the real data distribution so that its generative samples can be as real as possible, or in other words, can trick the discriminator to offer a high probability.\nArchitecture of a generative adversarial network. (Image source:\nwww.kdnuggets.com/2017/01/generative-...-learning.html\n)\nThese two models compete against each other during the training process: the generator $G$ is trying hard to trick the discriminator, while the critic model $D$ is trying hard not to be cheated. This interesting zero-sum game between two models motivates both to improve their functionalities.\nGiven,\nSymbol\nMeaning\nNotes\n$p_{z}$\nData distribution over noise input $z$\nUsually, just uniform.\n$p_{g}$\nThe generator’s distribution over data $x$\n$p_{r}$\nData distribution over real sample $x$\nOn one hand, we want to make sure the discriminator $D$’s decisions over real data are accurate by maximizing $\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$. Meanwhile, given a fake sample $G(z), z \\sim p_z(z)$, the discriminator is expected to output a probability, $D(G(z))$, close to zero by maximizing $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nOn the other hand, the generator is trained to increase the chances of $D$ producing a high probability for a fake example, thus to minimize $\\mathbb{E}_{z \\sim p_{z}(z)} [\\log (1 - D(G(z)))]$.\nWhen combining both aspects together, $D$ and $G$ are playing a\nminimax game\nin which we should optimize the following loss function:\n$$\n\\begin{aligned}\n\\min_G \\max_D L(D, G) \n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{z \\sim p_z(z)} [\\log(1 - D(G(z)))] \\\\\n& = \\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)] + \\mathbb{E}_{x \\sim p_g(x)} [\\log(1 - D(x)]\n\\end{aligned}\n$$\n($\\mathbb{E}_{x \\sim p_{r}(x)} [\\log D(x)]$ has no impact on $G$ during gradient descent updates.)\nWhat is the optimal value for D?\n#\nNow we have a well-defined loss function. Let’s first examine what is the best value for $D$.\n$$\nL(G, D) = \\int_x \\bigg( p_{r}(x) \\log(D(x)) + p_g (x) \\log(1 - D(x)) \\bigg) dx\n$$\nSince we are interested in what is the best value of $D(x)$ to maximize $L(G, D)$, let us label\n$$\n\\tilde{x} = D(x), \nA=p_{r}(x), \nB=p_g(x)\n$$\nAnd then what is inside the integral (we can safely ignore the integral because $x$ is sampled over all the possible values) is:\n$$\n\\begin{aligned}\nf(\\tilde{x}) \n& = A log\\tilde{x} + B log(1-\\tilde{x}) \\\\\n\\frac{d f(\\tilde{x})}{d \\tilde{x}}\n& = A \\frac{1}{ln10} \\frac{1}{\\tilde{x}} - B \\frac{1}{ln10} \\frac{1}{1 - \\tilde{x}} \\\\\n& = \\frac{1}{ln10} (\\frac{A}{\\tilde{x}} - \\frac{B}{1-\\tilde{x}}) \\\\\n& = \\frac{1}{ln10} \\frac{A - (A + B)\\tilde{x}}{\\tilde{x} (1 - \\tilde{x})} \\\\\n\\end{aligned}\n$$\nThus, set $\\frac{d f(\\tilde{x})}{d \\tilde{x}} = 0$, we get the best value of the discriminator: $D^*(x) = \\tilde{x}^* = \\frac{A}{A + B} = \\frac{p_{r}(x)}{p_{r}(x) + p_g(x)} \\in [0, 1]$.\nOnce the generator is trained to its optimal, $p_g$ gets very close to $p_{r}$. When $p_g = p_{r}$, $D^*(x)$ becomes $1/2$.\nWhat is the global optimal?\n#\nWhen both $G$ and $D$ are at their optimal values, we have $p_g = p_{r}$ and $D^*(x) = 1/2$ and the loss function becomes:\n$$\n\\begin{aligned}\nL(G, D^*) \n&= \\int_x \\bigg( p_{r}(x) \\log(D^*(x)) + p_g (x) \\log(1 - D^*(x)) \\bigg) dx \\\\\n&= \\log \\frac{1}{2} \\int_x p_{r}(x) dx + \\log \\frac{1}{2} \\int_x p_g(x) dx \\\\\n&= -2\\log2\n\\end{aligned}\n$$\nWhat does the loss function represent?\n#\nAccording to the formula listed in the\nprevious section\n, JS divergence between $p_{r}$ and $p_g$ can be computed as:\n$$\n\\begin{aligned}\nD_{JS}(p_{r} \\| p_g) \n=& \\frac{1}{2} D_{KL}(p_{r} || \\frac{p_{r} + p_g}{2}) + \\frac{1}{2} D_{KL}(p_{g} || \\frac{p_{r} + p_g}{2}) \\\\\n=& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_{r}(x) \\log \\frac{p_{r}(x)}{p_{r} + p_g(x)} dx \\bigg) + \\\\& \\frac{1}{2} \\bigg( \\log2 + \\int_x p_g(x) \\log \\frac{p_g(x)}{p_{r} + p_g(x)} dx \\bigg) \\\\\n=& \\frac{1}{2} \\bigg( \\log4 + L(G, D^*) \\bigg)\n\\end{aligned}\n$$\nThus,\n$$\nL(G, D^*) = 2D_{JS}(p_{r} \\| p_g) - 2\\log2\n$$\nEssentially the loss function of GAN quantifies the similarity between the generative data distribution $p_g$ and the real sample distribution $p_{r}$ by JS divergence when the discriminator is optimal. The best $G^*$ that replicates the real data distribution leads to the minimum $L(G^*, D^*) = -2\\log2$ which is aligned with equations above.\nOther Variations of GAN\n: There are many variations of GANs in different contexts or designed for different tasks. For example, for semi-supervised learning, one idea is to update the discriminator to output real class labels, $1, \\dots, K-1$, as well as one fake class label $K$. The generator model aims to trick the discriminator to output a classification label smaller than $K$.\nTensorflow Implementation\n:\ncarpedm20/DCGAN-tensorflow\nProblems in GANs\n#\nAlthough GAN has shown great success in the realistic image generation, the training is not easy; The process is known to be slow and unstable.\nHard to achieve Nash equilibrium\n#\nSalimans et al. (2016)\ndiscussed the problem with GAN’s gradient-descent-based training procedure. Two models are trained simultaneously to find a\nNash equilibrium\nto a two-player non-cooperative game. However, each model updates its cost independently with no respect to another player in the game. Updating the gradient of both models concurrently cannot guarantee a convergence.\nLet’s check out a simple example to better understand why it is difficult to find a Nash equilibrium in an non-cooperative game. Suppose one player takes control of $x$ to minimize $f_1(x) = xy$, while at the same time the other player constantly updates $y$ to minimize $f_2(y) = -xy$.\nBecause $\\frac{\\partial f_1}{\\partial x} = y$ and $\\frac{\\partial f_2}{\\partial y} = -x$, we update $x$ with $x-\\eta \\cdot y$ and $y$ with $y+ \\eta \\cdot x$ simulitanously in one iteration, where $\\eta$ is the learning rate. Once $x$ and $y$ have different signs, every following gradient update causes huge oscillation and the instability gets worse in time, as shown in\nA simulation of our example for updating $x$ to minimize $xy$ and updating $y$ to minimize $-xy$. The learning rate $\\eta = 0.1$. With more iterations, the oscillation grows more and more unstable.\nLow dimensional supports\n#\nTerm\nExplanation\nManifold\nA topological space that locally resembles Euclidean space near each point. Precisely, when this Euclidean space is of\ndimension $n$\n, the manifold is referred as\n$n$-manifold\n.\nSupport\nA real-valued function $f$ is the subset of the domain containing those elements which are not mapped to\nzero\n.\nArjovsky and Bottou (2017)\ndiscussed the problem of the\nsupports\nof $p_r$ and $p_g$ lying on low dimensional\nmanifolds\nand how it contributes to the instability of GAN training thoroughly in a very theoretical paper\n“Towards principled methods for training generative adversarial networks”\n.\nThe dimensions of many real-world datasets, as represented by $p_r$, only appear to be\nartificially high\n. They have been found to concentrate in a lower dimensional manifold. This is actually the fundamental assumption for\nManifold Learning\n. Thinking of the real world images, once the theme or the contained object is fixed, the images have a lot of restrictions to follow, i.e., a dog should have two ears and a tail, and a skyscraper should have a straight and tall body, etc. These restrictions keep images aways from the possibility of having a high-dimensional free form.\n$p_g$ lies in a low dimensional manifolds, too. Whenever the generator is asked to a much larger image like 64x64 given a small dimension, such as 100, noise variable input $z$, the distribution of colors over these 4096 pixels has been defined by the small 100-dimension random number vector and can hardly fill up the whole high dimensional space.\nBecause both $p_g$ and $p_r$ rest in low dimensional manifolds, they are almost certainly gonna be disjoint (See Fig. 4). When they have disjoint supports, we are always capable of finding a perfect discriminator that separates real and fake samples 100% correctly. Check the\npaper\nif you are curious about the proof.\nLow dimensional manifolds in high dimension space can hardly have overlaps. (Left) Two lines in a three-dimension space. (Right) Two surfaces in a three-dimension space.\nVanishing gradient\n#\nWhen the discriminator is perfect, we are guaranteed with $D(x) = 1, \\forall x \\in p_r$ and $D(x) = 0, \\forall x \\in p_g$. Therefore the loss function $L$ falls to zero and we end up with no gradient to update the loss during learning iterations. Fig. 5 demonstrates an experiment when the discriminator gets better, the gradient vanishes fast.\nFirst, a DCGAN is trained for 1, 10 and 25 epochs. Then, with the **generator fixed**, a discriminator is trained from scratch and measure the gradients with the original cost function. We see the gradient norms **decay quickly** (in log scale), in the best case 5 orders of magnitude after 4000 discriminator iterations. (Image source:\nArjovsky and Bottou, 2017\n)\nAs a result, training a GAN faces a\ndilemma\n:\nIf the discriminator behaves badly, the generator does not have accurate feedback and the loss function cannot represent the reality.\nIf the discriminator does a great job, the gradient of the loss function drops down to close to zero and the learning becomes super slow or even jammed.\nThis dilemma clearly is capable to make the GAN training very tough.\nMode collapse\n#\nDuring the training, the generator may collapse to a setting where it always produces same outputs. This is a common failure case for GANs, commonly referred to as\nMode Collapse\n. Even though the generator might be able to trick the corresponding discriminator, it fails to learn to represent the complex real-world data distribution and gets stuck in a small space with extremely low variety.\nA DCGAN model is trained with an MLP network with 4 layers, 512 units and ReLU activation function, configured to lack a strong inductive bias for image generation. The results shows a significant degree of mode collapse. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nLack of a proper evaluation metric\n#\nGenerative adversarial networks are not born with a good objection function that can inform us the training progress. Without a good evaluation metric, it is like working in the dark. No good sign to tell when to stop; No good indicator to compare the performance of multiple models.\nImproved GAN Training\n#\nThe following suggestions are proposed to help stabilize and improve the training of GANs.\nFirst five methods are practical techniques to achieve faster convergence of GAN training, proposed in\n“Improve Techniques for Training GANs”\n.\nThe last two are proposed in\n“Towards principled methods for training generative adversarial networks”\nto solve the problem of disjoint distributions.\n(1)\nFeature Matching\nFeature matching suggests to optimize the discriminator to inspect whether the generator’s output matches expected statistics of the real samples. In such a scenario, the new loss function is defined as $| \\mathbb{E}_{x \\sim p_r} f(x) - \\mathbb{E}_{z \\sim p_z(z)}f(G(z)) |_2^2 $, where $f(x)$ can be any computation of statistics of features, such as mean or median.\n(2)\nMinibatch Discrimination\nWith minibatch discrimination, the discriminator is able to digest the relationship between training data points in one batch, instead of processing each point independently.\nIn one minibatch, we approximate the closeness between every pair of samples, $c(x_i, x_j)$, and get the overall summary of one data point by summing up how close it is to other samples in the same batch, $o(x_i) = \\sum_{j} c(x_i, x_j)$. Then $o(x_i)$ is explicitly added to the input of the model.\n(3)\nHistorical Averaging\nFor both models, add $ | \\Theta - \\frac{1}{t} \\sum_{i=1}^t \\Theta_i |^2 $ into the loss function, where $\\Theta$ is the model parameter and $\\Theta_i$ is how the parameter is configured at the past training time $i$. This addition piece penalizes the training speed when $\\Theta$ is changing too dramatically in time.\n(4)\nOne-sided Label Smoothing\nWhen feeding the discriminator, instead of providing 1 and 0 labels, use soften values such as 0.9 and 0.1. It is shown to reduce the networks’ vulnerability.\n(5)\nVirtual Batch Normalization\n(VBN)\nEach data sample is normalized based on a fixed batch (\n“reference batch”\n) of data rather than within its minibatch. The reference batch is chosen once at the beginning and stays the same through the training.\nTheano Implementation\n:\nopenai/improved-gan\n(6)\nAdding Noises\n.\nBased on the discussion in the\nprevious section\n, we now know $p_r$ and $p_g$ are disjoint in a high dimensional space and it causes the problem of vanishing gradient. To artificially “spread out” the distribution and to create higher chances for two probability distributions to have overlaps, one solution is to add continuous noises onto the inputs of the discriminator $D$.\n(7)\nUse Better Metric of Distribution Similarity\nThe loss function of the vanilla GAN measures the JS divergence between the distributions of $p_r$ and $p_g$. This metric fails to provide a meaningful value when two distributions are disjoint.\nWasserstein metric\nis proposed to replace JS divergence because it has a much smoother value space. See more in the next section.\nWasserstein GAN (WGAN)\n#\nWhat is Wasserstein distance?\n#\nWasserstein Distance\nis a measure of the distance between two probability distributions.\nIt is also called\nEarth Mover’s distance\n, short for EM distance, because informally it can be interpreted as the minimum energy cost of moving and transforming a pile of dirt in the shape of one probability distribution to the shape of the other distribution. The cost is quantified by: the amount of dirt moved x the moving distance.\nLet us first look at a simple case where the probability domain is\ndiscrete\n. For example, suppose we have two distributions $P$ and $Q$, each has four piles of dirt and both have ten shovelfuls of dirt in total. The numbers of shovelfuls in each dirt pile are assigned as follows:\n$$\n\\begin{aligned}\n& P_1 = 3, P_2 = 2, P_3 = 1, P_4 = 4\\\\\n& Q_1 = 1, Q_2 = 2, Q_3 = 4, Q_4 = 3\n\\end{aligned}\n$$\nIn order to change $P$ to look like $Q$, as illustrated in Fig. 7, we:\nFirst move 2 shovelfuls from $P_1$ to $P_2$ => $(P_1, Q_1)$ match up.\nThen move 2 shovelfuls from $P_2$ to $P_3$ => $(P_2, Q_2)$ match up.\nFinally move 1 shovelfuls from $Q_3$ to $Q_4$ => $(P_3, Q_3)$ and $(P_4, Q_4)$ match up.\nIf we label the cost to pay to make $P_i$ and $Q_i$ match as $\\delta_i$, we would have $\\delta_{i+1} = \\delta_i + P_i - Q_i$ and in the example:\n$$\n\\begin{aligned}\n\\delta_0 &= 0\\\\\n\\delta_1 &= 0 + 3 - 1 = 2\\\\\n\\delta_2 &= 2 + 2 - 2 = 2\\\\\n\\delta_3 &= 2 + 1 - 4 = -1\\\\\n\\delta_4 &= -1 + 4 - 3 = 0\n\\end{aligned}\n$$\nFinally the Earth Mover’s distance is $W = \\sum \\vert \\delta_i \\vert = 5$.\nStep-by-step plan of moving dirt between piles in $P$ and $Q$ to make them match.\nWhen dealing with the continuous probability domain, the distance formula becomes:\n$$\nW(p_r, p_g) = \\inf_{\\gamma \\sim \\Pi(p_r, p_g)} \\mathbb{E}_{(x, y) \\sim \\gamma}[\\| x-y \\|]\n$$\nIn the formula above, $\\Pi(p_r, p_g)$ is the set of all possible joint probability distributions between $p_r$ and $p_g$. One joint distribution $\\gamma \\in \\Pi(p_r, p_g)$ describes one dirt transport plan, same as the discrete example above, but in the continuous probability space. Precisely $\\gamma(x, y)$ states the percentage of dirt should be transported from point $x$ to $y$ so as to make $x$ follows the same probability distribution of $y$. That’s why the marginal distribution over $x$ adds up to $p_g$, $\\sum_{x} \\gamma(x, y) = p_g(y)$ (Once we finish moving the planned amount of dirt from every possible $x$ to the target $y$, we end up with exactly what $y$ has according to $p_g$.) and vice versa $\\sum_{y} \\gamma(x, y) = p_r(x)$.\nWhen treating $x$ as the starting point and $y$ as the destination, the total amount of dirt moved is $\\gamma(x, y)$ and the travelling distance is $| x-y |$ and thus the cost is $\\gamma(x, y) \\cdot | x-y |$. The expected cost averaged across all the $(x,y)$ pairs can be easily computed as:\n$$\n\\sum_{x, y} \\gamma(x, y) \\| x-y \\| \n= \\mathbb{E}_{x, y \\sim \\gamma} \\| x-y \\|\n$$\nFinally, we take the minimum one among the costs of all dirt moving solutions as the EM distance. In the definition of Wasserstein distance, the $\\inf$ (\ninfimum\n, also known as\ngreatest lower bound\n) indicates that we are only interested in the smallest cost.\nWhy Wasserstein is better than JS or KL divergence?\n#\nEven when two distributions are located in lower dimensional manifolds without overlaps, Wasserstein distance can still provide a meaningful and smooth representation of the distance in-between.\nThe WGAN paper exemplified the idea with a simple example.\nSuppose we have two probability distributions, $P$ and $Q$:\n$$\n\\forall (x, y) \\in P, x = 0 \\text{ and } y \\sim U(0, 1)\\\\\n\\forall (x, y) \\in Q, x = \\theta, 0 \\leq \\theta \\leq 1 \\text{ and } y \\sim U(0, 1)\\\\\n$$\nThere is no overlap between $P$ and $Q$ when $\\theta \\neq 0$.\nWhen $\\theta \\neq 0$:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{KL}(Q \\| P) &= \\sum_{x=\\theta, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{0} = +\\infty \\\\\nD_{JS}(P, Q) &= \\frac{1}{2}(\\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2} + \\sum_{x=0, y \\sim U(0, 1)} 1 \\cdot \\log\\frac{1}{1/2}) = \\log 2\\\\\nW(P, Q) &= |\\theta|\n\\end{aligned}\n$$\nBut when $\\theta = 0$, two distributions are fully overlapped:\n$$\n\\begin{aligned}\nD_{KL}(P \\| Q) &= D_{KL}(Q \\| P) = D_{JS}(P, Q) = 0\\\\\nW(P, Q) &= 0 = \\lvert \\theta \\rvert\n\\end{aligned}\n$$\n$D_{KL}$ gives us inifity when two distributions are disjoint. The value of $D_{JS}$ has sudden jump, not differentiable at $\\theta = 0$. Only Wasserstein metric provides a smooth measure, which is super helpful for a stable learning process using gradient descents.\nUse Wasserstein distance as GAN loss function\n#\nIt is intractable to exhaust all the possible joint distributions in $\\Pi(p_r, p_g)$ to compute $\\inf_{\\gamma \\sim \\Pi(p_r, p_g)}$. Thus the authors proposed a smart transformation of the formula based on the Kantorovich-Rubinstein duality to:\n$$\nW(p_r, p_g) = \\frac{1}{K} \\sup_{\\| f \\|_L \\leq K} \\mathbb{E}_{x \\sim p_r}[f(x)] - \\mathbb{E}_{x \\sim p_g}[f(x)]\n$$\nwhere $\\sup$ (\nsupremum\n) is the opposite of $inf$ (infimum); we want to measure the least upper bound or, in even simpler words, the maximum value.\nLipschitz continuity?\nThe function $f$ in the new form of Wasserstein metric is demanded to satisfy $| f |_L \\leq K$, meaning it should be\nK-Lipschitz continuous\n.\nA real-valued function $f: \\mathbb{R} \\rightarrow \\mathbb{R}$ is called $K$-Lipschitz continuous if there exists a real constant $K \\geq 0$ such that, for all $x_1, x_2 \\in \\mathbb{R}$,\n$$\n\\lvert f(x_1) - f(x_2) \\rvert \\leq K \\lvert x_1 - x_2 \\rvert\n$$\nHere $K$ is known as a Lipschitz constant for function $f(.)$. Functions that are everywhere continuously differentiable is Lipschitz continuous, because the derivative, estimated as $\\frac{\\lvert f(x_1) - f(x_2) \\rvert}{\\lvert x_1 - x_2 \\rvert}$, has bounds. However, a Lipschitz continuous function may not be everywhere differentiable, such as $f(x) = \\lvert x \\rvert$.\nExplaining how the transformation happens on the Wasserstein distance formula is worthy of a long post by itself, so I skip the details here. If you are interested in how to compute Wasserstein metric using linear programming, or how to transfer Wasserstein metric into its dual form according to the Kantorovich-Rubinstein Duality, read this\nawesome post\n.\nSuppose this function $f$ comes from a family of K-Lipschitz continuous functions, $\\{ f_w \\}_{w \\in W}$, parameterized by $w$. In the modified Wasserstein-GAN, the “discriminator” model is used to learn $w$ to find a good $f_w$ and the loss function is configured as measuring the Wasserstein distance between $p_r$ and $p_g$.\n$$\nL(p_r, p_g) = W(p_r, p_g) = \\max_{w \\in W} \\mathbb{E}_{x \\sim p_r}[f_w(x)] - \\mathbb{E}_{z \\sim p_r(z)}[f_w(g_\\theta(z))]\n$$\nThus the “discriminator” is not a direct critic of telling the fake samples apart from the real ones anymore. Instead, it is trained to learn a $K$-Lipschitz continuous function to help compute Wasserstein distance. As the loss function decreases in the training, the Wasserstein distance gets smaller and the generator model’s output grows closer to the real data distribution.\nOne big problem is to maintain the $K$-Lipschitz continuity of $f_w$ during the training in order to make everything work out. The paper presents a simple but very practical trick: After every gradient update, clamp the weights $w$ to a small window, such as $[-0.01, 0.01]$, resulting in a compact parameter space $W$ and thus $f_w$ obtains its lower and upper bounds to preserve the Lipschitz continuity.\nAlgorithm of Wasserstein generative adversarial network. (Image source:\nArjovsky, Chintala, & Bottou, 2017.\n)\nCompared to the original GAN algorithm, the WGAN undertakes the following changes:\nAfter every gradient update on the critic function, clamp the weights to a small fixed range, $[-c, c]$.\nUse a new loss function derived from the Wasserstein distance, no logarithm anymore. The “discriminator” model does not play as a direct critic but a helper for estimating the Wasserstein metric between real and generated data distribution.\nEmpirically the authors recommended\nRMSProp\noptimizer on the critic, rather than a momentum based optimizer such as\nAdam\nwhich could cause instability in the model training. I haven’t seen clear theoretical explanation on this point through.\nSadly, Wasserstein GAN is not perfect. Even the authors of the original WGAN paper mentioned that\n“Weight clipping is a clearly terrible way to enforce a Lipschitz constraint”\n(Oops!). WGAN still suffers from unstable training, slow convergence after weight clipping (when clipping window is too large), and vanishing gradients (when clipping window is too small).\nSome improvement, precisely replacing weight clipping with\ngradient penalty\n, has been discussed in\nGulrajani et al. 2017\n. I will leave this to a future post.\nExample: Create New Pokemons!\n#\nJust for fun, I tried out\ncarpedm20/DCGAN-tensorflow\non a tiny dataset,\nPokemon sprites\n. The dataset only has 900-ish pokemon images, including different levels of same pokemon species.\nLet’s check out what types of new pokemons the model is able to create.\nUnfortunately due to the tiny training data, the new pokemons only have rough shapes without details. The shapes and colors do look better with more training epoches! Hooray!\nTrain\ncarpedm20/DCGAN-tensorflow\non a set of Pokemon sprite images. The sample outputs are listed after training epoches = 7, 21, 49.\nIf you are interested in a commented version of\ncarpedm20/DCGAN-tensorflow\nand how to modify it to train WGAN and WGAN with gradient penalty, check\nlilianweng/unified-gan-tensorflow\n.\nCited as:\n@article{weng2017gan,\n  title   = \"From GAN to WGAN\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-08-20-gan/\"\n}\nOR\n@misc{weng2019gan,\n    title={From GAN to WGAN},\n    author={Lilian Weng},\n    year={2019},\n    eprint={1904.08994},\n    archivePrefix={arXiv},\n    primaryClass={cs.LG}\n}\nReferences\n#\n[1] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.\n[2] Tim Salimans, et al.\n“Improved techniques for training gans.”\nNIPS 2016.\n[3] Martin Arjovsky and Léon Bottou.\n“Towards principled methods for training generative adversarial networks.”\narXiv preprint arXiv:1701.04862 (2017).\n[4] Martin Arjovsky, Soumith Chintala, and Léon Bottou.\n“Wasserstein GAN.”\narXiv preprint arXiv:1701.07875 (2017).\n[5] Ishaan Gulrajani, Faruk Ahmed, Martin Arjovsky, Vincent Dumoulin, Aaron Courville.\nImproved training of wasserstein gans.\narXiv preprint arXiv:1704.00028 (2017).\n[6]\nComputing the Earth Mover’s Distance under Transformations\n[7]\nWasserstein GAN and the Kantorovich-Rubinstein Duality\n[8]\nzhuanlan.zhihu.com/p/25071913\n[9] Ferenc Huszár.\n“How (not) to Train your Generative Model: Scheduled Sampling, Likelihood, Adversary?.”\narXiv preprint arXiv:1511.05101 (2015).",
            "metadata": {
              "title": "From GAN to WGAN | Lil'Log",
              "description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "keywords": "gan, long-read, generative-model, image-generation, math-heavy",
              "author": "Lilian Weng",
              "og:title": "From GAN to WGAN",
              "og:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
              "twitter:card": "summary",
              "twitter:title": "From GAN to WGAN",
              "twitter:description": "[Updated on 2018-09-30: thanks to Yoonju, we have this post translated in Korean!]\n\n[Updated on 2019-04-18: this post is also available on arXiv.]\nGenerative adversarial network (GAN) has shown great results in many generative tasks to replicate the real-world rich content such as images, human language, and music. It is inspired by game theory: two models, a generator and a critic, are competing with each other while making each other stronger at the same time. However, it is rather challenging to train a GAN model, as people are facing issues like training instability or failure to converge.",
              "article:section": "posts",
              "article:published_time": "2017-08-20T00:00:00+00:00",
              "article:modified_time": "2017-08-20T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/45444954e783/code/body-000.txt",
                "chars": 205,
                "language": "text"
              },
              {
                "file": "attachments/45444954e783/code/body-001.txt",
                "chars": 171,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "bytes": 221077,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-aa28a4cc1b3516c1be46.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/KL_JS_divergence.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "bytes": 157401,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-4199969ec35e7360ae98.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "bytes": 101972,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-95c24c614030b59aff01.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/nash_equilibrium.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "bytes": 447186,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-c2ebec0990753f6d5a87.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/low_dim_manifold.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "bytes": 736874,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f32623608491cb056216.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/GAN_vanishing_gradient.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "bytes": 529052,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-54028801a0ddfc354538.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/mode_collapse.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "bytes": 86758,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-501aa5d6dea1582e9385.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/EM_distance_discrete.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "bytes": 32150,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-7301ab34ef06aa0e487d.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/wasserstein_simple_example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "bytes": 313647,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-bacb4aa725276c994c68.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/WGAN_algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "bytes": 3106088,
                "reused": false,
                "local_path": "attachments/45444954e783/images/body-f670e3a31b7940e1d8ef.png",
                "src": "https://lilianweng.github.io/posts/2017-08-20-gan/pokemon-GAN.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/yjucho1/articles/blob/master/fromGANtoWGAN/readme.md",
                "label": "Korean",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.08994",
                "label": "arXiv",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "KL (Kullback–Leibler) divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence",
                "label": "Jensen–Shannon Divergence",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/Why-isnt-the-Jensen-Shannon-divergence-used-more-often-than-the-Kullback-Leibler-since-JS-is-symmetric-thus-possibly-a-better-indicator-of-distance",
                "label": "Quora post",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1511.05101.pdf",
                "label": "Huszar, 2015",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "www.kdnuggets.com/2017/01/generative-...-learning.html",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "previous section",
                "type": "a"
              },
              {
                "href": "https://github.com/carpedm20/DCGAN-tensorflow",
                "label": "carpedm20/DCGAN-tensorflow",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "label": "Salimans et al. (2016)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Nash_equilibrium",
                "label": "Nash equilibrium",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Manifold",
                "label": "Manifold",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Support_(mathematics)",
                "label": "Support",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.04862.pdf",
                "label": "Arjovsky and Bottou (2017)",
                "type": "a"
              },
              {
                "href": "http://scikit-learn.org/stable/modules/manifold.html",
                "label": "Manifold Learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1701.07875.pdf",
                "label": "Arjovsky, Chintala, & Bottou, 2017.",
                "type": "a"
              },
              {
                "href": "https://github.com/openai/improved-gan",
                "label": "openai/improved-gan",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Wasserstein_metric",
                "label": "Wasserstein metric",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Infimum_and_supremum",
                "label": "infimum",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lipschitz_continuity",
                "label": "K-Lipschitz continuous",
                "type": "a"
              },
              {
                "href": "https://vincentherrmann.github.io/blog/wasserstein/",
                "label": "awesome post",
                "type": "a"
              },
              {
                "href": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "label": "RMSProp",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.6980v8",
                "label": "Adam",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1704.00028.pdf",
                "label": "Gulrajani et al. 2017",
                "type": "a"
              },
              {
                "href": "https://github.com/PokeAPI/sprites/",
                "label": "Pokemon sprites",
                "type": "a"
              },
              {
                "href": "https://github.com/lilianweng/unified-gan-tensorflow",
                "label": "lilianweng/unified-gan-tensorflow",
                "type": "a"
              },
              {
                "href": "http://robotics.stanford.edu/~scohen/research/emdg/emdg.html",
                "label": "Computing the Earth Mover’s Distance under Transformations",
                "type": "a"
              },
              {
                "href": "https://zhuanlan.zhihu.com/p/25071913",
                "label": "zhuanlan.zhihu.com/p/25071913",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:34Z",
            "source_url": "https://lilianweng.github.io/posts/2017-08-20-gan/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.08994",
                "bytes": 2372969,
                "reused": false,
                "local_path": "papers/repair/a08caad93b55901c5b6f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": false,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.05101.pdf",
                "bytes": 505788,
                "reused": false,
                "local_path": "papers/repair/057d39e637c6097bcd7a.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/6125-improved-techniques-for-training-gans.pdf",
                "bytes": 2639054,
                "reused": false,
                "local_path": "papers/repair/762153e376c22f644d34.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.04862.pdf",
                "bytes": 566179,
                "reused": false,
                "local_path": "papers/repair/e9832d130ee863bb324f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.07875.pdf",
                "bytes": 8834587,
                "reused": false,
                "local_path": "papers/repair/941e1ba609c7c19a8af8.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf",
                "bytes": 546843,
                "reused": false,
                "local_path": "papers/repair/7b52598737bfafc8deab.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.6980v8",
                "bytes": 619544,
                "reused": false,
                "local_path": "papers/repair/0a612e9d0294ad8485d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.00028.pdf",
                "bytes": 6187582,
                "reused": false,
                "local_path": "papers/repair/e6aa0075133ef9410890.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 27088,
            "expected_body_images": 10,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/45444954e783/pages/source.html",
            "local_html": "attachments/45444954e783/pages/article.html",
            "body_base_path": "attachments/45444954e783/pages/",
            "body_markdown_path": "attachments/45444954e783/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
          "status": "partial",
          "article_id": "bd2a1c61491f",
          "local_path": "series-follow/1601/repair/99f4c939175460a007b6.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cfd86d1d041d4e587dd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/57e8505d379090b6a5c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
              "bytes": 66540,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/eb72333120a9bf61db22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
              "bytes": 517373,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/94806f3485ee4c7d4137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
              "bytes": 420355,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/10c3f7a4432b939f41e9.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
              "bytes": 110695,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9af813630ff27b91e9f8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
              "bytes": 104844,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2d52fb35835b8ffb9f5c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
              "bytes": 441748,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b512db56c30433d4c252.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
              "bytes": 81702,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/701853184c4d260333df.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
              "bytes": 75150,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/440b77c01199a8fa47a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
              "bytes": 308982,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/321a0b363e9a6d1aa98b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
              "bytes": 136227,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/65f1b4ee283f16066c80.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
              "bytes": 118602,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f6d1acbfbe9a2ebc5720.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
              "bytes": 128314,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6801941ec960782dbcdd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
              "bytes": 49638,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/aa7a4901bbb57ffba3a8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
              "bytes": 144593,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/61300c84161edec245ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
              "bytes": 92635,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e33cbf677e130ee48f58.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
              "bytes": 244624,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f5d3b8b9ebc8beb78c77.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
              "bytes": 135708,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/30a7b1c7f2d502623782.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
              "bytes": 181556,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/528e7d446bed9aeb5917.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
              "bytes": 306995,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/08fa8454100a632db05c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
              "bytes": 296726,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5fade868b98da3fc740e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
              "bytes": 150541,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1864a0421abec41db939.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
              "bytes": 300912,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9bbffc5733b6530c7240.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
              "bytes": 278596,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8ed5854240a34aa93f46.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "The Transformer Family Version 2.0",
            "keywords": "Transformer,注意力,架构",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "publish_date": "2023-01",
            "corpus_stage": "预训练/SFT",
            "notes": "Transformer架构家族全景综述（2.0版）",
            "id": "bd2a1c61491f",
            "collected_at": "2026-10-02T14:12:43",
            "title": "The Transformer Family Version 2.0 | Lil'Log",
            "body_markdown": "Many new Transformer architecture improvements have been proposed since my last post on\n“The Transformer Family”\nabout three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n#\nSymbol\nMeaning\n$d$\nThe model size / hidden state dimension / positional encoding size.\n$h$\nThe number of heads in multi-head attention layer.\n$L$\nThe segment length of input sequence.\n$N$\nThe total number of attention layers in the model; not considering MoE.\n$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\nThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\nThe key weight matrix.\n$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\nThe query weight matrix.\n$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\nThe value weight matrix. Often we have $d_k = d_v = d$.\n$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\nThe weight matrices per head.\n$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\nThe output weight matrix.\n$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\nThe query embedding inputs.\n$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\nThe key embedding inputs.\n$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\nThe value embedding inputs.\n$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\nRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n$S_i$\nA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\nThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n$a_{ij} \\in \\mathbf{A}$\nThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\nposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\nTransformer Basics\n#\nThe\nTransformer\n(which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions;\nVaswani, et al., 2017\n) model has an encoder-decoder architecture, as commonly used in many\nNMT\nmodels. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only\nBERT\nor decoder-only\nGPT\n.\nAttention and Self-Attention\n#\nAttention\nis a mechanism in neural network that a model can learn to make predictions by selectively attending to a given set of data. The amount of attention is quantified by learned weights and thus the output is usually formed as a weighted average.\nSelf-attention\nis a type of attention mechanism where the model makes prediction for one part of a data sample using other parts of the observation about the same sample. Conceptually, it feels quite similar to\nnon-local means\n. Also note that self-attention is permutation-invariant; in other words, it is an operation on sets.\nThere are various forms of attention / self-attention, Transformer (\nVaswani et al., 2017\n) relies on the\nscaled dot-product attention\n: given a query matrix $\\mathbf{Q}$, a key matrix $\\mathbf{K}$ and a value matrix $\\mathbf{V}$, the output is a weighted sum of the value vectors, where the weight assigned to each value slot is determined by the dot-product of the query with the corresponding key:\n$$\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q} {\\mathbf{K}}^\\top}{\\sqrt{d_k}})\\mathbf{V}\n$$\nAnd for a query and a key vector $\\mathbf{q}_i, \\mathbf{k}_j \\in \\mathbb{R}^d$ (row vectors in query and key matrices), we have a scalar score:\n$$\na_{ij} = \\text{softmax}(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})\n= \\frac{\\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_j}^\\top}{\\sqrt{d_k}})}{ \\sum_{r \\in \\mathcal{S}_i} \\exp(\\frac{\\mathbf{q}_i {\\mathbf{k}_r}^\\top}{\\sqrt{d_k}}) }\n$$\nwhere $\\mathcal{S}_i$ is a collection of key positions for the $i$-th query to attend to.\nSee my old\npost for other types of attention\nif interested.\nMulti-Head Self-Attention\n#\nThe\nmulti-head self-attention\nmodule is a key component in Transformer. Rather than only computing the attention once, the multi-head mechanism splits the inputs into smaller chunks and then computes the scaled dot-product attention over each subspace in parallel. The independent attention outputs are simply concatenated and linearly transformed into expected dimensions.\n$$\n\\begin{aligned}\n\\text{MultiHeadAttn}(\\mathbf{X}_q, \\mathbf{X}_k, \\mathbf{X}_v) &= [\\text{head}_1; \\dots; \\text{head}_h] \\mathbf{W}^o \\\\ \n\\text{where head}_i &= \\text{Attention}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{X}_v\\mathbf{W}^v_i)\n\\end{aligned}\n$$\nwhere $[.;.]$ is a concatenation operation. $\\mathbf{W}^q_i, \\mathbf{W}^k_i \\in \\mathbb{R}^{d \\times d_k/h}, \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$ are weight matrices to map input embeddings of size $L \\times d$ into query, key and value matrices. And $\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$ is the output linear transformation. All the weights should be learned during training.\nIllustration of the multi-head scaled dot-product attention mechanism. (Image source: Figure 2 in\nVaswani, et al., 2017\n)\nEncoder-Decoder Architecture\n#\nThe\nencoder\ngenerates an attention-based representation with capability to locate a specific piece of information from a large context. It consists of a stack of 6 identity modules, each containing two submodules, a\nmulti-head self-attention\nlayer and a\npoint-wise\nfully connected feed-forward network. By point-wise, it means that it applies the same linear transformation (with same weights) to each element in the sequence. This can also be viewed as a convolutional layer with filter size 1. Each submodule has a residual connection and layer normalization. All the submodules output data of the same dimension $d$.\nThe function of Transformer\ndecoder\nis to retrieve information from the encoded representation. The architecture is quite similar to the encoder, except that the decoder contains two multi-head attention submodules instead of one in each identical repeating module. The first multi-head attention submodule is\nmasked\nto prevent positions from attending to the future.\nThe architecture of the vanilla Transformer model. (Image source:\nFigure 17\n)\nPositional Encoding\n#\nBecause self-attention operation is permutation invariant, it is important to use proper\npositional encoding\nto provide\norder information\nto the model. The positional encoding $\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$ has the same dimension as the input embedding, so it can be added on the input directly. The vanilla Transformer considered two types of encodings:\nSinusoidal Positional Encoding\n#\nSinusoidal positional encoding is defined as follows, given the token position $i=1,\\dots,L$ and the dimension $\\delta=1,\\dots,d$:\n$$\n\\text{PE}(i,\\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nIn this way each dimension of the positional encoding corresponds to a sinusoid of different wavelengths in different dimensions, from $2\\pi$ to $10000 \\cdot 2\\pi$.\nSinusoidal positional encoding with $L=32$ and $d=128$. The value is between -1 (black) and 1 (white) and the value 0 is in gray.\nLearned Positional Encoding\n#\nLearned positional encoding assigns each element with a\nlearned\ncolumn vector which encodes its absolute position (\nGehring, et al. 2017\n) and furthermroe this encoding can be learned differently per layer (\nAl-Rfou et al. 2018\n).\nRelative Position Encoding\n#\nShaw et al. (2018)\n) incorporated relative positional information into $\\mathbf{W}^k$ and $\\mathbf{W}^v$. Maximum relative position is clipped to a maximum absolute value of $k$ and this clipping operation enables the model to generalize to unseen sequence lengths. Therefore, $2k + 1$ unique edge labels are considered and let us denote $\\mathbf{P}^k, \\mathbf{P}^v \\in \\mathbb{R}^{2k+1}$ as learnable relative position representations.\n$$\nA_{ij}^k = P^k_{\\text{clip}(j - i, k)} \\quad\nA_{ij}^v = P^v_{\\text{clip}(j - i, k)} \\quad\n\\text{where }\\text{clip}(x, k) = \\text{clip}(x, -k, k)\n$$\nTransformer-XL\n(\nDai et al., 2019\n) proposed a type of relative positional encoding based on reparametrization of dot-product of keys and queries. To keep the positional information flow coherently across segments, Transformer-XL encodes the\nrelative\nposition instead, as it could be sufficient enough to know the position offset for making good predictions, i.e. $i-j$, between one key vector $\\mathbf{k}_{\\tau, j}$ and its query $\\mathbf{q}_{\\tau, i}$.\nIf omitting the scalar $1/\\sqrt{d_k}$ and the normalizing term in softmax but including positional encodings, we can write the attention score between query at position $i$ and key at position $j$ as:\n$$\n\\begin{aligned}\na_{ij} \n&= \\mathbf{q}_i {\\mathbf{k}_j}^\\top = (\\mathbf{x}_i + \\mathbf{p}_i)\\mathbf{W}^q ((\\mathbf{x}_j + \\mathbf{p}_j)\\mathbf{W}^k)^\\top \\\\\n&= \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{x}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{x}_j^\\top + \\mathbf{p}_i\\mathbf{W}^q {\\mathbf{W}^k}^\\top\\mathbf{p}_j^\\top\n\\end{aligned}\n$$\nTransformer-XL reparameterizes the above four terms as follows:\n$$\na_{ij}^\\text{rel} = \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{content-based addressing} + \n\\underbrace{ \\mathbf{x}_i\\mathbf{W}^q \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{content-dependent positional bias} + \n\\underbrace{ \\color{red}{\\mathbf{u}} \\color{blue}{ {\\mathbf{W}_E^k}^\\top } \\mathbf{x}_j^\\top }_\\text{global content bias} + \n\\underbrace{ \\color{red}{\\mathbf{v}} \\color{blue}{ {\\mathbf{W}_R^k}^\\top } \\color{green}{\\mathbf{r}_{i-j}^\\top} }_\\text{global positional bias}\n$$\nReplace $\\mathbf{p}_j$ with relative positional encoding $\\mathbf{r}_{i-j} \\in \\mathbf{R}^{d}$;\nReplace $\\mathbf{p}_i\\mathbf{W}^q$ with two trainable parameters $\\mathbf{u}$ (for content) and $\\mathbf{v}$ (for location) in two different terms;\nSplit $\\mathbf{W}^k$ into two matrices, $\\mathbf{W}^k_E$ for content information and $\\mathbf{W}^k_R$ for location information.\nRotary Position Embedding\n#\nRotary position embedding (\nRoPE\n;\nSu et al. 2021\n) encodes the absolution position with a\nrotation matrix\nand multiplies key and value matrices of every attention layer with it to inject relative positional information at every layer.\nWhen encoding relative positional information into the inner product of the $i$-th key and the $j$-th query, we would like to formulate the function in a way that the inner product is only about the relative position $i-j$. Rotary Position Embedding (RoPE) makes use of the rotation operation in Euclidean space and frames the relative position embedding as simply rotating feature matrix by an angle proportional to its position index.\nGiven a vector $\\mathbf{z}$, if we want to rotate it counterclockwise by $\\theta$, we can multiply it by a rotation matrix to get $R\\mathbf{z}$ where the rotation matrix $R$ is defined as:\n$$\nR = \\begin{bmatrix}\n\\cos\\theta & -\\sin\\theta \\\\\n\\sin\\theta & \\cos\\theta\n\\end{bmatrix}\n$$\nWhen generalizing to higher dimensional space, RoPE divide the $d$-dimensional space into $d/2$ subspaces and constructs a rotation matrix $R$ of size $d \\times d$ for token at position $i$:\n$$\nR^d_{\\Theta, i} = \\begin{bmatrix}\n\\cos i\\theta_1 & -\\sin i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n\\sin i\\theta_1 & \\cos i\\theta_1 & 0 & 0 & \\dots & 0 & 0 \\\\\n0 & 0 & \\cos i\\theta_2 & -\\sin i\\theta_2 & \\dots & 0 & 0 \\\\\n0 & 0 & \\sin i\\theta_2 & \\cos i\\theta_2 & \\dots & 0 & 0 \\\\\n\\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n0 & 0 & 0 & 0 & \\dots & \\cos i\\theta_{d/2} & -\\sin i\\theta_{d/2} \\\\\n0 & 0 & 0 & 0 & \\dots & \\sin i\\theta_{d/2} & \\cos i\\theta_{d/2} \\\\\n\\end{bmatrix}\n$$\nwhere in the paper we have $\\Theta = {\\theta_i = 10000^{-2(i−1)/d}, i \\in [1, 2, …, d/2]}$. Note that this is essentially equivalent to sinusoidal positional encoding but formulated as a rotation matrix.\nThen both key and query matrices incorporates the positional information by multiplying with this rotation matrix:\n$$\n\\begin{aligned}\n& \\mathbf{q}_i^\\top \\mathbf{k}_j = (R^d_{\\Theta, i} \\mathbf{W}^q\\mathbf{x}_i)^\\top (R^d_{\\Theta, j} \\mathbf{W}^k\\mathbf{x}_j) = \\mathbf{x}_i^\\top\\mathbf{W}^q R^d_{\\Theta, j-i}\\mathbf{W}^k\\mathbf{x}_j \\\\\n& \\text{ where } R^d_{\\Theta, j-i} = (R^d_{\\Theta, i})^\\top R^d_{\\Theta, j}\n\\end{aligned}\n$$\nVisual illustration of how rotary position embedding is implemented.(Image source:\nSu et al., 2021\n) Note: I used $i$ instead of $m$ to represent the position index compared to the original figure in the paper.\nLonger Context\n#\nThe length of an input sequence for transformer models at inference time is upper-bounded by the context length used for training. Naively increasing context length leads to high consumption in both time ($\\mathcal{O}(L^2d)$) and memory ($\\mathcal{O}(L^2)$) and may not be supported due to hardware constraints.\nThis section introduces several improvements in transformer architecture to better support long context at inference; E.g. using additional memory, design for better context extrapolation, or recurrency mechanism.\nContext Memory\n#\nThe vanilla Transformer has a fixed and limited attention span. The model can only attend to other elements in the same segments during each update step and no information can flow across separated fixed-length segments. This\ncontext segmentation\ncauses several issues:\nThe model cannot capture very long term dependencies.\nIt is hard to predict the first few tokens in each segment given no or thin context.\nThe evaluation is expensive. Whenever the segment is shifted  to the right by one, the new segment is re-processed from scratch, although there are a lot of overlapped tokens.\nTransformer-XL\n(\nDai et al., 2019\n; “XL” means “extra long”) modifies the architecture to reuse hidden states between segments with an additional memory. The recurrent connection between segments is introduced into the model by continuously using the hidden states from the previous segments.\nA comparison between the training phrase of vanilla Transformer & Transformer-XL with a segment length 4. (Image source: left part of Figure 2 in\nDai et al., 2019\n).\nLet’s label the hidden state of the $n$-th layer for the $(\\tau + 1)$-th segment in the model as $\\mathbf{h}_{\\tau+1}^{(n)} \\in \\mathbb{R}^{L \\times d}$. In addition to the hidden state of the last layer for the same segment $\\mathbf{h}_{\\tau+1}^{(n-1)}$, it also depends on the hidden state of the same layer for the previous segment $\\mathbf{h}_{\\tau}^{(n)}$.  By incorporating information from the previous hidden states, the model extends the attention span much longer in the past, over multiple segments.\n$$\n\\begin{aligned}\n\\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} &= [\\text{stop-gradient}(\\mathbf{h}_{\\tau}^{(n-1)}) \\circ \\mathbf{h}_{\\tau+1}^{(n-1)}] \\\\\n\\mathbf{Q}_{\\tau+1}^{(n)} &= \\mathbf{h}_{\\tau+1}^{(n-1)}\\mathbf{W}^q \\\\\n\\mathbf{K}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^k \\\\\n\\mathbf{V}_{\\tau+1}^{(n)} &= \\color{red}{\\widetilde{\\mathbf{h}}_{\\tau+1}^{(n-1)}} \\mathbf{W}^v \\\\\n\\mathbf{h}_{\\tau+1}^{(n)} &= \\text{transformer-layer}(\\mathbf{Q}_{\\tau+1}^{(n)}, \\mathbf{K}_{\\tau+1}^{(n)}, \\mathbf{V}_{\\tau+1}^{(n)})\n\\end{aligned}\n$$\nNote that both keys and values rely on extended hidden states, while queries only consume hidden states at the current step. The concatenation operation $[. \\circ .]$ is along the sequence length dimension. And Transformer-XL needs to use\nrelative positional encoding\nbecause previous and current segments would be assigned with the same encoding if we encode absolute positions, which is undesired.\nCompressive Transformer\n(\nRae et al. 2019\n) extends Transformer-XL by compressing past memories to support longer sequences. It explicitly adds\nmemory\nslots of size $m_m$ per layer for storing past activations of this layer to preserve long context. When some past activations become old enough, they are compressed and saved in an additional\ncompressed memory\nof size $m_{cm}$ per layer.\nCompressive transformer maintains two types of memory slots, memory and compressed memory, to support long context. (Image source:\nRae et al. 2019\n).\nBoth memory and compressed memory are FIFO queues. Given the model context length $L$, the compression function of compression rate $c$ is defined as $f_c: \\mathbb{R}^{L \\times d} \\to \\mathbb{R}^{[\\frac{L}{c}] \\times d}$, mapping $L$ oldest activations to $[\\frac{L}{c}]$ compressed memory elements. There are several choices of compression functions:\nMax/mean pooling of kernel and stride size $c$;\n1D convolution with kernel and stride size $c$ (need to learn additional parameters);\nDilated convolution (need to learn additional parameters). In their experiments, convolution compression works out the best on\nEnWik8\ndataset;\nMost used memories.\nCompressive transformer has two additional training losses:\nAuto-encoding loss\n(lossless compression objective) measures how well we can reconstruct the original memories from compressed memories\n$$\n \\mathcal{L}_{ac} = \\| \\textbf{old_mem}^{(i)} - g(\\textbf{new_cm}^{(i)}) \\|_2\n $$\nwhere $g: \\mathbb{R}^{[\\frac{L}{c}] \\times d} \\to \\mathbb{R}^{L \\times d}$ reverses the compression function $f$.\nAttention-reconstruction loss\n(lossy objective) reconstructs content-based attention over memory vs compressed memory and minimize the difference:\n$$\n \\mathcal{L}_{ar} = \\|\\text{attn}(\\mathbf{h}^{(i)}, \\textbf{old_mem}^{(i)}) − \\text{attn}(\\mathbf{h}^{(i)}, \\textbf{new_cm}^{(i)})\\|_2\n $$\nTransformer-XL with a memory of size $m$ has a maximum temporal range of $m \\times N$, where $N$ is the number of layers in the model, and attention cost $\\mathcal{O}(L^2 + Lm)$. In comparison, compressed transformer has a temporal range of $(m_m + c \\cdot m_{cm}) \\times N$ and attention cost $\\mathcal{O}(L^2 + L(m_m + m_{cm}))$. A larger compression rate $c$ gives better tradeoff between temporal range length and attention cost.\nAttention weights, from oldest to newest, are stored in three locations: compressed memory → memory → causally masked sequence. In the experiments, they observed an increase in attention weights from oldest activations stored in the regular memory, to activations stored in the compressed memory, implying that the network is learning to preserve salient information.\nAttention weights with one standard deviation as error bars versus memory positions, from oldest (left) to newest (right). (Image source:\nRae et al. 2019\n).\nNon-Differentiable External Memory\n#\n$k$NN-LM\n(\nKhandelwal et al. 2020\n) enhances a pretrained LM with a separate $k$NN model by linearly interpolating the next token probabilities predicted by both models. The $k$NN model is built upon an external key-value store  which can store any large pre-training dataset or OOD new dataset. This datastore is preprocessed to save a\nlarge\nnumber of pairs, (LM embedding representation of context, next token) and the nearest neighbor retrieval happens in the LM embedding space. Because the datastore can be gigantic, we need to rely on libraries for fast dense vector search such as\nFAISS\nor\nScaNN\n. The indexing process only happens once and parallelism is easy to implement at inference time.\nAt inference time, the next token probability is a weighted sum of two predictions:\n$$\n\\begin{aligned}\np(y \\vert \\mathbf{x}) &= \\lambda \\; p_\\text{kNN}(y \\vert \\mathbf{x}) + (1- \\lambda) \\; p_\\text{LM}(y \\vert \\mathbf{x}) \\\\\np_\\text{kNN}(y \\vert \\mathbf{x}) &\\propto \\sum_{(k_i, w_i) \\in \\mathcal{N}} \\mathbb{1}[y = w_i] \\exp(-d(k_i, f(\\mathbf{x})))\n\\end{aligned}\n$$\nwhere $\\mathcal{N}$ contains a set of nearest neighbor data points retrieved by $k$NN; $d(., .)$ is a distance function such as L2 distance.\nAccording to the experiments, larger datastore size or larger $k$ is correlated with better perplexity. The weighting scalar $\\lambda$ should be tuned, but in general it is expected to be larger for out-of-domain data compared to in-domain data and larger datastore can afford a larger $\\lambda$.\nSPALM\n(\nAdaptive semiparametric language models\n;\nYogatama et al. 2021\n) incorporates both (1) Transformer-XL style memory for hidden states from external context as short-term memory and (2) $k$NN-LM style key-value store as long memory.\nIllustration of how SPALM combines context memory of past hidden states (short term memory) with an external key-value datastore (long term memory) to support longer context. (Image source:\nYogatama et al. 2021\n).\nSPALM runs $k$NN search to fetch $k$ tokens with most relevant context. For each token we can get the same embedding representation provided by a pretrained LM, denoted as $\\{\\mathbf{y}_i\\}_{i=1}^k$. The gating mechanism first aggregates the retrieved token embeddings with a simple attention layer using $\\mathbf{h}^R_t$ (the hidden state for token $x_t$ at layer $R$) as a query and then learns a gating parameter $\\mathbf{g}_t$ to balance between local information $\\mathbf{h}^R_t$ and long-term information $\\mathbf{m}_t$.\n$$\n\\begin{aligned}\n\\mathbf{m}_t &= \\sum_{i=1}^k \\frac{\\exp(\\mathbf{y}_i^\\top \\mathbf{h}^R_t)}{\\sum_{j=1}^k \\exp(\\mathbf{y}_j^\\top \\mathbf{h}^R_t)} \\cdot \\mathbf{y}_i \\\\\n\\mathbf{g}_t &= \\sigma(\\mathbf{w}_g^\\top \\mathbf{h}_t^R) \\\\\n\\mathbf{z}_t &= (1 - \\mathbf{g}_t) \\odot \\mathbf{m}_t + \\mathbf{g}_t \\odot \\mathbf{h}^R_t \\\\\np(x_{t+1}\\mid \\mathbf{x}_{\\leq t}) &= \\text{softmax}(\\mathbf{z}_t; \\mathbf{W})\n\\end{aligned}\n$$\nwhere $\\mathbf{w}_g$ is a parameter vector to learn; $\\sigma(.)$ is sigmoid; $\\mathbf{W}$ is the word embedding matrix shared between both input and output tokens. Different from $k$NN-LM, they didn’t find the nearest neighbor distance to be helpful in the aggregation of retrieved tokens.\nDuring training, the key representations in the long-term memory stay constant, produced by a pretrained LM, but the value encoder, aka the word embedding matrix, gets updated.\nMemorizing Transformer\n(\nWu et al. 2022\n) adds a $k$NN-augmented attention layer near the top stack of a decoder-only Transformer. This special layer maintains a Transformer-XL style FIFO cache of past key-value pairs.\nThe same QKV values are used for both local attention and $k$NN mechanisms. The $k$NN lookup returns top-$k$ (key, value) pairs for each query in the input sequence and then they are processed through the self-attention stack to compute a weighted average of retrieved values. Two types of attention are combined with a learnable per-head gating parameter. To prevent large distributional shifts in value magnitude, both keys and values in the cache are normalized.\nWhat they found during experiments with Memorizing Transformer:\nIt is observed in some experiments that training models with a small memory and then finetuned with a larger memory works better than training with a large memory from scratch.\nThe smaller Memorizing Transformer with just 8k tokens in memory can match the perplexity of a larger vanilla Transformer with 5X more trainable parameters.\nIncreasing the size of external memory provided consistent gains up to a size of 262K.\nA  non-memory transformer can be finetuned to use memory.\nFine-tuning a vanilla Transformer with a key-value memory can achieve similar performance as training a memorizing transformer from scratch. (Image source:\nWu et al. 2022\n).\nDistance-Enhanced Attention Scores\n#\nDistance Aware Transformer\n(\nDA-Transformer\n;\nWu, et al. 2021\n) and\nAttention with Linear Biases\n(\nALiBi\n;\nPress et al. 2022\n) are motivated by similar ideas — in order to encourage the model to extrapolate over longer context than what the model is trained on, we can explicitly attach the positional information to every pair of attention score based on the distance between key and query tokens.\nNote that the default positional encoding in vanilla Transformer only adds positional information to the input sequence, while later improved encoding mechanisms alter attention scores of every layer, such as\nrotary position embedding\n, and they take on form very similar to distance enhanced attention scores.\nDA-Transformer\n(\nWu, et al. 2021\n) multiplies attention scores at each layer by a learnable bias that is formulated as a function of the distance between key and query. Different attention heads use different parameters to distinguish diverse preferences to short-term vs long-term context. Given two positions, $i, j$, DA-Transformer uses the following weighting function to alter the self-attention score:\n$$\n\\begin{aligned}\n\\mathbf{R}^{(i)} &= \\alpha_i \\mathbf{R} \\quad \\text{where }R_{ij} = \\vert i-j \\vert\\\\\nf(\\mathbf{R}^{(i)}; \\beta_i) &= \\frac{1 + \\exp(\\beta_i)}{1 + \\exp(\\beta_i - \\mathbf{R}^{(i)})} \\\\\n\\text{attn}(\\mathbf{Q}^{(i)}, \\mathbf{K}^{(i)}, \\mathbf{V}^{(i)}) &= \\text{row-softmax}\\Big(\\frac{\\text{ReLU}(\\mathbf{Q}^{(i)}\\mathbf{K}^{(i)\\top})f(\\mathbf{R}^{(i)})}{\\sqrt{d}}\\Big) \\mathbf{V}^{(i)}\n\\end{aligned}\n$$\nwhere $\\alpha_i$ is a learnable parameters to weight relative distance differently per head where the head is indexed by superscript $^{(i)}$; $\\beta_i$ is a learnable parameter to control the upper bound and ascending slope wrt the distance for the $i$-th attention head. The weighting function $f(.)$ is designed in a way that: (1) $f(0)=1$; (2) $f(\\mathbf{R}^{(i)}) = 0$ when $\\mathbf{R}^{(i)} \\to -\\infty$; (3) $f(\\mathbf{R}^{(i)})$ is bounded when $\\mathbf{R}^{(i)} \\to +\\infty$; (4) the scale is tunable; (5) and the function is monotonic. The extra time complexity brought by $f(\\mathbf{R}^{(i)})$ is $\\mathcal{O}(L^2)$ and it is small relative to the self attention time complexity $\\mathcal{O}(L^2 d)$. The extra memory consumption is minimal, ~$\\mathcal{O}(2h)$.\nInstead of multipliers,\nALiBi\n(\nPress et al. 2022\n) adds a constant bias term on query-key attention scores, proportional to pairwise distances. The bias introduces a strong recency preference and penalizes keys that are too far away. The penalties are increased at different rates within different heads.\n$$\n\\text{softmax}(\\mathbf{q}_i \\mathbf{K}^\\top + \\alpha_i \\cdot [0, -1, -2, \\dots, -(i-1)])\n$$\nwhere $\\alpha_i$ is a head-specific weighting scalar. Different from DA-transformer, $\\alpha_i$ is not learned but fixed as a geometric sequence; for example, for 8 heads, ${\\alpha_i} = {\\frac{1}{2}, \\frac{1}{2^2}, \\dots, \\frac{1}{2^8}}$. The overall idea is very much similar to what relative positional encoding aims to solve.\nIllustration of how ALiBi enhances attention scores with a positional bias term. (Image source:\nPress et al. 2021\n).\nWith ALiBi,\nPress et al. (2022)\ntrained a 1.3B model on context length 1024 during training and extrapolated to 2046 at inference time.\nExtrapolation experiments for running inference with Transformers of different configs, including sinusoidal positional encoding, rotary positional encoding, simplified relative positional encoding in T5 and ALiBi. All models were trained with small context length but inference ran for much longer context. (Image source:\nPress et al. 2021\n).\nMake it Recurrent\n#\nUniversal Transformer\n(\nDehghani, et al. 2019\n) combines self-attention in Transformer with the recurrent mechanism in RNN, aiming to benefit from both a long-term global receptive field of Transformer and learned inductive biases of RNN. Rather than going through a fixed number of layers, Universal Transformer dynamically adjusts the number of steps using\nadaptive computation time\n. If we fix the number of steps, an Universal Transformer is equivalent to a multi-layer Transformer with shared parameters across layers.\nOn a high level, the universal transformer can be viewed as a recurrent function for learning the hidden state representation per token. The recurrent function evolves in parallel across token positions and the information between positions is shared through self-attention.\nHow the Universal Transformer refines a set of hidden state representations repeatedly for every position in parallel. (Image source: Figure 1 in\nDehghani, et al. 2019\n).\nGiven an input sequence of length $L$, Universal Transformer iteratively updates the representation $\\mathbf{h}^t \\in \\mathbb{R}^{L \\times d}$ at step $t$ for an adjustable number of steps. At step 0, $\\mathbf{h}^0$ is initialized to be same as the input embedding matrix. All the positions are processed in parallel in the multi-head self-attention mechanism and then go through a recurrent transition function.\n$$\n\\begin{aligned}\n\\mathbf{A}^t &= \\text{LayerNorm}(\\mathbf{h}^{t-1} + \\text{MultiHeadAttention}(\\mathbf{h}^{t-1} + \\mathbf{P}^t) \\\\\n\\mathbf{h}^t &= \\text{LayerNorm}(\\mathbf{A}^{t-1} + \\text{Transition}(\\mathbf{A}^t))\n\\end{aligned}\n$$\nwhere $\\text{Transition}(.)$ is either a\nseparable convolution\nor a fully-connected neural network that consists of two position-wise (i.e. applied to each row of $\\mathbf{A}^t$ individually) affine transformation + one ReLU.\nThe positional encoding $\\mathbf{P}^t$ uses\nsinusoidal position signal\nbut with an additional time dimension:\n$$\n\\text{PE}(i, t, \\delta) = \n\\begin{cases}\n\\sin(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\sin(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta'\\\\\n\\cos(\\frac{i}{10000^{2\\delta'/d}}) \\oplus \\cos(\\frac{t}{10000^{2\\delta'/d}}) & \\text{if } \\delta = 2\\delta' + 1\\\\\n\\end{cases}\n$$\nA simplified illustration of Universal Transformer. The encoder and decoder share the same basic recurrent structure. But the decoder also attends to final encoder representation $\\mathbf{h}^T$. (Image source: Figure 2 in\nDehghani, et al. 2019\n)\nIn the adaptive version of Universal Transformer, the number of recurrent steps $T$ is dynamically determined by\nACT\n. Each position is equipped with a dynamic ACT halting mechanism. Once a per-token recurrent block halts, it stops taking more recurrent updates but simply copies the current value to the next step until all the blocks halt or until the model reaches a maximum step limit.\nAdaptive Modeling\n#\nAdaptive modeling refers to a mechanism that can adjust the amount of computation according to different inputs. For example, some tokens may only need local information and thus demand a shorter attention span; Or some tokens are relatively easier to predict and do not need to be processed through the entire attention stack.\nAdaptive Attention Span\n#\nOne key advantage of Transformer is the capability of capturing long-term dependencies. Depending on the context, the model may prefer to attend further sometime than others; or one attention head may had different attention pattern from the other. If the attention span could adapt its length flexibly and only attend further back when needed, it would help reduce both computation and memory cost to support longer maximum context size in the model.\nThis is the motivation for\nAdaptive Attention Span\n.\nSukhbaatar et al (2019)\nproposed a self-attention mechanism that seeks an optimal attention span. They hypothesized that different attention heads might assign scores differently within the same context window (See Fig. 14) and thus the optimal span would be trained separately per head.\nTwo attention heads in the same model, A & B, assign attention differently within the same context window. Head A attends more to the recent tokens, while head B look further back into the past uniformly. (Image source:\nSukhbaatar, et al. 2019\n)\nGiven the $i$-th token, we need to compute the attention weights between this token and other keys within its attention span of size $s$:\n$$\n\\begin{aligned}\ne_{ij} &= \\mathbf{q}_i {\\mathbf{k}_j}^\\top \\\\ \na_{ij} &= \\text{softmax}(e_{ij}) = \\frac{\\exp(e_{ij})}{\\sum_{r=i-s}^{i-1} \\exp(e_{ir})} \\\\\n\\mathbf{y}_i &= \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{v}_r = \\sum_{r=i-s}^{i-1}a_{ir}\\mathbf{x}_r\\mathbf{W}^v\n\\end{aligned}\n$$\nA\nsoft mask function\n$m_z$ is added to control for an effective adjustable attention span, which maps the distance between query and key into a [0, 1] value. $m_z$ is parameterized by $z \\in [0, s]$ and $z$ is to be learned:\n$$\nm_z(x) = \\text{clip}(\\frac{1}{R}(R+z-x), 0, 1)\n$$\nwhere $R$ is a hyper-parameter which defines the softness of $m_z$.\nThe soft masking function used in the adaptive attention span. (Image source:\nSukhbaatar, et al. 2019\n.)\nThe soft mask function is applied to the softmax elements in the attention weights:\n$$\na_{ij} = \\frac{m_z(i-j)\\exp(s_{ij})}{\\sum_{r=i-s}^{i-1}m_z(i-r) \\exp(s_{ir})}\n$$\nIn the above equation, $z$ is differentiable so it is trained jointly with other parts of the model. Parameters $z^{(i)}, i=1, \\dots, h$ are learned\nseparately per head\n. Moreover, the loss function has an extra L1 penalty on $\\sum_{i=1}^h z^{(i)}$.\nUsing\nAdaptive Computation Time\n, the approach can be further enhanced to have flexible attention span length, adaptive to the current input dynamically. The span parameter $z_t$ of an attention head at time $t$ is a sigmoidal function, $z_t = S \\sigma(\\mathbf{v} \\cdot \\mathbf{x}_t +b)$, where the vector $\\mathbf{v}$ and the bias scalar $b$ are learned jointly with other parameters.\nIn the experiments of Transformer with adaptive attention span,\nSukhbaatar, et al. (2019)\nfound a general tendency that lower layers do not require very long attention spans, while a few attention heads in higher layers may use exceptionally long spans. Adaptive attention span also helps greatly reduce the number of FLOPS, especially in a big model with many attention layers and a large context length.\nDepth-Adaptive Transformer\n#\nAt inference time, it is natural to assume that some tokens are easier to predict and thus do not require as much computation as others. Therefore we may only process its prediction through a limited number of layers to achieve a good balance between speed and performance.\nBoth\nDepth-Adaptive Transformer\n(\nElabyad et al. 2020\n) and\nConfident Adaptive Language Model\n(\nCALM\n;\nSchuster et al. 2022\n) are motivated by this idea and learn to predict optimal numbers of layers needed for different input tokens.\nDepth-adaptive transformer\n(\nElabyad et al. 2020\n) attaches an output classifier to every layer to produce exit predictions based on activations of that layer. The classifier weight matrices can be different per layer or shared across layers. During training, the model sample different sequences of exits such that the model is optimized with hidden states of different layers. The learning objective incorporates likelihood probabilities predicted at different layers, $n=1, \\dots, N$:\n$$\n\\text{LL}^n_t = \\log p(y_t \\vert \\mathbf{h}^n_{t-1}) \\quad\n\\text{LL}^n = \\sum_{t=1}^{\\vert\\mathbf{y}\\vert} LL^n_t\n$$\nAdaptive depth classifiers outputs a parametric distribution $q_t$. It is trained with cross entropy loss against an oracle distribution $q^*_t$. The paper explored three confiurations for how to learn such a classifier $q_t$.\nIllustration of three types of adaptive depth classifiers.\n(Image source:\nElabyad et al. 2020\n).\nSequence-specific depth classifier\n: All tokens of the same sequence share the same exit block. It depends on the average of the encoder representation of the sequence. Given an input sequence $\\mathbf{x}$ of length $L$, the classifier takes $\\bar{\\mathbf{x}} = \\frac{1}{L} \\sum_{t=1}^L \\mathbf{x}_t$ as input and outputs a multinomial distribution of $N$ dimensions, corresponding to $N$ layers.\n$$\n \\begin{aligned}\n q(n \\vert \\mathbf{x}) &=\\text{softmax}(\\mathbf{W}_n \\bar{\\mathbf{x}} + b_n) \\in \\mathbb{R}^N \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\text{LL}^n - \\lambda n) \\\\\n \\text{or }q_\\text{corr}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n C^n - \\lambda n) \\text{ where }C^n = \\vert\\{t \\vert y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})\\}\\vert \\\\\n \\end{aligned}\n $$\nwhere $\\delta$ is\ndirac delta\n(unit impulse) function and $-\\lambda n$ is a regularization term to encourage lower layer exits. The ground truth $q^*$ can be prepared in two way, based on maximum likelihood $q_\\text{lik}^*$ or correctness $q_\\text{corr}^*$.\nToken-specific depth classifier (multinomial)\n: Each token is decoded with different exit block, predicted conditioned on the first decoder hidden state $\\mathbf{h}^1_t$:\n$$\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) = \\text{softmax}(\\mathbf{W}_n \\mathbf{h}^1_t + b_n)\n $$\nToken-specific depth classifier (geometric-like)\n:  A binary exit prediction distribution is made per layer per token, $\\mathcal{X}^n_t$. The RBF kernel $\\kappa(t, t’) = \\exp(\\frac{\\vert t - t’ \\vert^2}{\\sigma})$ is used to smooth the predictions to incorporate the impact of current decision on future time steps.\n$$\n \\begin{aligned}\n \\mathcal{X}^n_t &= \\text{sigmoid}(\\mathbf{w}_n^\\top \\mathbf{h}^n_t + b_n)\\quad \\forall n \\in [1, \\dots, N-1] \\\\\n q_t(n \\vert \\mathbf{x}, \\mathbf{y}_{< t}) &= \\begin{cases}\n \\mathcal{X}^n_t \\prod_{n' < n} (1 - \\mathcal{X}^{n'}_t) & \\text{if } n < N\\\\\n \\prod_{n' < N} (1 - \\mathcal{X}^{n'}_t) & \\text{otherwise}\n \\end{cases} \\\\\n q_\\text{lik}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\widetilde{\\text{LL}}^n_t - \\lambda n) \\text{ where } \\widetilde{\\text{LL}}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') LL^n_{t'} \\\\\n \\text{or }q_\\text{cor}^*(\\mathbf{x}, \\mathbf{y}) &= \\delta(\\arg\\max_n \\tilde{C}_t^n - \\lambda n) \\text{ where }C_t^n = \\mathbb{1}[y_t = \\arg\\max_y p(y \\vert \\mathbf{h}^n_{t-1})],\\; \\tilde{C}^n_t = \\sum_{t'=1}^{\\vert\\mathbf{y}\\vert}\\kappa(t, t') C^n_{t'} \\\\\n \\end{aligned}\n $$\nAt inference time, the confidence threshold for making an exit decision needs to be calibrated. Depth-adaptive transformer finds such a threshold on a validation set via grid search.\nCALM\n(\nSchuster et al. 2022\n) applied the Learn then Test (LTT) framework (\nAngelopoulos et al. 2021\n) to identify a subset of valid thresholds and chose the minimum value as the threshold for inference. Except for training per-layer exit classifier, CALM also explored other methods for adaptive depth prediction, including the softmax responses (i.e. difference between top two softmax outputs) and hidden state saturation (i.e. $\\cos(\\mathbf{h}^n_t, \\mathbf{h}^{n+1}_t)$) as confidence scores for exit decisions. They found softmax responses result in best inference speedup.\nEfficient Attention\n#\nThe computation and memory cost of the vanilla Transformer grows quadratically with sequence length and hence it is hard to be applied on very long sequences. Many efficiency improvements for Transformer architecture have something to do with the self-attention module - making it cheaper, smaller or faster to run. See the survey paper on\nEfficient Transformers\n(\nTay et al. 2020\n).\nSparse Attention Patterns\n#\nFixed Local Context\n#\nA simple alternation to make self-attention less expensive is to restrict the attention span of each token to\nlocal\ncontext only, so that self-attention grows linearly with the sequence length.\nThe idea was introduced by\nImage Transformer\n(\nParmer, et al 2018\n), which formulates image generation as sequence modeling using an encoder-decoder transformer architecture:\nThe encoder generates a contextualized, per-pixel-channel representation of the source image;\nThen the decoder autoregressively generates an output image, one channel per pixel at each time step.\nLet’s label the representation of the current pixel to be generated as the query $\\mathbf{q}$. Other positions whose representations will be used for computing $\\mathbf{q}$ are key vector $\\mathbf{k}_1, \\mathbf{k}_2, \\dots$ and they together form a memory matrix $\\mathbf{M}$. The scope of $\\mathbf{M}$ defines the context window for pixel query $\\mathbf{q}$.\nImage Transformer introduced two types of localized $\\mathbf{M}$, as illustrated below.\nIllustration of 1D and 2D attention span for visual inputs in Image Transformer. The black line marks a query block and the cyan outlines the actual attention span for pixel q. (Image source: Figure 2 in\nParmer et al, 2018\n)\n1D Local Attention\n: The input image is flattened in the\nraster scanning\norder, that is, from left to right and top to bottom. The linearized image is then partitioned into non-overlapping query blocks. The context window consists of pixels in the same query block as $\\mathbf{q}$ and a fixed number of additional pixels generated before this query block.\n2D Local Attention\n: The image is partitioned into multiple non-overlapping rectangular query blocks. The query pixel can attend to all others in the same memory blocks. To make sure the pixel at the top-left corner can also have a valid context window, the memory block is extended to the top, left and right by a fixed amount, respectively.\nStrided Context\n#\nSparse Transformer\n(\nChild et al., 2019\n) introduced\nfactorized self-attention\n, through sparse matrix factorization, making it possible to train dense attention networks with hundreds of layers on sequence length up to 16,384, which would be infeasible on modern hardware otherwise.\nGiven a set of attention connectivity pattern $\\mathcal{S} = \\{S_1, \\dots, S_n\\}$, where each $S_i$ records a set of key positions that the $i$-th query vector attends to.\n$$\n\\begin{aligned}\n\\text{Attend}(\\mathbf{X}, \\mathcal{S}) &= \\Big( a(\\mathbf{x}_i, S_i) \\Big)_{i \\in \\{1, \\dots, L\\}} \\\\\n\\text{ where } a(\\mathbf{x}_i, S_i) &= \\text{softmax}\\Big(\\frac{(\\mathbf{x}_i \\mathbf{W}^q)(\\mathbf{x}_j \\mathbf{W}^k)_{j \\in S_i}^\\top}{\\sqrt{d_k}}\\Big) (\\mathbf{x}_j \\mathbf{W}^v)_{j \\in S_i}\n\\end{aligned}\n$$\nNote that although the size of $S_i$ is not fixed, $a(\\mathbf{x}_i, S_i)$ is always of size $d_v$ and thus $\\text{Attend}(\\mathbf{X}, \\mathcal{S}) \\in \\mathbb{R}^{L \\times d_v}$.\nIn auto-regressive models, one attention span is defined as $S_i = \\{j: j \\leq i\\}$ as it allows each token to attend to all the positions in the past.\nIn factorized self-attention, the set $S_i$ is decomposed into a\ntree\nof dependencies, such that for every pair of $(i, j)$ where $j \\leq i$, there is a path connecting $i$ back to $j$ and $i$ can attend to $j$ either directly or indirectly.\nPrecisely, the set $S_i$ is divided into $p$\nnon-overlapping\nsubsets, where the $m$-th subset is denoted as $A^{(m)}_i \\subset S_i, m = 1,\\dots, p$. Therefore the path between the output position $i$ and any $j$ has a maximum length $p + 1$. For example, if $(j, a, b, c, \\dots, i)$ is a path of indices between $i$ and $j$, we would have $j \\in A_a^{(1)}, a \\in A_b^{(2)}, b \\in A_c^{(3)}, \\dots$, so on and so forth.\nSparse Factorized Attention\nSparse Transformer proposed two types of fractorized attention. It is easier to understand the concepts as illustrated in Fig. 10 with 2D image inputs as examples.\nThe top row illustrates the attention connectivity patterns in (a) Transformer, (b) Sparse Transformer with strided attention, and (c) Sparse Transformer with fixed attention. The bottom row contains corresponding self-attention connectivity matrices. Note that the top and bottom rows are not in the same scale. (Image source:\nChild et al., 2019\n+ a few of extra annotations.)\nStrided\nattention with stride $\\ell \\sim \\sqrt{n}$. This works well with image data as the structure is aligned with strides. In the image case, each pixel would attend to all the previous $\\ell$ pixels in the raster scanning order (naturally cover the entire width of the image) and then those pixels attend to others in the same column (defined by another attention connectivity subset).\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{ t, t+1, \\dots, i\\} \\text{, where } t = \\max(0, i - \\ell) \\\\\n A_i^{(2)} &= \\{j: (i-j) \\mod \\ell = 0\\}\n \\end{aligned}\n $$\nFixed\nattention. A small set of tokens summarize previous locations and propagate that information to all future locations.\n$$\n \\begin{aligned}\n A_i^{(1)} &= \\{j: \\lfloor \\frac{j}{\\ell} \\rfloor = \\lfloor \\frac{i}{\\ell} \\rfloor \\} \\\\\n A_i^{(2)} &= \\{j: j \\mod \\ell \\in \\{\\ell-c, \\dots, \\ell-1\\} \\}\n \\end{aligned}\n $$\nwhere $c$ is a hyperparameter. If $c=1$, it restricts the representation whereas many depend on a few positions. The paper chose $c\\in \\{ 8, 16, 32 \\}$ for $\\ell \\in \\{ 128, 256 \\}$.\nUse Factorized Self-Attention in Transformer\nThere are three ways to use sparse factorized attention patterns in Transformer architecture:\nOne attention type per residual block and then interleave them,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, A^{(n \\mod p)}) \\mathbf{W}^o$, where $n$ is the index of the current residual block.\nSet up a single head which attends to locations that all the factorized heads attend to,\n$\\text{attn}(\\mathbf{X}) = \\text{Attend}(\\mathbf{X}, \\cup_{m=1}^p A^{(m)}) \\mathbf{W}^o $.\nUse a multi-head attention mechanism, but different from vanilla Transformer, each head might adopt a pattern presented above, 1 or 2. $\\rightarrow$ This option often performs the best.\nSparse Transformer also proposed a set of changes so as to train the Transformer up to hundreds of layers, including gradient checkpointing, recomputing attention & FF layers during the backward pass, mixed precision training, efficient block-sparse implementation, etc. Please check the\npaper\nfor more details or my previous post on\ntechniques for scaling up model training\n.\nBlockwise Attention\n(\nQiu et al. 2019\n) introduces a\nsparse block matrix\nto only allow each token to attend to a small set of other tokens. Each attention matrix of size $L \\times L$ is partitioned into $n \\times n$ smaller blocks of size $\\frac{L}{n}\\times\\frac{L}{n}$ and a sparse block matrix $\\mathbf{M} \\in \\{0, 1\\}^{L \\times L}$ is defined by a permutation $\\pi$ of ${1, \\dots, n}$, which records the column index per row in the block matrix.\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) &= \\text{softmax}\\Big(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{d}} \\odot \\mathbf{M}\\Big)\\mathbf{V} \\\\\n(\\mathbf{A} \\odot \\mathbf{M})_{ij} &= \\begin{cases}\nA_{ij} & \\text{if }M_{ij} = 1 \\\\\n-\\infty & \\text{if }M_{ij} = 0 \\\\\n\\end{cases} \\\\\n\\text{where } M_{ij} &= \\begin{cases}\n1 & \\text{if }\\pi\\big(\\lfloor\\frac{(i-1)n}{L} + 1\\rfloor\\big) = \\lfloor\\frac{(j-1)n}{L} + 1\\rfloor \\\\\n0 & \\text{otherwise}\n\\end{cases}\n\\end{aligned}\n$$\nThe actual implementation of Blockwise Attention only stores QKV as block matrices, each of size $n\\times n$:\n$$\n\\text{Blockwise-attn}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}, \\mathbf{M}) = \\begin{bmatrix}\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_1\\hat{\\mathbf{k}}_{\\pi(1)}^\\top}{\\sqrt{d}} \\Big)\\hat{\\mathbf{v}}_{\\pi(1)} \\\\\n\\vdots \\\\\n\\text{softmax}\\big(\\frac{\\hat{\\mathbf{q}}_n\\hat{\\mathbf{k}}_{\\pi(n)}^\\top}{\\sqrt{d}} \\odot \\Big)\\hat{\\mathbf{v}}_{\\pi(n)} \\\\\n\\end{bmatrix}\n$$\nwhere $\\hat{\\mathbf{q}}_i$, $\\hat{\\mathbf{k}}_i$ and $\\hat{\\mathbf{v}}_i$ are the $i$-the row in the QKV block matrix respectively. Each $\\mathbf{q}_i\\mathbf{k}_{\\pi(i)}^\\top, \\forall i = 1, \\dots, n$ is of size $\\frac{N}{n}\\times\\frac{N}{n}$ and therefore Blockwise Attention is able to reduce the memory complexity of attention matrix from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(\\frac{L}{n}\\times\\frac{L}{n} \\times n) = \\mathcal{O}(L^2/n)$.\nCombination of Local and Global Context\n#\nETC\n(\nExtended Transformer Construction\n;\nAinslie et al. 2019\n),\nLongformer\n(\nBeltagy et al. 2020\n) and\nBig Bird\n(\nZaheer et al. 2020\n) models combine both local and global context when building an attention matrix. All these models can be initialized from existing pretrained models.\nGlobal-Local Attention\nof\nETC\n(\nAinslie et al. 2019\n) takes two inputs, (1) the long input $\\mathbf{x}^l$ of size $n_l$ which is the regular input sequence and (2) the global input $\\mathbf{x}^g$ of size $n_g$ which contains a smaller number of auxiliary tokens, $n_g \\ll n_l$. Attention is thus split into four components based on directional attention across these two inputs: g2g, g2l, l2g and l2l. Because the l2l attention piece can be very large, it is restricted to a fixed size attention span of radius $w$ (i.e. local attention span) and the l2l matrix can be reshaped to $n_l \\times (2w+1)$.\nETC utilizes four binary matrices to handle structured inputs, $\\mathbf{M}^{g2g}$, $\\mathbf{M}^{g2l}$, $\\mathbf{M}^{l2g}$ and $\\mathbf{M}^{l2l}$. For example, each element $z^g_i \\in \\mathbb{R}^d$ in the attention output $z^g = (z^g_1, \\dots, z^g_{n_g})$ for g2g attention piece is formatted as:\n$$\n\\begin{aligned}\na^{g2g}_{ij} = \\frac{1}{\\sqrt{d}} x^g_i \\mathbf{W}^Q (x^g_j \\mathbf{W}^K + P^K_{ij})^\\top - (1- M^{g2g}_{ij})C \\\\\nA^{g2g}_{ij} = \\frac{\\exp(a^{g2g}_{ij})}{\\sum_{k=1}^{n_g} \\exp(a^{g2g}_{ik})} \\quad\nz^g_i = \\sum^{n_g}_{j=1} A^{g2g}_{ij} x^g_j \\mathbf{W}^V\n\\end{aligned}\n$$\nwhere $P^K_{ij}$ is a learnable vector for relative position encoding and $C$ is a very large constant ($C=10000$ in the paper) to offset any attention weights when mask is off.\nAttention patterns of ETC, Longformer and Big Bird.\nOne more update in ETC is to incorporate a CPC (contrastive predictive coding) task using\nNCE loss\ninto the pretraining stage, besides the\nMLM\ntask: The representation of one sentence should be similar to the representation of context around it when this sentence is masked.\nThe global input $\\mathbf{x}^g$ for ETC is constructed as follows: Assuming there are some segments within the long inputs (e.g. by sentence), each segment is attached with one auxiliary token to learn global inputs.\nRelative position encoding\nis used to mark the global segment tokens with the token position. Hard masking in one direction (i.e., tokens before vs after are labeled differently) is found to bring performance gains in some datasets.\nAttention pattern in Longformer contains three components:\nLocal attention\n: Similar to ETC, local attention is controlled by a sliding window of fixed size $w$;\nGlobal attention of preselected tokens\n: Longformer has a few pre-selected tokens (e.g.\n[CLS]\ntoken) assigned with global attention span, that is, attending to all other tokens in the input sequence.\nDilated attention\n: Dilated sliding window of fixed size $r$ and gaps of dilation size $d$, similar to Sparse Transformer;\nBig Bird\nis quite similar to Longformer, equipped with both local attention and a few preselected tokens with global attention span, but Big Bird replaces dilated attention with a new mechanism where all tokens attend to a set of random tokens. The design is motivated by the fact that attention pattern can be viewed as a\ndirected graph\nand a\nrandom graph\nhas the property that information is able to rapidly flow between any pair of nodes.\nLongformer\nuses smaller window size at lower layers and larger window sizes at higher layers. Ablation studies showed that this setup works better than reversed or fixed size config. Lower layers do not have dilated sliding windows to better learn to use immediate local context. Longformer also has a staged training procedure where initially the model is trained with small window size to learn from local context and then subsequent stages of training have window sizes increased and learning rate decreased.\nContent-based Attention\n#\nThe improvements proposed by\nReformer\n(\nKitaev, et al. 2020\n) aim to solve the following pain points in vanilla Transformer:\nQuadratic time and memory complexity within self-attention module.\nMemory in a model with $N$ layers is $N$-times larger than in a single-layer model because we need to store activations for back-propagation.\nThe intermediate FF layers are often quite large.\nReformer proposed two main changes:\nReplace the dot-product attention with\nlocality-sensitive hashing (LSH) attention\n, reducing the complexity from $\\mathcal{O}(L^2)$ to $\\mathcal{O}(L\\log L)$.\nReplace the standard residual blocks with\nreversible residual layers\n, which allows storing activations only once during training instead of $N$ times (i.e. proportional to the number of layers).\nLocality-Sensitive Hashing Attention\nIn $\\mathbf{Q} \\mathbf{K}^\\top$ part of the\nattention formula\n, we are only interested in the largest elements as only large elements contribute a lot after softmax. For each query $\\mathbf{q}_i \\in \\mathbf{Q}$, we are looking for row vectors in $\\mathbf{K}$ closest to $\\mathbf{q}_i$. In order to find nearest neighbors quickly in high-dimensional space, Reformer incorporates\nLocality-Sensitive Hashing (LSH)\ninto its attention mechanism.\nA hashing scheme $x \\mapsto h(x)$ is\nlocality-sensitive\nif it preserves the distancing information between data points, such that close vectors obtain similar hashes while distant vectors have very different ones. The Reformer adopts a hashing scheme as such, given a fixed random matrix $\\mathbf{R} \\in \\mathbb{R}^{d \\times b/2}$ (where $b$ is a hyperparam), the hash function is $h(x) = \\arg\\max([xR; −xR])$.\nIllustration of Locality-Sensitive Hashing (LSH) attention. (Image source: right part of Figure 1 in\nKitaev, et al. 2020\n).\nIn LSH attention, a query can only attend to positions in the same hashing bucket, $S_i = \\{j: h(\\mathbf{q}_i) = h(\\mathbf{k}_j)\\}$. It is carried out in the following process, as illustrated in Fig. 20:\n(a) The attention matrix for full attention is often sparse.\n(b) Using LSH, we can sort the keys and queries to be aligned according to their hash buckets.\n(c) Set $\\mathbf{Q} = \\mathbf{K}$ (precisely $\\mathbf{k}_j = \\mathbf{q}_j / |\\mathbf{q}_j|$), so that there are equal numbers of keys and queries in one bucket, easier for batching. Interestingly, this “shared-QK” config does not affect the performance of the Transformer.\n(d) Apply batching where chunks of $m$ consecutive queries are grouped together.\nThe LSH attention consists of 4 steps: bucketing, sorting, chunking, and attention computation. (Image source: left part of Figure 1 in\nKitaev, et al. 2020\n).\nReversible Residual Network\nAnother improvement by Reformer is to use\nreversible residual layers\n(\nGomez et al. 2017\n). The motivation for reversible residual network is to design the architecture in a way that activations at any given layer can be recovered from the activations at the following layer, using only the model parameters. Hence, we can save memory by recomputing the activation during backprop rather than storing all the activations.\nGiven a layer $x \\mapsto y$, the normal residual layer does $y = x + F(x)$, but the reversible layer splits both input and output into pairs $(x_1, x_2) \\mapsto (y_1, y_2)$ and then executes the following:\n$$\ny_1 = x_1 + F(x_2),\\; y_2 = x_2 + G(y_1) \n$$\nand reversing is easy:\n$$\nx_2 = y_2 - G(y_1), \\; x_1 = y_1 − F(x_2)\n$$\nReformer applies the same idea to Transformer by combination attention ($F$) and feed-forward layers ($G$) within a reversible net block:\n$$\nY_1 = X_1 + \\text{Attention}(X_2), \\; Y_2 = X_2 + \\text{FeedForward}(Y_1)\n$$\nThe memory can be further reduced by chunking the feed-forward computation:\n$$\nY_2 = [Y_2^{(1)}; \\dots; Y_2^{(c)}] = [X_2^{(1)} + \\text{FeedForward}(Y_1^{(1)}); \\dots; X_2^{(c)} + \\text{FeedForward}(Y_1^{(c)})]\n$$\nThe resulting reversible Transformer does not need to store activation in every layer.\nRouting Transformer\n(\nRoy et al. 2021\n) is also built on content-based clustering of keys and queries. Instead of using a static hashing function like LSH, it utilizes online $k$-means clustering and combines it with local, temporal sparse attention to reduce the attention complexity from $O(L^2)$ to $O(L^{1.5})$.\nWithin routing attention, both keys and queries are clustered with $k$-means clustering method and the same set of centroids $\\boldsymbol{\\mu} = (\\mu_1, \\dots, \\mu_k) \\in \\mathbb{R}^{k \\times d}$. Queries are routed to keys that get assigned to the same centroid. The total complexity is $O(Lkd + L^2d/k)$, where $O(Lkd)$ is for running clustering assignments and $O(L^2d/k)$ is for attention computation. The cluster centroids are updated by EMA (exponential moving average) using all associated keys and queries.\nIn the experiments for Routing Transformer, some best config only has routing attention enabled in the last two layers of the model and half of the attention heads, while the other half utilizing local attention. They also observed that local attention is a pretty strong baseline and larger attention window always leads to better results.\nLow-Rank Attention\n#\nLinformer\n(\nWang et al. 2020\n) approximates the full attention matrix with a\nlow rank\nmatrix, reducing the time & space complexity to be\nlinear\n. Instead of using expensive SVD to identify low rank decomposition, Linformer adds two linear projections $\\mathbf{E}_i, \\mathbf{F}_i \\in \\mathbb{R}^{L \\times k}$ for key and value matrices, respectively, reducing their dimensions from $L \\times d$ to $k \\times d$. As long as $k \\ll L$, the attention memory can be greatly reduced.\n$$\n\\begin{aligned}\n\\overline{\\text{head}}_i \n&= \\text{attn}(\\mathbf{X}_q\\mathbf{W}^q_i, \\mathbf{E}_i\\mathbf{X}_k\\mathbf{W}^k_i, \\mathbf{F}_i\\mathbf{X}_v\\mathbf{W}^v_i) \\\\\n&= \\underbrace{\\text{softmax}\\Big( \\frac{\\mathbf{X}_q\\mathbf{W}^q_i (\\mathbf{E}_i \\mathbf{X}_k\\mathbf{W}^k_i)^\\top}{\\sqrt{d}} \\Big)}_{\\text{low rank attention matrix }\\bar{A} \\in \\mathbb{R}^{k \\times d}} \\mathbf{F}_i \\mathbf{X}_v\\mathbf{W}^v_i\n\\end{aligned}\n$$\nAdditional techniques can be applied to further improve efficiency of Linformer:\nParameter sharing between projection layers, such as head-wise, key-value  and layer-wise (across all layers) sharing.\nUse different $k$ at different layers, as heads in higher layers tend to have a more skewed distribution (lower rank) and thus we can use smaller $k$ at higher layers.\nUse different types of projections; e.g. mean/max pooling, convolution layer with kernel and stride $L/k$.\n(Left) Informer has two projection layers added for keys and values. (Right) Plot of inference time as a function of sequence length. (Image source:\nWang et al. 2020\n).\nRandom Feature Attention\n(\nRFA\n;\nPeng et al. 2021\n) relies on\nrandom feature methods\n(\nRahimi & Recht, 2007\n) to approximate softmax operation in self-attention with low rank feature maps in order to achieve linear time and space complexity.\nPerformers\n(\nChoromanski et al. 2021\n) also adopts random feature attention with improvements on the kernel construction to further reduce the kernel approximation error.\nThe main theorem behind RFA is from\nRahimi & Recht, 2007\n:\nLet $\\phi: \\mathbb{R}^d \\to \\mathbb{R}^{2D}$ be a nonlinear transformation:\n$$\n\\phi(\\mathbf{x}) = \\frac{1}{\\sqrt{D}}[\\sin(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\sin(\\mathbf{w}_D^\\top \\mathbf{x}), \\cos(\\mathbf{w}_1^\\top \\mathbf{x}), \\dots, \\cos(\\mathbf{w}_D^\\top \\mathbf{x})]^\\top\n$$\nWhen $d$-dimensional random vectors $\\mathbf{w}_i$ are i.i.d. from $\\mathcal{N}(\\mathbf{0}, \\sigma^2\\mathbf{I}_d)$,\n$$\n\\mathbb{E}_{\\mathbf{w}_i} [\\phi(\\mathbf{x}) \\cdot \\phi(\\mathbf{y})] = \\exp(-\\frac{\\| \\mathbf{x} - \\mathbf{y} \\|^2}{2\\sigma^2})\n$$\nAn unbiased estimation of $\\exp(\\mathbf{x} \\cdot \\mathbf{y})$ is:\n$$\n\\begin{aligned}\n\\exp(\\mathbf{x} \\cdot \\mathbf{y} / \\sigma^2) \n&= \\exp(\\frac{1}{2\\sigma^2}(\\|\\mathbf{x}\\|^2 + \\|\\mathbf{y}\\|^2 - \\|\\mathbf{x} - \\mathbf{y}\\|^2) \\\\\n&= \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2}) ( - \\frac{\\|\\mathbf{x} - \\mathbf{y}\\|^2}{2\\sigma^2}) \\\\\n&\\approx \\exp(\\frac{\\|\\mathbf{x}\\|^2}{2\\sigma^2}) \\exp(\\frac{\\|\\mathbf{y}\\|^2}{2\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) \\\\\n&= \\exp(\\frac{1}{\\sigma^2})\\;\\phi(\\mathbf{x})\\cdot\\phi(\\mathbf{y}) & \\text{; unit vectors}\n\\end{aligned}\n$$\nThen we can write the attention function as follows, where $\\otimes$ is outer product operation and $\\sigma^2$ is the temperature:\n$$\n\\begin{aligned}\n\\text{attn}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\}) \n&= \\sum_i \\frac{\\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_i/\\sigma^2)}{\\sum_j \\exp(\\mathbf{q}_t\\cdot\\mathbf{k}_j/\\sigma^2)}\\mathbf{v}_i^\\top\n\\approx \\sum_i \\frac{\\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_i)\\mathbf{v}_i^\\top}{\\sum_j \\phi(\\mathbf{q}_t)\\phi(\\mathbf{k}_j)} \\\\\n&= \\color{green}{\\frac{\\phi(\\mathbf{q}_t)^\\top \\sum_i \\phi(\\mathbf{k}_i)\\otimes\\mathbf{v}_i}{\\phi(\\mathbf{q}_t)^\\top \\sum_j \\phi(\\mathbf{k}_j)}\n= \\text{RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}, \\{\\mathbf{v}_i\\})}\n\\end{aligned}\n$$\n(Left) The order of computation for default softmax operation. (Right) The order of computation when using random feature attention, a lot cheaper than default softmax. (Image source:\nPeng et al. 2021\n).\nCausal Attention RFA\nhas token at time step $t$ only attend to earlier keys and values $\\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}$. Let us use a tuple of variables, $(\\mathbf{S}_t \\in \\mathbb{R}^{2D \\times d}, \\mathbf{z} \\in \\mathbb{R}^{2D})$, to track the hidden state history at time step $t$, similar to RNNs:\n$$\n\\begin{aligned}\n&\\text{causal-RFA}(\\mathbf{q}_t, \\{\\mathbf{k}_i\\}_{i \\leq t}, \\{\\mathbf{v}_i\\}_{i \\leq t}) = \\frac{\\phi(\\mathbf{q}_t)^\\top \\mathbf{S}_t}{\\phi(\\mathbf{q}_t) \\cdot \\mathbf{z}_t} \\\\\n&\\text{where } \n\\mathbf{S}_t = \\mathbf{S}_{t-1} + \\phi(\\mathbf{k}_t)\\otimes\\mathbf{v}_t,\n\\quad \n\\mathbf{z}_t = \\mathbf{z}_{t-1} + \\phi(\\mathbf{k}_t)\n\\end{aligned}\n$$\nwhere $2D$ is the size of $\\phi(.)$ and $D$ should be no less than the model size $d$ for reasonable approximation.\nRFA leads to significant speedup in autoregressive decoding and the memory complexity mainly depends on the choice of $D$ when constructing the kernel $\\phi(.)$.\nPerformer modifies the random feature attention with positive random feature maps to reduce the estimation error. It also keeps the randomly sampled $\\mathbf{w}_1, \\dots, \\mathbf{w}_D$ to be orthogonal to further reduce the variance of the estimator.\nComparison of approximation error when using (Left) i.i.d vs orthogonal features and (Right) sin/cos vs positive random features. (Image source:\nChoromanski et al. 2021\n).\nTransformers for Reinforcement Learning\n#\nThe self-attention mechanism avoids compressing the whole past into a fixed-size hidden state and does not suffer from vanishing or exploding gradients as much as RNNs. Reinforcement Learning tasks can for sure benefit from these traits.\nHowever\n, it is quite difficult to train Transformer even in supervised learning, let alone in the RL context. It could be quite challenging to stabilize and train a LSTM agent by itself, after all.\nThe\nGated Transformer-XL\n(\nGTrXL\n;\nParisotto, et al. 2019\n) is one attempt to use Transformer for RL. GTrXL succeeded in stabilizing training with two changes on top of\nTransformer-XL\n:\nThe layer normalization is only applied on the input stream in a residual module, but NOT on the shortcut stream. A key benefit to this reordering is to allow the original input to flow from the first to last layer.\nThe residual connection is replaced with a GRU-style (Gated Recurrent Unit;\nChung et al., 2014\n)\ngating\nmechanism.\n$$\n\\begin{aligned}\nr &= \\sigma(W_r^{(l)} y + U_r^{(l)} x) \\\\\nz &= \\sigma(W_z^{(l)} y + U_z^{(l)} x - b_g^{(l)}) \\\\\n\\hat{h} &= \\tanh(W_g^{(l)} y + U_g^{(l)} (r \\odot x)) \\\\\ng^{(l)}(x, y) &= (1-z)\\odot x + z\\odot \\hat{h}\n\\end{aligned}\n$$\nThe gating function parameters are explicitly initialized to be close to an identity map - this is why there is a $b_g$ term. A $b_g > 0$ greatly helps with the learning speedup.\nComparison of the model architecture of Transformer-XL, Transformer-XL with the layer norm reordered, and Gated Transformer-XL. (Image source: Figure 1 in\nParisotto, et al. 2019\n)\nDecision Transformer\n(\nDT\n;\nChen et al 2021\n) formulates Reinforcement Learning problems as a process of\nconditional sequence modeling\n, outputting the optimal actions conditioned on the desired return, past states and actions. It therefore becomes straightforward to use Transformer architecture. Decision Transformer is for\noff-policy RL\n, where the model only has access to a fixed collection of trajectories collected by other policies.\nTo encourage the model to learn how to act in order to achieve a desired return, it feeds the model with desired future return $\\hat{R} = \\sum_{t’=t}^T r_{t’}$ instead of the current reward. The trajectory consists of a list of triplets, (return-to-go $\\hat{R}_t, state $s_t$, action $a_t$), and it is used as an input sequence for Transformer:\n$$\n\\tau = (\\hat{R}_1, s_1, a_1, \\hat{R}_2, s_2, a_2, \\dots, \\hat{R}_T, s_T, a_T)\n$$\nThree linear layers are added and trained for return-to-go, state and action respectively to extract token embeddings. The prediction head learns to predict $a_t$ corresponding to the input token $s_t$. The training uses cross-entropy loss for discrete actions or MSE for continuous actions. Predicting the states or return-to-go was not found to help improve the performance in their experiments.\nThe experiments compared DT with several model-free RL algorithm baselines and showed that:\nDT is more efficient than behavior cloning in low data regime;\nDT can model the distribution of returns very well;\nHaving a long context is crucial for obtaining good results;\nDT can work with sparse rewards.\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2023). The transformer family version 2.0. Lil’Log. https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/.\nOr\n@article{weng2023transformer,\n  title   = \"The Transformer Family Version 2.0\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2023\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/\"\n}\nReferences\n#\n[1] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[2] Rami Al-Rfou, et al.\n“Character-level language modeling with deeper self-attention.”\nAAAI 2019.\n[3] Olah & Carter,\n“Attention and Augmented Recurrent Neural Networks”\n, Distill, 2016.\n[4] Sainbayar Sukhbaatar, et al.\n“Adaptive Attention Span in Transformers”\n. ACL 2019.\n[5] Rewon Child, et al.\n“Generating Long Sequences with Sparse Transformers”\narXiv:1904.10509 (2019).\n[6] Nikita Kitaev, et al.\n“Reformer: The Efficient Transformer”\nICLR 2020.\n[7] Alex Graves. (“Adaptive Computation Time for Recurrent Neural Networks”)[https://arxiv.org/abs/1603.08983]\n[8] Niki Parmar, et al.\n“Image Transformer”\nICML 2018.\n[9] Zihang Dai, et al.\n“Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.”\nACL 2019.\n[10] Aidan N. Gomez, et al.\n“The Reversible Residual Network: Backpropagation Without Storing Activations”\nNIPS 2017.\n[11] Mostafa Dehghani, et al.\n“Universal Transformers”\nICLR 2019.\n[12] Emilio Parisotto, et al.\n“Stabilizing Transformers for Reinforcement Learning”\narXiv:1910.06764 (2019).\n[13] Rae et al.\n“Compressive Transformers for Long-Range Sequence Modelling.”\n2019.\n[14] Press et al.\n“Train Short, Test Long: Attention With Linear Biases Enables Input Length Extrapolation.”\nICLR 2022.\n[15] Wu, et al.\n“DA-Transformer: Distance Aware Transformer”\n2021.\n[16] Elabyad et al.\n“Depth-Adaptive Transformer.”\nICLR 2020.\n[17] Schuster et al.\n“Confident Adaptive Language Modeling”\n2022.\n[18] Qiu et al.\n“Blockwise self-attention for long document understanding”\n2019\n[19] Roy et al.\n“Efficient Content-Based Sparse Attention with Routing Transformers.”\n2021.\n[20] Ainslie et al.\n“ETC: Encoding Long and Structured Inputs in Transformers.”\nEMNLP 2019.\n[21] Beltagy et al.\n“Longformer: The long-document transformer.”\n2020.\n[22] Zaheer et al.\n“Big Bird: Transformers for Longer Sequences.”\n2020.\n[23] Wang et al.\n“Linformer: Self-Attention with Linear Complexity.”\narXiv preprint arXiv:2006.04768 (2020).\n[24] Tay et al. 2020\n“Sparse Sinkhorn Attention.”\nICML 2020.\n[25] Peng et al.\n“Random Feature Attention.”\nICLR 2021.\n[26] Choromanski et al.\n“Rethinking Attention with Performers.”\nICLR 2021.\n[27] Khandelwal et al.\n“Generalization through memorization: Nearest neighbor language models.”\nICLR 2020.\n[28] Yogatama et al.\n“Adaptive semiparametric language models.”\nACL 2021.\n[29] Wu et al.\n“Memorizing Transformers.”\nICLR 2022.\n[30] Su et al.\n“Roformer: Enhanced transformer with rotary position embedding.”\narXiv preprint arXiv:2104.09864 (2021).\n[31] Shaw et al.\n“Self-attention with relative position representations.”\narXiv preprint arXiv:1803.02155 (2018).\n[32] Tay et al.\n“Efficient Transformers: A Survey.”\nACM Computing Surveys 55.6 (2022): 1-28.\n[33] Chen et al.,\n“Decision Transformer: Reinforcement Learning via Sequence Modeling”\narXiv preprint arXiv:2106.01345 (2021).",
            "metadata": {
              "title": "The Transformer Family Version 2.0 | Lil'Log",
              "description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "keywords": "architecture, attention, transformer, foundation, long-read, reinforcement-learning",
              "author": "Lilian Weng",
              "og:title": "The Transformer Family Version 2.0",
              "og:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
              "twitter:card": "summary",
              "twitter:title": "The Transformer Family Version 2.0",
              "twitter:description": "Many new Transformer architecture improvements have been proposed since my last post on “The Transformer Family” about three years ago. Here I did a big refactoring and enrichment of that 2020 post — restructure the hierarchy of sections and improve many sections with more recent papers. Version 2.0 is a superset of the old version, about twice the length.\nNotations\n\n\t\n\t\t\t\n\t\t\t\t\tSymbol\n\t\t\t\t\tMeaning\n\t\t\t\n\t\n\t\n\t\t\t\n\t\t\t\t\t$d$\n\t\t\t\t\tThe model size / hidden state dimension / positional encoding size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$h$\n\t\t\t\t\tThe number of heads in multi-head attention layer.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$L$\n\t\t\t\t\tThe segment length of input sequence.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$N$\n\t\t\t\t\tThe total number of attention layers in the model; not considering MoE.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{X} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tThe input sequence where each element has been mapped into an embedding vector of shape $d$, same as the model size.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe key weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^q \\in \\mathbb{R}^{d \\times d_k}$\n\t\t\t\t\tThe query weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^v \\in \\mathbb{R}^{d \\times d_v}$\n\t\t\t\t\tThe value weight matrix. Often we have $d_k = d_v = d$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^k_i, \\mathbf{W}^q_i \\in \\mathbb{R}^{d \\times d_k/h}; \\mathbf{W}^v_i \\in \\mathbb{R}^{d \\times d_v/h}$\n\t\t\t\t\tThe weight matrices per head.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{W}^o \\in \\mathbb{R}^{d_v \\times d}$\n\t\t\t\t\tThe output weight matrix.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}^q \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe query embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{K} = \\mathbf{X}\\mathbf{W}^k \\in \\mathbb{R}^{L \\times d_k}$\n\t\t\t\t\tThe key embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{V} = \\mathbf{X}\\mathbf{W}^v \\in \\mathbb{R}^{L \\times d_v}$\n\t\t\t\t\tThe value embedding inputs.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{q}_i, \\mathbf{k}_i \\in \\mathbb{R}^{d_k}, \\mathbf{v}_i \\in \\mathbb{R}^{d_v}$\n\t\t\t\t\tRow vectors in query, key, value matrices, $\\mathbf{Q}$, $\\mathbf{K}$ and $\\mathbf{V}$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$S_i$\n\t\t\t\t\tA collection of key positions for the $i$-th query $\\mathbf{q}_i$ to attend to.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{A} \\in \\mathbb{R}^{L \\times L}$\n\t\t\t\t\tThe self-attention matrix between a input sequence of lenght $L$ and itself. $\\mathbf{A} = \\text{softmax}(\\mathbf{Q}\\mathbf{K}^\\top / \\sqrt{d_k})$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$a_{ij} \\in \\mathbf{A}$\n\t\t\t\t\tThe scalar attention score between query $\\mathbf{q}_i$ and key $\\mathbf{k}_j$.\n\t\t\t\n\t\t\t\n\t\t\t\t\t$\\mathbf{P} \\in \\mathbb{R}^{L \\times d}$\n\t\t\t\t\tposition encoding matrix, where the $i$-th row $\\mathbf{p}_i$ is the positional encoding for input $\\mathbf{x}_i$.\n\t\t\t\n\t\n\nTransformer Basics\nThe Transformer (which will be referred to as “vanilla Transformer” to distinguish it from other enhanced versions; Vaswani, et al., 2017) model has an encoder-decoder architecture, as commonly used in many NMT models. Later simplified Transformer was shown to achieve great performance in language modeling tasks, like in encoder-only BERT or decoder-only GPT.",
              "article:section": "posts",
              "article:published_time": "2023-01-27T00:00:00+00:00",
              "article:modified_time": "2023-01-27T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/bd2a1c61491f/code/body-000.txt",
                "chars": 272,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-cfd86d1d041d4e587dd2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-57e8505d379090b6a5c2.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "bytes": 66540,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-eb72333120a9bf61db22.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sinoidual-positional-encoding.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "bytes": 517373,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-94806f3485ee4c7d4137.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RoPE.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "bytes": 420355,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-10c3f7a4432b939f41e9.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/transformer-XL-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "bytes": 110695,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9af813630ff27b91e9f8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "bytes": 104844,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-2d52fb35835b8ffb9f5c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/compressive-transformer-memory.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "bytes": 441748,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-b512db56c30433d4c252.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/SPALM2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "bytes": 81702,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-701853184c4d260333df.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/memorizing-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "bytes": 75150,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-440b77c01199a8fa47a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-bias.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "bytes": 308982,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-321a0b363e9a6d1aa98b.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ALiBi-exp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "bytes": 136227,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-65f1b4ee283f16066c80.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer-loop.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "bytes": 118602,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f6d1acbfbe9a2ebc5720.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/universal-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "bytes": 128314,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-6801941ec960782dbcdd.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/attention-per-head.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "bytes": 49638,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-aa7a4901bbb57ffba3a8.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/soft-masking-function.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "bytes": 144593,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-61300c84161edec245ef.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/depth-adaptive-classifier.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "bytes": 92635,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-e33cbf677e130ee48f58.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/image-transformer-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "bytes": 244624,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-f5d3b8b9ebc8beb78c77.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/sparse-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "bytes": 135708,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-30a7b1c7f2d502623782.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/combined-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "bytes": 181556,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-528e7d446bed9aeb5917.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention-matrix.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "bytes": 306995,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-08fa8454100a632db05c.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/LSH-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "bytes": 296726,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-5fade868b98da3fc740e.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/linformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "bytes": 150541,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-1864a0421abec41db939.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/RFA.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "bytes": 300912,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-9bbffc5733b6530c7240.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/performer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "bytes": 278596,
                "reused": false,
                "local_path": "attachments/bd2a1c61491f/images/body-8ed5854240a34aa93f46.png",
                "src": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/gated-transformer-XL.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "“The Transformer Family”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1706.03762",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-06-24-attention/",
                "label": "NMT",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "BERT",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Non-local_means",
                "label": "non-local means",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.03122",
                "label": "Gehring, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1808.04444",
                "label": "Al-Rfou et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1803.02155",
                "label": "Shaw et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.02860",
                "label": "Dai et al., 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.09864",
                "label": "Su et al. 2021",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Rotation_matrix",
                "label": "rotation matrix",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.05507",
                "label": "Rae et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.00172",
                "label": "Khandelwal et al. 2020",
                "type": "a"
              },
              {
                "href": "https://github.com/facebookresearch/faiss",
                "label": "FAISS",
                "type": "a"
              },
              {
                "href": "https://github.com/google-research/google-research/tree/master/scann",
                "label": "ScaNN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2102.02557",
                "label": "Yogatama et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2203.08913",
                "label": "Wu et al. 2022",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2021.naacl-main.166",
                "label": "Wu, et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2108.12409",
                "label": "Press et al. 2022",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1807.03819",
                "label": "Dehghani, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.02357",
                "label": "separable convolution",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1905.07799",
                "label": "Sukhbaatar et al (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.10073",
                "label": "Elabyad et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2207.07061",
                "label": "Schuster et al. 2022",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Dirac_delta_function",
                "label": "dirac delta",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2110.01052",
                "label": "Angelopoulos et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.06732",
                "label": "Tay et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.05751",
                "label": "Parmer, et al 2018",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Raster_scan",
                "label": "raster scanning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1904.10509",
                "label": "Child et al., 2019",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
                "label": "techniques for scaling up model training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.02972",
                "label": "Qiu et al. 2019",
                "type": "a"
              },
              {
                "href": "https://aclanthology.org/2020.emnlp-main.19/",
                "label": "Ainslie et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2004/05150",
                "label": "Beltagy et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2007.14062",
                "label": "Zaheer et al. 2020",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2021-05-31-contrastive/",
                "label": "NCE loss",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_graph",
                "label": "directed graph",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Random_graph",
                "label": "random graph",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2001.04451",
                "label": "Kitaev, et al. 2020",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Locality-sensitive_hashing",
                "label": "Locality-Sensitive Hashing (LSH)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.04585",
                "label": "Gomez et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2003.05997",
                "label": "Roy et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.04768",
                "label": "Wang et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2103.02143",
                "label": "Peng et al. 2021",
                "type": "a"
              },
              {
                "href": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "label": "Rahimi & Recht, 2007",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2009.14794",
                "label": "Choromanski et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.06764",
                "label": "Parisotto, et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1412.3555",
                "label": "Chung et al., 2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2106.01345",
                "label": "Chen et al 2021",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "off-policy RL",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "“Attention is all you need.”",
                "type": "a"
              },
              {
                "href": "http://doi.org/10.23915/disti",
                "label": "“Attention and Augmented Recurrent Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2002.11296",
                "label": "“Sparse Sinkhorn Attention.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:12Z",
            "source_url": "https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1706.03762",
                "bytes": 2215244,
                "reused": true,
                "local_path": "papers/repair/c3ab01e47e614fe3cf33.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.03122",
                "bytes": 573311,
                "reused": false,
                "local_path": "papers/repair/758d2db10bbacb1a4049.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1808.04444",
                "bytes": 726375,
                "reused": false,
                "local_path": "papers/repair/f7a4eccd97bbfdf62ee3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1803.02155",
                "bytes": 235373,
                "reused": false,
                "local_path": "papers/repair/f32df5aeac8714d373be.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.02860",
                "bytes": 4570910,
                "reused": false,
                "local_path": "papers/repair/8514ec65c2953ee68ccf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.09864",
                "bytes": 599289,
                "reused": true,
                "local_path": "papers/repair/b64aa8c5e278403b64ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.05507",
                "bytes": 584093,
                "reused": false,
                "local_path": "papers/repair/244ccad8664efd18e77c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.00172",
                "bytes": 451453,
                "reused": false,
                "local_path": "papers/repair/43f160fbf0fa81d77393.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2102.02557",
                "bytes": 1018474,
                "reused": false,
                "local_path": "papers/repair/b5c9e91bd79c1b9ef250.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2203.08913",
                "bytes": 1047591,
                "reused": false,
                "local_path": "papers/repair/691204beb9e3b5b17a09.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2108.12409",
                "bytes": 759030,
                "reused": true,
                "local_path": "papers/repair/238b286ab4f338940590.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1807.03819",
                "bytes": 2371799,
                "reused": false,
                "local_path": "papers/repair/933b1c22c5c54fb670e9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.02357",
                "bytes": 804466,
                "reused": false,
                "local_path": "papers/repair/9aca5987caa4ba692507.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1905.07799",
                "bytes": 381620,
                "reused": false,
                "local_path": "papers/repair/71b8a5bd387ec43c94cc.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.10073",
                "bytes": 480824,
                "reused": false,
                "local_path": "papers/repair/929832372275e4ca6acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2207.07061",
                "bytes": 3006455,
                "reused": false,
                "local_path": "papers/repair/3e493b8dcc10d3f89436.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2110.01052",
                "bytes": 2934353,
                "reused": false,
                "local_path": "papers/repair/f48952de2c7830ad0fc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.06732",
                "bytes": 847824,
                "reused": true,
                "local_path": "papers/repair/5442c18a5d3ec7c8eca5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.05751",
                "bytes": 1108088,
                "reused": false,
                "local_path": "papers/repair/e71a6184638a873330d8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1904.10509",
                "bytes": 4436935,
                "reused": false,
                "local_path": "papers/repair/b20b3e8f92bfa6d99c9d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.02972",
                "bytes": 716586,
                "reused": false,
                "local_path": "papers/repair/e8d64283562a841b64f9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/2004/05150",
                "retried_at": "2026-10-20T18:03:23Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2007.14062",
                "bytes": 1153823,
                "reused": false,
                "local_path": "papers/repair/f56d7d4a1317893ab3ad.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2001.04451",
                "bytes": 658515,
                "reused": false,
                "local_path": "papers/repair/362c024f67418a537ddf.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.04585",
                "bytes": 543235,
                "reused": false,
                "local_path": "papers/repair/5416fd20cbe5674f95d1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2003.05997",
                "bytes": 727287,
                "reused": false,
                "local_path": "papers/repair/d2f0607b565e49aa10fe.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.04768",
                "bytes": 922879,
                "reused": false,
                "local_path": "papers/repair/f20cd0da3a7534f96d1a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2103.02143",
                "bytes": 1241988,
                "reused": false,
                "local_path": "papers/repair/e438f2e0a286bcd79311.pdf"
              },
              {
                "status": "ok",
                "url": "https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf",
                "bytes": 488453,
                "reused": false,
                "local_path": "papers/repair/38e94b7d3685dc5b22d9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2009.14794",
                "bytes": 5880177,
                "reused": true,
                "local_path": "papers/repair/26948568ccf004004970.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.06764",
                "bytes": 2179274,
                "reused": false,
                "local_path": "papers/repair/51f85523d9bf32a25ab8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1412.3555",
                "bytes": 683896,
                "reused": false,
                "local_path": "papers/repair/50678b2017a71df661ae.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2106.01345",
                "bytes": 704784,
                "reused": false,
                "local_path": "papers/repair/9e056437cb3e5b4f695d.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": false,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2002.11296",
                "bytes": 450138,
                "reused": true,
                "local_path": "papers/repair/0008d87e3417535c824a.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 68430,
            "expected_body_images": 25,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/bd2a1c61491f/pages/source.html",
            "local_html": "attachments/bd2a1c61491f/pages/article.html",
            "body_base_path": "attachments/bd2a1c61491f/pages/",
            "body_markdown_path": "attachments/bd2a1c61491f/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
          "status": "partial",
          "article_id": "1c9291c74af3",
          "local_path": "series-follow/1601/repair/7ed03d41ab2c6b4d9091.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
              "bytes": 2159899,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/8571ab535bf08b3eb897.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
              "bytes": 36779,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/244663c064863ba3add1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
              "bytes": 163006,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/417a080a721a8da35e76.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
              "bytes": 360658,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7a8e772d26ca2075d030.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
              "bytes": 329846,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a79121328d38f1e7decb.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
              "bytes": 1061108,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/217a917d5b695d69920e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
              "bytes": 3290656,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/16ff0e0557cd1ec7183b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
              "bytes": 190907,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/68ed274d29e23ec04058.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
              "bytes": 20601,
              "reused": false,
              "content_type": "image/jpeg",
              "local_path": "series-follow/1601/repair/assets/f7ff47f8ed0c85c31c04.jpg"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
              "bytes": 194344,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d885b9f00fc903916eff.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
              "bytes": 236994,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/43b2947b31f475b9d117.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
              "bytes": 476899,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/202d6793b7b96d2f655a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
              "bytes": 401199,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/47a02b382f80dc9a2137.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
              "bytes": 106503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d314a0ab86b5abc9e45b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
              "bytes": 136297,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5bee749c4008d551aef3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
              "bytes": 198560,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9686a8baee36d438f09c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
              "bytes": 376109,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7cfc826648a35a656e03.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
              "bytes": 485628,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4f9fa106ff81362212ba.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
              "bytes": 124592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3442cdcfc8a317d5e9cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
              "bytes": 392406,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d18eeaedd090128a06bf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
              "bytes": 3409897,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/82aaa856d170c7aa0cea.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Attention? Attention!",
            "keywords": "注意力机制,自注意力,多头",
            "domain": "大模型算法",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "publish_date": "2018-06",
            "corpus_stage": "预训练/SFT",
            "notes": "注意力机制经典综述",
            "id": "1c9291c74af3",
            "collected_at": "2026-10-02T14:13:17",
            "title": "Attention? Attention! | Lil'Log",
            "body_markdown": "[Updated on 2018-10-28: Add\nPointer Network\nand the\nlink\nto my implementation of Transformer.]\n[Updated on 2018-11-06: Add a\nlink\nto the implementation of Transformer model.]\n[Updated on 2018-11-18: Add\nNeural Turing Machines\n.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the\nshow-attention-tell\npaper; moved it to\nSelf-Attention\nsection.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is\nhere\n.]\nAttention is, to some extent, motivated by how we pay visual attention to different regions of an image or correlate words in one sentence. Take the picture of a Shiba Inu in Fig. 1 as an example.\nA Shiba Inu in a men’s outfit. The credit of the original photo goes to Instagram\n@mensweardog\n.\nHuman visual attention allows us to focus on a certain region with “high resolution” (i.e. look at the pointy ear in the yellow box) while perceiving the surrounding image in “low resolution” (i.e. now how about the snowy background and the outfit?), and then adjust the focal point or do the inference accordingly. Given a small patch of an image, pixels in the rest provide clues what should be displayed there. We expect to see a pointy ear in the yellow box because we have seen a dog’s nose, another pointy ear on the right, and Shiba’s mystery eyes (stuff in the red boxes). However, the sweater and blanket at the bottom would not be as helpful as those doggy features.\nSimilarly, we can explain the relationship between words in one sentence or close context. When we see “eating”, we expect to encounter a food word very soon. The color term describes the food, but probably not so much with “eating” directly.\nOne word \"attends\" to other words in the same sentence differently.\nIn a nutshell, attention in deep learning can be broadly interpreted as a vector of importance weights: in order to predict or infer one element, such as a pixel in an image or a word in a sentence, we estimate using the attention vector how strongly it is correlated with (or “\nattends to\n” as you may have read in many papers) other elements and take the sum of their values weighted by the attention vector as the approximation of the target.\nWhat’s Wrong with Seq2Seq Model?\n#\nThe\nseq2seq\nmodel was born in the field of language modeling (\nSutskever, et al. 2014\n). Broadly speaking, it aims to transform an input sequence (source) to a new one (target) and both sequences can be of arbitrary lengths. Examples of transformation tasks include machine translation between multiple languages in either text or audio, question-answer dialog generation, or even parsing sentences into grammar trees.\nThe seq2seq model normally has an encoder-decoder architecture, composed of:\nAn\nencoder\nprocesses the input sequence and compresses the information into a context vector (also known as sentence embedding or “thought” vector) of a\nfixed length\n. This representation is expected to be a good summary of the meaning of the\nwhole\nsource sequence.\nA\ndecoder\nis initialized with the context vector to emit the transformed output. The early work only used the last state of the encoder network as the decoder initial state.\nBoth the encoder and decoder are recurrent neural networks, i.e. using\nLSTM or GRU\nunits.\nThe encoder-decoder model, translating the sentence \"she is eating a green apple\" to Chinese. The visualization of both encoder and decoder is unrolled in time.\nA critical and apparent disadvantage of this fixed-length context vector design is incapability of remembering long sentences. Often it has forgotten the first part once it completes processing the whole input. The attention mechanism was born (\nBahdanau et al., 2015\n) to resolve this problem.\nBorn for Translation\n#\nThe attention mechanism was born to help memorize long source sentences in neural machine translation (\nNMT\n). Rather than building a single context vector out of the encoder’s last hidden state, the secret sauce invented by attention is to create shortcuts between the context vector and the entire source input. The weights of these shortcut connections are customizable for each output element.\nWhile the context vector has access to the entire input sequence, we don’t need to worry about forgetting. The alignment between the source and target is learned and controlled by the context vector. Essentially the context vector consumes three pieces of information:\nencoder hidden states;\ndecoder hidden states;\nalignment between source and target.\nThe encoder-decoder model with additive attention mechanism in\nBahdanau et al., 2015\n.\nDefinition\n#\nNow let’s define the attention mechanism introduced in NMT in a scientific way. Say, we have a source sequence $\\mathbf{x}$ of length $n$ and try to output a target sequence $\\mathbf{y}$ of length $m$:\n$$\n\\begin{aligned}\n\\mathbf{x} &= [x_1, x_2, \\dots, x_n] \\\\\n\\mathbf{y} &= [y_1, y_2, \\dots, y_m]\n\\end{aligned}\n$$\n(Variables in bold indicate that they are vectors; same for everything else in this post.)\nThe encoder is a\nbidirectional RNN\n(or other recurrent network setting of your choice) with a forward hidden state $\\overrightarrow{\\boldsymbol{h}}_i$ and a backward one $\\overleftarrow{\\boldsymbol{h}}_i$. A simple concatenation of two represents the encoder state. The motivation is to include both the preceding and following words in the annotation of one word.\n$$\n\\boldsymbol{h}_i = [\\overrightarrow{\\boldsymbol{h}}_i^\\top; \\overleftarrow{\\boldsymbol{h}}_i^\\top]^\\top, i=1,\\dots,n\n$$\nThe decoder network has hidden state $\\boldsymbol{s}_t=f(\\boldsymbol{s}_{t-1}, y_{t-1}, \\mathbf{c}_t)$ for the output word at position t, $t=1,\\dots,m$, where the context vector $\\mathbf{c}_t$ is a sum of hidden states of the input sequence, weighted by alignment scores:\n$$\n\\begin{aligned}\n\\mathbf{c}_t &= \\sum_{i=1}^n \\alpha_{t,i} \\boldsymbol{h}_i & \\small{\\text{; Context vector for output }y_t}\\\\\n\\alpha_{t,i} &= \\text{align}(y_t, x_i) & \\small{\\text{; How well two words }y_t\\text{ and }x_i\\text{ are aligned.}}\\\\\n&= \\frac{\\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_i))}{\\sum_{i'=1}^n \\exp(\\text{score}(\\boldsymbol{s}_{t-1}, \\boldsymbol{h}_{i'}))} & \\small{\\text{; Softmax of some predefined alignment score.}}.\n\\end{aligned}\n$$\nThe alignment model assigns a score $\\alpha_{t,i}$ to the pair of input at position i and output at position t, $(y_t, x_i)$, based on how well they match. The set of $\\{\\alpha_{t, i}\\}$ are weights defining how much of each source hidden state should be considered for each output. In Bahdanau’s paper, the alignment score $\\alpha$ is parametrized by a\nfeed-forward network\nwith a single hidden layer and this network is jointly trained with other parts of the model. The score function is therefore in the following form, given that tanh is used as the non-linear activation function:\n$$\n\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i])\n$$\nwhere both $\\mathbf{v}_a$ and $\\mathbf{W}_a$ are weight matrices to be learned in the alignment model.\nThe matrix of alignment scores is a nice byproduct to explicitly show the correlation between source and target words.\nAlignment matrix of \"L'accord sur l'Espace économique européen a été signé en août 1992\" (French) and its English translation \"The agreement on the European Economic Area was signed in August 1992\". (Image source: Fig 3 in\nBahdanau et al., 2015\n)\nCheck out this nice\ntutorial\nby Tensorflow team for more implementation instructions.\nA Family of Attention Mechanisms\n#\nWith the help of the attention, the dependencies between source and target sequences are not restricted by the in-between distance anymore! Given the big improvement by attention in machine translation, it soon got extended into the computer vision field (\nXu et al. 2015\n) and people started exploring various other forms of attention mechanisms (\nLuong, et al., 2015\n;\nBritz et al., 2017\n;\nVaswani, et al., 2017\n).\nSummary\n#\nBelow is a summary table of several popular attention mechanisms and corresponding alignment score functions:\nName\nAlignment score function\nCitation\nContent-base attention\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\text{cosine}[\\boldsymbol{s}_t, \\boldsymbol{h}_i]$\nGraves2014\nAdditive(*)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_{t-1}; \\boldsymbol{h}_i])$\nBahdanau2015\nLocation-Base\n$\\alpha_{t,i} = \\text{softmax}(\\mathbf{W}_a \\boldsymbol{s}_t)$\nNote: This simplifies the softmax alignment to only depend on the target position.\nLuong2015\nGeneral\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\mathbf{W}_a\\boldsymbol{h}_i$\nwhere $\\mathbf{W}_a$ is a trainable weight matrix in the attention layer.\nLuong2015\nDot-Product\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\boldsymbol{s}_t^\\top\\boldsymbol{h}_i$\nLuong2015\nScaled Dot-Product(^)\n$\\text{score}(\\boldsymbol{s}_t, \\boldsymbol{h}_i) = \\frac{\\boldsymbol{s}_t^\\top\\boldsymbol{h}_i}{\\sqrt{n}}$\nNote: very similar to the dot-product attention except for a scaling factor; where n is the dimension of the source hidden state.\nVaswani2017\n(*) Referred to as “concat” in Luong, et al., 2015 and as “additive attention” in Vaswani, et al., 2017.\n(^) It adds a scaling factor $1/\\sqrt{n}$, motivated by the concern when the input is large, the softmax function may have an extremely small gradient, hard for efficient learning.\nHere are a summary of broader categories of attention mechanisms:\nName\nDefinition\nCitation\nSelf-Attention(&)\nRelating different positions of the same input sequence. Theoretically the self-attention can adopt any score functions above, but just replace the target sequence with the same input sequence.\nCheng2016\nGlobal/Soft\nAttending to the entire input state space.\nXu2015\nLocal/Hard\nAttending to the part of input state space; i.e. a patch of the input image.\nXu2015\n;\nLuong2015\n(&) Also, referred to as “intra-attention” in Cheng et al., 2016 and some other papers.\nSelf-Attention\n#\nSelf-attention\n, also known as\nintra-attention\n, is an attention mechanism relating different positions of a single sequence in order to compute a representation of the same sequence. It has been shown to be very useful in machine reading, abstractive summarization, or image description generation.\nThe\nlong short-term memory network\npaper used self-attention to do machine reading. In the example below, the self-attention mechanism enables us to learn the correlation between the current words and the previous part of the sentence.\nThe current word is in red and the size of the blue shade indicates the activation level. (Image source:\nCheng et al., 2016\n)\nSoft vs Hard Attention\n#\nIn the\nshow, attend and tell\npaper, attention mechanism is applied to images to generate captions. The image is first encoded by a CNN to extract features. Then a LSTM decoder consumes the convolution features to produce descriptive words one by one, where the weights are learned through attention. The visualization of the attention weights clearly demonstrates which regions of the image the model is paying attention to so as to output a certain word.\n\"A woman is throwing a frisbee in a park.\" (Image source: Fig. 6(b) in\nXu et al. 2015\n)\nThis paper first proposed the distinction between “soft” vs “hard” attention, based on whether the attention has access to the entire image or only a patch:\nSoft\nAttention: the alignment weights are learned and placed “softly” over all patches in the source image; essentially the same type of attention as in\nBahdanau et al., 2015\n.\nPro\n: the model is smooth and differentiable.\nCon\n: expensive when the source input is large.\nHard\nAttention: only selects one patch of the image to attend to at a time.\nPro\n: less calculation at the inference time.\nCon\n: the model is non-differentiable and requires more complicated techniques such as variance reduction or reinforcement learning to train. (\nLuong, et al., 2015\n)\nGlobal vs Local Attention\n#\nLuong, et al., 2015\nproposed the “global” and “local” attention. The global attention is similar to the soft attention, while the local one is an interesting blend between\nhard and soft\n, an improvement over the hard attention to make it differentiable: the model first predicts a single aligned position for the current target word and a window centered around the source position is then used to compute a context vector.\nGlobal vs local attention (Image source: Fig 2 & 3 in\nLuong, et al., 2015\n)\nNeural Turing Machines\n#\nAlan Turing in\n1936\nproposed a minimalistic model of computation. It is composed of a infinitely long tape and a head to interact with the tape. The tape has countless cells on it, each filled with a symbol: 0, 1 or blank (\" “). The operation head can read symbols, edit symbols and move left/right on the tape. Theoretically a Turing machine can simulate any computer algorithm, irrespective of how complex or expensive the procedure might be. The infinite memory gives a Turing machine an edge to be mathematically limitless. However, infinite memory is not feasible in real modern computers and then we only consider Turing machine as a mathematical model of computation.\nHow a Turing machine looks like: a tape + a head that handles the tape. (Image source:\nhttp://aturingmachine.com/\n)\nNeural Turing Machine\n(\nNTM\n,\nGraves, Wayne & Danihelka, 2014\n) is a model architecture for coupling a neural network with external memory storage. The memory mimics the Turing machine tape and the neural network controls the operation heads to read from or write to the tape. However, the memory in NTM is finite, and thus it probably looks more like a “Neural\nvon Neumann\nMachine”.\nNTM contains two major components, a\ncontroller\nneural network and a\nmemory\nbank.\nController: is in charge of executing operations on the memory. It can be any type of neural network, feed-forward or recurrent.\nMemory: stores processed information. It is a matrix of size $N \\times M$, containing N vector rows and each has $M$ dimensions.\nIn one update iteration, the controller processes the input and interacts with the memory bank accordingly to generate output. The interaction is handled by a set of parallel\nread\nand\nwrite\nheads. Both read and write operations are “blurry” by softly attending to all the memory addresses.\nFig 10. Neural Turing Machine Architecture.\nReading and Writing\n#\nWhen reading from the memory at time t, an attention vector of size $N$, $\\mathbf{w}_t$ controls how much attention to assign to different memory locations (matrix rows). The read vector $\\mathbf{r}_t$ is a sum weighted by attention intensity:\n$$\n\\mathbf{r}_t = \\sum_{i=1}^N w_t(i)\\mathbf{M}_t(i)\\text{, where }\\sum_{i=1}^N w_t(i)=1, \\forall i: 0 \\leq w_t(i) \\leq 1\n$$\nwhere $w_t(i)$ is the $i$-th element in $\\mathbf{w}_t$ and $\\mathbf{M}_t(i)$ is the $i$-th row vector in the memory.\nWhen writing into the memory at time t, as inspired by the input and forget gates in LSTM, a write head first wipes off some old content according to an erase vector $\\mathbf{e}_t$ and then adds new information by an add vector $\\mathbf{a}_t$.\n$$\n\\begin{aligned}\n\\tilde{\\mathbf{M}}_t(i) &= \\mathbf{M}_{t-1}(i) [\\mathbf{1} - w_t(i)\\mathbf{e}_t] &\\scriptstyle{\\text{; erase}}\\\\\n\\mathbf{M}_t(i) &= \\tilde{\\mathbf{M}}_t(i) + w_t(i) \\mathbf{a}_t &\\scriptstyle{\\text{; add}}\n\\end{aligned}\n$$\nAttention Mechanisms\n#\nIn Neural Turing Machine, how to generate the attention distribution $\\mathbf{w}_t$ depends on the addressing mechanisms: NTM uses a mixture of content-based and location-based addressings.\nContent-based addressing\nThe content-addressing creates attention vectors based on the similarity between the key vector $\\mathbf{k}_t$ extracted by the controller from the input and memory rows. The content-based attention scores are computed as cosine similarity and then normalized by softmax. In addition, NTM adds a strength multiplier $\\beta_t$ to amplify or attenuate the focus of the distribution.\n$$\nw_t^c(i) \n= \\text{softmax}(\\beta_t \\cdot \\text{cosine}[\\mathbf{k}_t, \\mathbf{M}_t(i)])\n= \\frac{\\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(i)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(i)\\|})}{\\sum_{j=1}^N \\exp(\\beta_t \\frac{\\mathbf{k}_t \\cdot \\mathbf{M}_t(j)}{\\|\\mathbf{k}_t\\| \\cdot \\|\\mathbf{M}_t(j)\\|})}\n$$\nInterpolation\nThen an interpolation gate scalar $g_t$ is used to blend the newly generated content-based attention vector with the attention weights in the last time step:\n$$\n\\mathbf{w}_t^g = g_t \\mathbf{w}_t^c + (1 - g_t) \\mathbf{w}_{t-1} \n$$\nLocation-based addressing\nThe location-based addressing sums up the values at different positions in the attention vector, weighted by a weighting distribution over allowable integer shifts. It is equivalent to a 1-d convolution with a kernel $\\mathbf{s}_t(.)$, a function of the position offset. There are multiple ways to define this distribution. See for inspiration.\nTwo ways to represent the shift weighting distribution $\\mathbf{s}\\_t$.\nFinally the attention distribution is enhanced by a sharpening scalar $\\gamma_t \\geq 1$.\n$$\n\\begin{aligned}\n\\tilde{w}_t(i) &= \\sum_{j=1}^N w_t^g(j) s_t(i-j) & \\scriptstyle{\\text{; circular convolution}}\\\\\nw_t(i) &= \\frac{\\tilde{w}_t(i)^{\\gamma_t}}{\\sum_{j=1}^N \\tilde{w}_t(j)^{\\gamma_t}} & \\scriptstyle{\\text{; sharpen}}\n\\end{aligned}\n$$\nThe complete process of generating the attention vector $\\mathbf{w}_t$ at time step t is illustrated in All the parameters produced by the controller are unique for each head. If there are multiple read and write heads in parallel, the controller would output multiple sets.\nFlow diagram of the addressing mechanisms in Neural Turing Machine. (Image source:\nGraves, Wayne & Danihelka, 2014\n)\nPointer Network\n#\nIn problems like sorting or travelling salesman, both input and output are sequential data. Unfortunately, they cannot be easily solved by classic seq-2-seq or NMT models, given that the discrete categories of output elements are not determined in advance, but depends on the variable input size. The\nPointer Net\n(\nPtr-Net\n;\nVinyals, et al. 2015\n) is proposed to resolve this type of problems: When the output elements correspond to\npositions\nin an input sequence. Rather than using attention to blend hidden units of an encoder into a context vector (See Fig. 8), the Pointer Net applies attention over the input elements to pick one as the output at each decoder step.\nThe architecture of a Pointer Network model. (Image source:\nVinyals, et al. 2015\n)\nThe Ptr-Net outputs a sequence of integer indices, $\\boldsymbol{c} = (c_1, \\dots, c_m)$ given a sequence of input vectors $\\boldsymbol{x} = (x_1, \\dots, x_n)$ and $1 \\leq c_i \\leq n$. The model still embraces an encoder-decoder framework. The encoder and decoder hidden states are denoted as $(\\boldsymbol{h}_1, \\dots, \\boldsymbol{h}_n)$ and $(\\boldsymbol{s}_1, \\dots, \\boldsymbol{s}_m)$, respectively. Note that $\\mathbf{s}_i$ is the output gate after cell activation in the decoder. The Ptr-Net applies additive attention between states and then normalizes it by softmax to model the output conditional probability:\n$$\n\\begin{aligned}\ny_i &= p(c_i \\vert c_1, \\dots, c_{i-1}, \\boldsymbol{x}) \\\\\n    &= \\text{softmax}(\\text{score}(\\boldsymbol{s}_t; \\boldsymbol{h}_i)) = \\text{softmax}(\\mathbf{v}_a^\\top \\tanh(\\mathbf{W}_a[\\boldsymbol{s}_t; \\boldsymbol{h}_i]))\n\\end{aligned}\n$$\nThe attention mechanism is simplified, as Ptr-Net does not blend the encoder states into the output with attention weights. In this way, the output only responds to the positions but not the input content.\nTransformer\n#\n“Attention is All you Need”\n(Vaswani, et al., 2017), without a doubt, is one of the most impactful and interesting paper in 2017. It presented a lot of improvements to the soft attention and make it possible to do seq2seq modeling\nwithout\nrecurrent network units. The proposed “\ntransformer\n” model is entirely built on the self-attention mechanisms without using sequence-aligned recurrent architecture.\nThe secret recipe is carried in its model architecture.\nKey, Value and Query\n#\nThe major component in the transformer is the unit of\nmulti-head self-attention mechanism\n. The transformer views the encoded representation of the input as a set of\nkey\n-\nvalue\npairs, $(\\mathbf{K}, \\mathbf{V})$, both of dimension $n$ (input sequence length); in the context of NMT, both the keys and values are the encoder hidden states. In the decoder, the previous output is compressed into a\nquery\n($\\mathbf{Q}$ of dimension $m$) and the next output is produced by mapping this query and the set of keys and values.\nThe transformer adopts the\nscaled dot-product attention\n: the output is a weighted sum of the values, where the weight assigned to each value is determined by the dot-product of the query with all the keys:\n$$\n\\text{Attention}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) = \\text{softmax}(\\frac{\\mathbf{Q}\\mathbf{K}^\\top}{\\sqrt{n}})\\mathbf{V}\n$$\nMulti-Head Self-Attention\n#\nMulti-head scaled dot-product attention mechanism. (Image source: Fig 2 in\nVaswani, et al., 2017\n)\nRather than only computing the attention once, the multi-head mechanism runs through the scaled dot-product attention multiple times in parallel. The independent attention outputs are simply concatenated and linearly transformed into the expected dimensions. I assume the motivation is because ensembling always helps? ;) According to the paper,\n“multi-head attention allows the model to jointly attend to information from different representation\nsubspaces\nat different positions. With a single attention head, averaging inhibits this.”\n$$\n\\begin{aligned}\n\\text{MultiHead}(\\mathbf{Q}, \\mathbf{K}, \\mathbf{V}) &= [\\text{head}_1; \\dots; \\text{head}_h]\\mathbf{W}^O \\\\\n\\text{where head}_i &= \\text{Attention}(\\mathbf{Q}\\mathbf{W}^Q_i, \\mathbf{K}\\mathbf{W}^K_i, \\mathbf{V}\\mathbf{W}^V_i)\n\\end{aligned}\n$$\nwhere $\\mathbf{W}^Q_i$, $\\mathbf{W}^K_i$, $\\mathbf{W}^V_i$, and $\\mathbf{W}^O$ are parameter matrices to be learned.\nEncoder\n#\nThe transformer’s encoder. (Image source:\nVaswani, et al., 2017\n)\nThe encoder generates an attention-based representation with capability to locate a specific piece of information from a potentially infinitely-large context.\nA stack of N=6 identical layers.\nEach layer has a\nmulti-head self-attention layer\nand a simple position-wise\nfully connected feed-forward network\n.\nEach sub-layer adopts a\nresidual\nconnection and a layer\nnormalization\n.\nAll the sub-layers output data of the same dimension $d_\\text{model} = 512$.\nDecoder\n#\nThe transformer’s decoder. (Image source:\nVaswani, et al., 2017\n)\nThe decoder is able to retrieval from the encoded representation.\nA stack of N = 6 identical layers\nEach layer has two sub-layers of multi-head attention mechanisms and one sub-layer of fully-connected feed-forward network.\nSimilar to the encoder, each sub-layer adopts a residual connection and a layer normalization.\nThe first multi-head attention sub-layer is\nmodified\nto prevent positions from attending to subsequent positions, as we don’t want to look into the future of the target sequence when predicting the current position.\nFull Architecture\n#\nFinally here is the complete view of the transformer’s architecture:\nBoth the source and target sequences first go through embedding layers to produce data of the same dimension $d_\\text{model} =512$.\nTo preserve the position information, a sinusoid-wave-based positional encoding is applied and summed with the embedding output.\nA softmax and linear layer are added to the final decoder output.\nThe full model architecture of the transformer. (Image source: Fig 1 & 2 in\nVaswani, et al., 2017\n.)\nTry to implement the transformer model is an interesting experience, here is mine:\nlilianweng/transformer-tensorflow\n. Read the comments in the code if you are interested.\nSNAIL\n#\nThe transformer has no recurrent or convolutional structure, even with the positional encoding added to the embedding vector, the sequential order is only weakly incorporated. For problems sensitive to the positional dependency like\nreinforcement learning\n, this can be a big problem.\nThe\nSimple Neural Attention\nMeta-Learner\n(\nSNAIL\n) (\nMishra et al., 2017\n) was developed partially to resolve the problem with\npositioning\nin the transformer model by combining the self-attention mechanism in transformer with\ntemporal convolutions\n. It has been demonstrated to be good at both supervised learning and reinforcement learning tasks.\nSNAIL model architecture (Image source:\nMishra et al., 2017\n)\nSNAIL was born in the field of meta-learning, which is another big topic worthy of a post by itself. But in simple words, the meta-learning model is expected to be generalizable to novel, unseen tasks in the similar distribution. Read\nthis\nnice introduction if interested.\nSelf-Attention GAN\n#\nSelf-Attention GAN\n(\nSAGAN\n;\nZhang et al., 2018\n) adds self-attention layers into\nGAN\nto enable both the generator and the discriminator to better model relationships between spatial regions.\nThe classic\nDCGAN\n(Deep Convolutional GAN) represents both discriminator and generator as multi-layer convolutional networks. However, the representation capacity of the network is restrained by the filter size, as the feature of one pixel is limited to a small local region. In order to connect regions far apart, the features have to be dilute through layers of convolutional operations and the dependencies are not guaranteed to be maintained.\nAs the (soft) self-attention in the vision context is designed to explicitly learn the relationship between one pixel and all other positions, even regions far apart, it can easily capture global dependencies. Hence GAN equipped with self-attention is expected to\nhandle details better\n, hooray!\nConvolution operation and self-attention have access to regions of very different sizes.\nThe SAGAN adopts the\nnon-local neural network\nto apply the attention computation. The convolutional image feature maps $\\mathbf{x}$ is branched out into three copies, corresponding to the concepts of\nkey, value, and query\nin the transformer:\nKey: $f(\\mathbf{x}) = \\mathbf{W}_f \\mathbf{x}$\nQuery: $g(\\mathbf{x}) = \\mathbf{W}_g \\mathbf{x}$\nValue: $h(\\mathbf{x}) = \\mathbf{W}_h \\mathbf{x}$\nThen we apply the dot-product attention to output the self-attention feature maps:\n$$\n\\begin{aligned}\n\\alpha_{i,j} &= \\text{softmax}(f(\\mathbf{x}_i)^\\top g(\\mathbf{x}_j)) \\\\\n\\mathbf{o}_j &= \\mathbf{W}_v \\Big( \\sum_{i=1}^N \\alpha_{i,j} h(\\mathbf{x}_i) \\Big)\n\\end{aligned}\n$$\nThe self-attention mechanism in SAGAN. (Image source: Fig. 2 in\nZhang et al., 2018\n)\nNote that $\\alpha_{i,j}$ is one entry in the attention map, indicating how much attention the model should pay to the $i$-th position when synthesizing the $j$-th location. $\\mathbf{W}_f$, $\\mathbf{W}_g$, and $\\mathbf{W}_h$ are all 1x1 convolution filters. If you feel that 1x1 conv sounds like a weird concept (i.e., isn’t it just to multiply the whole feature map with one number?), watch this short\ntutorial\nby Andrew Ng. The output $\\mathbf{o}_j$ is a column vector of the final output $\\mathbf{o}= (\\mathbf{o}_1, \\mathbf{o}_2, \\dots, \\mathbf{o}_j, \\dots, \\mathbf{o}_N)$.\nFurthermore, the output of the attention layer is multiplied by a scale parameter and added back to the original input feature map:\n$$\n\\mathbf{y} = \\mathbf{x}_i + \\gamma \\mathbf{o}_i\n$$\nWhile the scaling parameter $\\gamma$ is increased gradually from 0 during the training, the network is configured to first rely on the cues in the local regions and then gradually learn to assign more weight to the regions that are further away.\n128×128 example images generated by SAGAN for different classes. (Image source: Partial Fig. 6 in\nZhang et al., 2018\n)\nCited as:\n@article{weng2018attention,\n  title   = \"Attention? Attention!\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-06-24-attention/\"\n}\nReferences\n#\n[1]\n“Attention and Memory in Deep Learning and NLP.”\n- Jan 3, 2016 by Denny Britz\n[2]\n“Neural Machine Translation (seq2seq) Tutorial”\n[3] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio.\n“Neural machine translation by jointly learning to align and translate.”\nICLR 2015.\n[4] Kelvin Xu, Jimmy Ba, Ryan Kiros, Kyunghyun Cho, Aaron Courville, Ruslan Salakhudinov, Rich Zemel, and Yoshua Bengio.\n“Show, attend and tell: Neural image caption generation with visual attention.”\nICML, 2015.\n[5] Ilya Sutskever, Oriol Vinyals, and Quoc V. Le.\n“Sequence to sequence learning with neural networks.”\nNIPS 2014.\n[6] Thang Luong, Hieu Pham, Christopher D. Manning.\n“Effective Approaches to Attention-based Neural Machine Translation.”\nEMNLP 2015.\n[7] Denny Britz, Anna Goldie, Thang Luong, and Quoc Le.\n“Massive exploration of neural machine translation architectures.”\nACL 2017.\n[8] Ashish Vaswani, et al.\n“Attention is all you need.”\nNIPS 2017.\n[9] Jianpeng Cheng, Li Dong, and Mirella Lapata.\n“Long short-term memory-networks for machine reading.”\nEMNLP 2016.\n[10] Xiaolong Wang, et al.\n“Non-local Neural Networks.”\nCVPR 2018\n[11] Han Zhang, Ian Goodfellow, Dimitris Metaxas, and Augustus Odena.\n“Self-Attention Generative Adversarial Networks.”\narXiv preprint arXiv:1805.08318 (2018).\n[12] Nikhil Mishra, Mostafa Rohaninejad, Xi Chen, and Pieter Abbeel.\n“A simple neural attentive meta-learner.”\nICLR 2018.\n[13]\n“WaveNet: A Generative Model for Raw Audio”\n- Sep 8, 2016 by DeepMind.\n[14]  Oriol Vinyals, Meire Fortunato, and Navdeep Jaitly.\n“Pointer networks.”\nNIPS 2015.\n[15] Alex Graves, Greg Wayne, and Ivo Danihelka.\n“Neural turing machines.”\narXiv preprint arXiv:1410.5401 (2014).",
            "metadata": {
              "title": "Attention? Attention! | Lil'Log",
              "description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "keywords": "architecture, attention, transformer, rnn",
              "author": "Lilian Weng",
              "og:title": "Attention? Attention!",
              "og:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
              "twitter:card": "summary",
              "twitter:title": "Attention? Attention!",
              "twitter:description": "[Updated on 2018-10-28: Add Pointer Network and the link to my implementation of Transformer.]\n[Updated on 2018-11-06: Add a link to the implementation of Transformer model.]\n[Updated on 2018-11-18: Add Neural Turing Machines.]\n[Updated on 2019-07-18: Correct the mistake on using the term “self-attention” when introducing the show-attention-tell paper; moved it to Self-Attention section.]\n[Updated on 2020-04-07: A follow-up post on improved Transformer models is here.]",
              "article:section": "posts",
              "article:published_time": "2018-06-24T00:00:00+00:00",
              "article:modified_time": "2018-06-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/1c9291c74af3/code/body-000.txt",
                "chars": 222,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "bytes": 2159899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-8571ab535bf08b3eb897.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shiba-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "bytes": 36779,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-244663c064863ba3add1.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/sentence-example-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "bytes": 163006,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-417a080a721a8da35e76.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-example.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "bytes": 360658,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7a8e772d26ca2075d030.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/encoder-decoder-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "bytes": 329846,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-a79121328d38f1e7decb.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/bahdanau-fig3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "bytes": 1061108,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-217a917d5b695d69920e.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/cheng2016-fig1.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "bytes": 3290656,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-16ff0e0557cd1ec7183b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/xu2015-fig6b.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "bytes": 190907,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-68ed274d29e23ec04058.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/luong2015-fig2-3.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "bytes": 20601,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-f7ff47f8ed0c85c31c04.jpg",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/turing-machine.jpg",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "bytes": 194344,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d885b9f00fc903916eff.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "bytes": 236994,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-43b2947b31f475b9d117.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/shift-weighting.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "bytes": 476899,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-202d6793b7b96d2f655a.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/NTM-flow-addressing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "bytes": 401199,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-47a02b382f80dc9a2137.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/ptr-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "bytes": 106503,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d314a0ab86b5abc9e45b.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/multi-head-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "bytes": 136297,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-5bee749c4008d551aef3.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-encoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "bytes": 198560,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-9686a8baee36d438f09c.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer-decoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "bytes": 376109,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-7cfc826648a35a656e03.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "bytes": 485628,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-4f9fa106ff81362212ba.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/snail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "bytes": 124592,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-3442cdcfc8a317d5e9cd.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/conv-vs-self-attention.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "bytes": 392406,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-d18eeaedd090128a06bf.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "bytes": 3409897,
                "reused": false,
                "local_path": "attachments/1c9291c74af3/images/body-82aaa856d170c7aa0cea.png",
                "src": "https://lilianweng.github.io/posts/2018-06-24-attention/SAGAN-examples.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://github.com/lilianweng/transformer-tensorflow",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1502.03044",
                "label": "show-attention-tell",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2020-04-07-the-transformer-family/",
                "label": "here",
                "type": "a"
              },
              {
                "href": "https://www.instagram.com/mensweardog/?hl=en",
                "label": "@mensweardog",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.3215",
                "label": "Sutskever, et al. 2014",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "LSTM or GRU",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1409.0473.pdf",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/nlp-sequence-models/bidirectional-rnn-fyXnn",
                "label": "bidirectional RNN",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/versions/master/tutorials/seq2seq",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "label": "Xu et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.04025.pdf",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.03906",
                "label": "Britz et al., 2017",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "label": "Vaswani, et al., 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.5401",
                "label": "Graves2014",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1508.4025.pdf",
                "label": "Luong2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1601.06733.pdf",
                "label": "Cheng2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.0473",
                "label": "Bahdanau et al., 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1508.04025",
                "label": "Luong, et al., 2015",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Turing_machine",
                "label": "1936",
                "type": "a"
              },
              {
                "href": "http://aturingmachine.com/",
                "label": "http://aturingmachine.com/",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Von_Neumann_architecture",
                "label": "von Neumann",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.03134",
                "label": "Vinyals, et al. 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1512.03385.pdf",
                "label": "residual",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-02-19-rl-overview/",
                "label": "reinforcement learning",
                "type": "a"
              },
              {
                "href": "http://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/",
                "label": "Meta-Learner",
                "type": "a"
              },
              {
                "href": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "label": "Mishra et al., 2017",
                "type": "a"
              },
              {
                "href": "https://deepmind.com/blog/wavenet-generative-model-raw-audio/",
                "label": "temporal convolutions",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1805.08318.pdf",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-08-20-gan/",
                "label": "GAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06434",
                "label": "DCGAN",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1711.07971.pdf",
                "label": "non-local neural network",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1805.08318",
                "label": "Zhang et al., 2018",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/lecture/convolutional-neural-networks/networks-in-networks-and-1x1-convolutions-ZTb8x",
                "label": "tutorial",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/2016/01/attention-and-memory-in-deep-learning-and-nlp/",
                "label": "“Attention and Memory in Deep Learning and NLP.”",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/nmt",
                "label": "“Neural Machine Translation (seq2seq) Tutorial”",
                "type": "a"
              },
              {
                "href": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "label": "“Sequence to sequence learning with neural networks.”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.03141",
                "label": "“A simple neural attentive meta-learner.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:32Z",
            "source_url": "https://lilianweng.github.io/posts/2018-06-24-attention/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1502.03044",
                "bytes": 9582640,
                "reused": false,
                "local_path": "papers/repair/cc9ae4c67126750bbe41.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.3215",
                "bytes": 112084,
                "reused": false,
                "local_path": "papers/repair/61d552395d0f0789263b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473.pdf",
                "bytes": 444482,
                "reused": false,
                "local_path": "papers/repair/ffb5ff16a013792114ac.pdf"
              },
              {
                "status": "ok",
                "url": "http://proceedings.mlr.press/v37/xuc15.pdf",
                "bytes": 3126761,
                "reused": false,
                "local_path": "papers/repair/53e1470cf7704d6e3cb9.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/dac4f1215a64e5bf890e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.03906",
                "bytes": 305967,
                "reused": false,
                "local_path": "papers/repair/2864d7bf295692b04b3f.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf",
                "bytes": 569417,
                "reused": true,
                "local_path": "papers/repair/95fa654499d86d006948.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.5401",
                "bytes": 1357690,
                "reused": false,
                "local_path": "papers/repair/968a0ef3e0f98e3e8588.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.4025.pdf",
                "bytes": 249825,
                "reused": false,
                "local_path": "papers/repair/538f66bff21c49b4a2af.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1601.06733.pdf",
                "bytes": 2520829,
                "reused": false,
                "local_path": "papers/repair/eab5cb0dbe082766664e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.0473",
                "bytes": 444482,
                "reused": true,
                "local_path": "papers/repair/b6909588ff7b9ebf375f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1508.04025",
                "bytes": 249825,
                "reused": true,
                "local_path": "papers/repair/94d3d49016ad40753c67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.03134",
                "bytes": 469544,
                "reused": false,
                "local_path": "papers/repair/88d23cac0369adc66dcd.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.03385.pdf",
                "bytes": 819383,
                "reused": false,
                "local_path": "papers/repair/984099b2816e5988dbb2.pdf"
              },
              {
                "status": "http_404",
                "url": "http://metalearning.ml/papers/metalearn17_mishra.pdf",
                "retried_at": "2026-10-20T18:09:22Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318.pdf",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/09d96a257954f78287a4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06434",
                "bytes": 7457198,
                "reused": false,
                "local_path": "papers/repair/adcbe83e3cd16cada0ea.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1711.07971.pdf",
                "bytes": 2853537,
                "reused": false,
                "local_path": "papers/repair/684df287e5824edb084a.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1805.08318",
                "bytes": 6338711,
                "reused": false,
                "local_path": "papers/repair/72f7e2aac2061b4b2acd.pdf"
              },
              {
                "status": "ok",
                "url": "https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf",
                "bytes": 142950,
                "reused": false,
                "local_path": "papers/repair/3cc5c95987280b914097.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.03141",
                "bytes": 1026799,
                "reused": false,
                "local_path": "papers/repair/75189519ab64f046e1aa.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29634,
            "expected_body_images": 21,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/1c9291c74af3/pages/source.html",
            "local_html": "attachments/1c9291c74af3/pages/article.html",
            "body_base_path": "attachments/1c9291c74af3/pages/",
            "body_markdown_path": "attachments/1c9291c74af3/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
          "status": "ok",
          "article_id": "3cea57e75b80",
          "local_path": "series-follow/1601/repair/af2ac25733510357c46b.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
              "bytes": 313515,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/41ecf126bf1745efcc5a.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
              "bytes": 146194,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3ea228d0e87dde9e7cf1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
              "bytes": 354759,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6bd3a5f62a05f8cd2ac7.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
              "bytes": 416371,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b634c681f16b15e45c48.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
              "bytes": 57364,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/db6d0799d37711ac02cd.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
              "bytes": 599299,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e2359292b85ebbae6075.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
              "bytes": 423806,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a6b205a1fce5f8c10434.png"
            }
          ],
          "article": {
            "id": "3cea57e75b80",
            "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "bytes": 313515,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-41ecf126bf1745efcc5a.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-dnn-structure.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "bytes": 146194,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-3ea228d0e87dde9e7cf1.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "bytes": 354759,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-6bd3a5f62a05f8cd2ac7.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-information-plane-merged.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "bytes": 416371,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-b634c681f16b15e45c48.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-mean-variation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "bytes": 57364,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-db6d0799d37711ac02cd.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-bound.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "bytes": 599299,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-e2359292b85ebbae6075.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-layers.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "bytes": 423806,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/3cea57e75b80/images/body-a6b205a1fce5f8c10434.png",
                "src": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/ib-training-size.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=bLqJHjXihK8",
                "src": "https://youtu.be/bLqJHjXihK8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-bLqJHjXihK8.mp4",
                "bytes": 393293403,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "3474.261000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=P1A1yNsxMjc",
                "src": "https://youtu.be/P1A1yNsxMjc",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/3cea57e75b80/videos/repair-P1A1yNsxMjc.mp4",
                "bytes": 7744527,
                "valid": true,
                "height": 1080,
                "width": 1440,
                "duration": "100.041000",
                "reused": false
              }
            ],
            "body_markdown": "Professor Naftali Tishby passed away in 2021. Hope the post can introduce his cool idea of information bottleneck to more people.\nRecently I watched the talk\n“Information Theory in Deep Learning”\nby Prof Naftali Tishby and found it very interesting. He presented how to apply the information theory to study the growth and transformation of deep neural networks during training. Using the\nInformation Bottleneck (IB)\nmethod, he proposed a new learning bound for deep neural networks (DNN), as the traditional learning theory fails due to the exponentially large number of parameters. Another keen observation is that DNN training involves two distinct phases: First, the network is trained to fully represent the input data and minimize the generalization error; then, it learns to forget the irrelevant details by compressing the representation of the input.\nMost of the materials in this post are from Prof Tishby’s talk and\nrelated papers\n.\nBasic Concepts\n#\nMarkov Chain\nA Markov process is a\n“memoryless”\n(also called “Markov Property”) stochastic process. A Markov chain is a type of Markov process containing multiple discrete states. That is being said, the conditional probability of future states of the process is only determined by the current state and does not depend on the past states.\nKullback–Leibler (KL) Divergence\nKL divergence measures how one probability distribution $p$ diverges from a second expected probability distribution $q$. It is asymmetric.\n$$\n\\begin{aligned}\nD_{KL}(p \\| q) &= \\sum_x p(x) \\log \\frac{p(x)}{q(x)} \\\\\n &= - \\sum_x p(x)\\log q(x) + \\sum_x p(x)\\log p(x) \\\\\n &= H(P, Q) - H(P)\n\\end{aligned}\n$$\n$D_{KL}$ achieves the minimum zero when $p(x)$ == $q(x)$ everywhere.\nMutual Information\nMutual information measures the mutual dependence between two variables. It quantifies the “amount of information” obtained about one random variable through the other random variable. Mutual information is symmetric.\n$$\n\\begin{aligned}\nI(X;Y) &= D_{KL}[p(x,y) \\| p(x)p(y)] \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x, y)}{p(x)p(y)}) \\\\\n &= \\sum_{x \\in X, y \\in Y} p(x, y) \\log(\\frac{p(x|y)}{p(x)}) \\\\ \n &= H(X) - H(X|Y) \\\\\n\\end{aligned}\n$$\nData Processing Inequality (DPI)\nFor any markov chain: $X \\to Y \\to Z$, we would have $I(X; Y) \\geq I(X; Z)$.\nA deep neural network can be viewed as a Markov chain, and thus when we are moving down the layers of a DNN, the mutual information between the layer and the input can only decrease.\nReparametrization invariance\nFor two invertible functions $\\phi$, $\\psi$, the mutual information still holds: $I(X; Y) = I(\\phi(X); \\psi(Y))$.\nFor example, if we shuffle the weights in one layer of DNN, it would not affect the mutual information between this layer and another.\nDeep Neural Networks as Markov Chains\n#\nThe training data contains sampled observations from the joint distribution of $X$ and $Y$. The input variable $X$ and weights of hidden layers are all high-dimensional random variable. The ground truth target $Y$ and the predicted value $\\hat{Y}$ are random variables of smaller dimensions in the classification settings.\nThe structure of a deep neural network, which consists of the target label $Y$, input layer $X$, hidden layers $h\\_1, \\dots, h\\_m$ and the final prediction $\\hat{Y}$. (Image source:\nTishby and Zaslavsky, 2015\n)\nIf we label the hidden layers of a DNN as $h_1, h_2, \\dots, h_m$ as in Fig. 1, we can view each layer as one state of a Markov Chain: $ h_i \\to h_{i+1}$. According to DPI, we would have:\n$$\n\\begin{aligned}\nH(X) \\geq I(X; h_1) \\geq I(X; h_2) \\geq \\dots \\geq I(X; h_m) \\geq I(X; \\hat{Y}) \\\\\nI(X; Y) \\geq I(h_1; Y) \\geq I(h_2; Y) \\geq \\dots \\geq I(h_m; Y) \\geq I(\\hat{Y}; Y)\n\\end{aligned}\n$$\nA DNN is designed to learn how to describe $X$ to predict $Y$ and eventually, to compress $X$ to only hold the information related to $Y$. Tishby describes this processing as\n“successive refinement of relevant information”\n.\nInformation Plane Theorem\n#\nA DNN has successive internal representations of $X$, a set of hidden layers $\\{T_i\\}$. The\ninformation plane\ntheorem characterizes each layer by its encoder and decoder information. The encoder is a representation of the input data $X$, while the decoder translates the information in the current layer to the target ouput $Y$.\nPrecisely, in an information plane plot:\nX-axis\n: The sample complexity of $T_i$ is determined by the encoder mutual information $I(X; T_i)$. Sample complexity refers to how many samples you need to achieve certain accuracy and generalization.\nY-axis\n: The accuracy (generalization error) is determined by the decoder mutual information $I(T_i; Y)$.\nThe encoder vs decoder mutual information of DNN hidden layers of 50 experiments. Different layers are color-coders, with green being the layer right next to the input and the orange being the furthest. There are three snapshots, at the initial epoch, 400 epochs and 9000 epochs respectively. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nEach dot in marks the encoder/ decoder mutual information of one hidden layer of one network simulation (no regularization is applied; no weights decay, no dropout, etc.). They move up as expected because the knowledge about the true labels is increasing (accuracy increases). At the early stage, the hidden layers learn a lot about the input $X$, but later they start to compress to forget some information about the input. Tishby believes that\n“the most important part of learning is actually forgetting”\n. Check out this\nnice video\nthat demonstrates how the mutual information measures of layers are changing in epoch time.\nHere is an aggregated view of Fig 2. The compression happens after the generalization error becomes very small. (Image source:\nTishby’ talk 15:15\n)\nTwo Optimization Phases\n#\nTracking the normalized mean and standard deviation of each layer’s weights in time also reveals two optimization phases of the training process.\nThe norm of mean and standard deviation of each layer's weight gradients for each layer as a function of training epochs. Different layers are color-coded. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nAmong early epochs, the mean values are three magnitudes larger than the standard deviations. After a sufficient number of epochs, the error saturates and the standard deviations become much noisier afterward. The further a layer is away from the output, the noisier it gets, because the noises can get amplified and accumulated through the back-prop process (not due to the width of the layer).\nLearning Theory\n#\n“Old” Generalization Bounds\n#\nThe generalization bounds defined by the classic learning theory is:\n$$\n\\epsilon^2 < \\frac{\\log|H_\\epsilon| + \\log{1/\\delta}}{2m}\n$$\n$\\epsilon$: The difference between the training error and the generalization error. The generalization error measures how accurate the prediction of an algorithm is for previously unseen data.\n$H_\\epsilon$: $\\epsilon$-cover of the hypothesis class. Typically we assume the size $\\vert H_\\epsilon \\vert \\sim (1/\\epsilon)^d$.\n$\\delta$: Confidence.\n$m$: The number of training samples.\n$d$: The VC dimension of the hypothesis.\nThis definition states that the difference between the training error and the generalization error is bounded by a function of the hypothesis space size and the dataset size. The bigger the hypothesis space gets, the bigger the generalization error becomes. I recommend this tutorial on ML theory,\npart1\nand\npart2\n, if you are interested in reading more on generalization bounds.\nHowever, it does not work for deep learning. The larger a network is, the more parameters it needs to learn. With this generalization bounds, larger networks (larger $d$) would have worse bounds. This is contrary to the intuition that larger networks are able to achieve better performance with higher expressivity.\n“New” Input compression bound\n#\nTo solve this counterintuitive observation, Tishby et al. proposed a new input compression bound for DNN.\nFirst let us have $T_\\epsilon$ as an $\\epsilon$-partition of the input variable $X$. This partition compresses the input with respect to the homogeneity to the labels into small cells. The cells in total can cover the whole input space. If the prediction outputs binary values, we can replace the cardinality of the hypothesis, $\\vert H_\\epsilon \\vert$, with $2^{\\vert T_\\epsilon \\vert}$.\n$$\n|H_\\epsilon| \\sim 2^{|X|} \\to 2^{|T_\\epsilon|}\n$$\nWhen $X$ is large, the size of $X$ is approximately $2^{H(X)}$. Each cell in the $\\epsilon$-partition is of size $2^{H(X \\vert T_\\epsilon)}$. Therefore we have $\\vert T_\\epsilon \\vert \\sim \\frac{2^{H(X)}}{2^{H(X \\vert T_\\epsilon)}} = 2^{I(T_\\epsilon; X)}$. Then the input compression bound becomes:\n$$\n\\epsilon^2 < \\frac{2^{I(T_\\epsilon; X)} + \\log{1/\\delta}}{2m}\n$$\nThe black line is the optimal achievable information bottleneck (IB) limit. The red line corresponds to the upper bound on the out-of-sample IB distortion, when trained on a finite sample set. $\\Delta C$ is the complexity gap and $\\Delta G$ is the generalization gap. (Recreated based on\nTishby’ talk 24:50\n)\nNetwork Size and Training Data Size\n#\nThe Benefit of More Hidden Layers\n#\nHaving more layers give us computational benefits and speed up the training process for good generalization.\nThe optimization time is much shorter (fewer epochs) with more hidden layers. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCompression through stochastic relaxation\n: According to the\ndiffusion equation\n, the relaxation time of layer $k$ is proportional to the exponential of this layer’s compression amount $\\Delta S_k$: $\\Delta t_k \\sim \\exp(\\Delta S_k)$. We can compute the layer compression as $\\Delta S_k = I(X; T_k) - I(X; T_{k-1})$.  Because $\\exp(\\sum_k \\Delta S_k) \\geq \\sum_k \\exp(\\Delta S_k)$, we would expect an exponential decrease in training epochs with more hidden layers (larger $k$).\nThe Benefit of More Training Samples\n#\nFitting more training data requires more information captured by the hidden layers. With increased training data size, the decoder mutual information (recall that this is directly related to the generalization error), $I(T; Y)$, is pushed up and gets closer to the theoretical information bottleneck bound. Tishby emphasized that It is the mutual information, not the layer size or the VC dimension, that determines generalization, different from standard theories.\nThe training data of different sizes is color-coded. The information plane of multiple converged networks are plotted. More training data leads to better generalization. (Image source:\nShwartz-Ziv and Tishby, 2017\n)\nCited as:\n@article{weng2017infotheory,\n  title   = \"Anatomize Deep Learning with Information Theory\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/\"\n}\nReferences\n#\n[1] Naftali Tishby.\nInformation Theory of Deep Learning\n[2]\nMachine Learning Theory - Part 1: Introduction\n[3]\nMachine Learning Theory - Part 2: Generalization Bounds\n[4]\nNew Theory Cracks Open the Black Box of Deep Learning\nby Quanta Magazine.\n[5] Naftali Tishby and Noga Zaslavsky.\n“Deep learning and the information bottleneck principle.”\nIEEE Information Theory Workshop (ITW), 2015.\n[6] Ravid Shwartz-Ziv and Naftali Tishby.\n“Opening the Black Box of Deep Neural Networks via Information.”\narXiv preprint arXiv:1703.00810, 2017.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:54Z",
            "title": "Anatomize Deep Learning with Information Theory | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/3cea57e75b80/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/physics/0004057.pdf",
                "bytes": 136267,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2bcb5c185f6c851f4943.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1503.02406.pdf",
                "bytes": 370205,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e3468aeea8ac86e9dd9c.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.00810.pdf",
                "bytes": 3921623,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/d2cb5165e032151c7470.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 11409,
            "expected_body_images": 7,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/3cea57e75b80/pages/source.html",
            "local_html": "attachments/3cea57e75b80/pages/article.html",
            "body_base_path": "attachments/3cea57e75b80/pages/",
            "body_markdown_path": "attachments/3cea57e75b80/pages/article.md",
            "links": [
              {
                "href": "https://youtu.be/bLqJHjXihK8",
                "label": "“Information Theory in Deep Learning”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/physics/0004057.pdf",
                "label": "Information Bottleneck (IB)",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-09-28-information-bottleneck/",
                "label": "related papers",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Markov_chain",
                "label": "Markov Chain",
                "type": "a"
              },
              {
                "href": "http://mathworld.wolfram.com/Memoryless.html",
                "label": "“memoryless”",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence",
                "label": "Kullback–Leibler (KL) Divergence",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Mutual_information",
                "label": "Mutual Information",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Data_processing_inequality",
                "label": "Data Processing Inequality (DPI)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Parametrization",
                "label": "Reparametrization invariance",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1503.02406.pdf",
                "label": "Tishby and Zaslavsky, 2015",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.00810.pdf",
                "label": "Shwartz-Ziv and Tishby, 2017",
                "type": "a"
              },
              {
                "href": "https://youtu.be/P1A1yNsxMjc",
                "label": "nice video",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=15m15s",
                "label": "Tishby’ talk 15:15",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt1/",
                "label": "part1",
                "type": "a"
              },
              {
                "href": "https://mostafa-samir.github.io/ml-theory-pt2/",
                "label": "part2",
                "type": "a"
              },
              {
                "href": "https://youtu.be/bLqJHjXihK8?t=24m56s",
                "label": "Tishby’ talk 24:50",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Fokker%E2%80%93Planck_equation",
                "label": "diffusion equation",
                "type": "a"
              },
              {
                "href": "https://www.quantamagazine.org/new-theory-cracks-open-the-black-box-of-deep-learning-20170921/",
                "label": "New Theory Cracks Open the Black Box of Deep Learning",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/TBA",
          "status": "http_404"
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-08-06-nas/aging-evolutionary-algorithms",
          "status": "http_404"
        },
        {
          "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
          "status": "partial",
          "article_id": "18b05e29ab9d",
          "local_path": "series-follow/1601/repair/788a1d1b274cec73d601.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
              "bytes": 252865,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/afdfe639fc8e1e1fffd2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
              "bytes": 398921,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/16ceaeb88e6dddc6da50.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
              "bytes": 101901,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e1a448b3ff933291fe36.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
              "bytes": 381220,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/0cbda3f821a3c389eac8.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
              "bytes": 346442,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7e88364dbbb1f375b821.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
              "bytes": 228570,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/df4787f5cc26e6a6c19f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
              "bytes": 338618,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5e41793b605df1e81d30.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
              "bytes": 288179,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3f6e0179b739c72f6462.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
              "bytes": 922761,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f1d133cc3f81469a78d0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
              "bytes": 287370,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f0267a45ebe0513db62f.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
              "bytes": 261905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/3bf6bcdbee4e7c90f493.png"
            }
          ],
          "article": {
            "id": "18b05e29ab9d",
            "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "bytes": 252865,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-afdfe639fc8e1e1fffd2.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/types-of-curriculum-2.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "bytes": 398921,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-16ceaeb88e6dddc6da50.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/curriculum-by-transfer-learning.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "bytes": 101901,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-e1a448b3ff933291fe36.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/teacher-student-curriculum.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "bytes": 381220,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-0cbda3f821a3c389eac8.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/ALP-GMM-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "bytes": 346442,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-7e88364dbbb1f375b821.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/self-play-maze.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "bytes": 228570,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-df4787f5cc26e6a6c19f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/generative-goal-learning-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "bytes": 338618,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-5e41793b605df1e81d30.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/setter-judge-goal-generation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "bytes": 288179,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3f6e0179b739c72f6462.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "bytes": 922761,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f1d133cc3f81469a78d0.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/CARML-algorithm.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "bytes": 287370,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-f0267a45ebe0513db62f.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/progressive-networks.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "bytes": 261905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/18b05e29ab9d/images/body-3bf6bcdbee4e7c90f493.png",
                "src": "https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/mix-and-match.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "[Updated on 2020-02-03: mentioning\nPCG\nin the “Task-Specific Curriculum” section.\n[Updated on 2020-02-04: Add a new\n“curriculum through distillation”\nsection.\nIt sounds like an impossible task if we want to teach integral or derivative to a 3-year-old who does not even know basic arithmetics. That’s why education is important, as it provides a systematic way to break down complex knowledge and a nice curriculum for teaching concepts from simple to hard. A curriculum makes learning difficult things easier and approachable for us humans. But, how about machine learning models? Can we train our models more efficiently with a curriculum? Can we design a curriculum to speed up learning?\nBack in 1993, Jeffrey Elman has proposed the idea of training neural networks with a curriculum. His early work on learning simple language grammar demonstrated the importance of such a strategy: starting with a restricted set of simple data and gradually increasing the complexity of training samples; otherwise the model was not able to learn at all.\nCompared to training without a curriculum, we would expect the adoption of the curriculum to expedite the speed of convergence and may or may not improve the final model performance. To design an efficient and effective curriculum is not easy. Keep in mind that, a bad curriculum may even hamper learning.\nNext, we will look into several categories of curriculum learning, as illustrated in Most cases are applied to Reinforcement Learning, with a few exceptions on Supervised Learning.\nFive types of curriculum for reinforcement learning.\nIn “The importance of starting small” paper (\nElman 1993\n), I especially like the starting sentences and find them both inspiring and affecting:\n“Humans differ from other species along many dimensions, but two are particularly noteworthy. Humans display an exceptional capacity to learn; and humans are remarkable for the unusually long time it takes to reach maturity. The adaptive advantage of learning is clear, and it may be argued that, through culture, learning has created the basis for a non-genetically based transmission of behaviors which may accelerate the evolution of our species.”\nIndeed, learning is probably the best superpower we humans have.\nTask-Specific Curriculum\n#\nBengio, et al. (2009)\nprovided a good overview of curriculum learning in the old days. The paper presented two ideas with toy experiments using a manually designed task-specific curriculum:\nCleaner Examples may yield better generalization faster.\nIntroducing gradually more difficult examples speeds up online training.\nIt is plausible that some curriculum strategies could be useless or even harmful. A good question to answer in the field is:\nWhat could be the general principles that make some curriculum strategies work better than others?\nThe Bengio 2009 paper hypothesized it would be beneficial to make learning focus on “interesting” examples that are neither too hard or too easy.\nIf our naive curriculum is to train the model on samples with a gradually increasing level of complexity, we need a way to quantify the difficulty of a task first. One idea is to use its minimal loss with respect to another model while this model is pretrained on other tasks (\nWeinshall, et al. 2018\n). In this way, the knowledge of the pretrained model can be transferred to the new model by suggesting a rank of training samples. Fig. 2 shows the effectiveness of the\ncurriculum\ngroup (green), compared to\ncontrol\n(random order; yellow) and\nanti\n(reverse the order; red) groups.\nImage classification accuracy on test image set (5 member classes of \"small mammals\" in CIFAR100). There are 4 experimental groups, (a) `curriculum`: sort the labels by the confidence of another trained classifier (e.g. the margin of an SVM); (b) `control-curriculum`: sort the labels randomly; (c) `anti-curriculum`: sort the labels reversely; (d) `None`: no curriculum. (Image source:\nWeinshall, et al. 2018\n)\nZaremba & Sutskever (2014)\ndid an interesting experiment on training LSTM to predict the output of a short Python program for mathematical ops without actually executing the code. They found curriculum is necessary for learning. The program’s complexity is controlled by two parameters,\nlength\n∈ [1, a] and\nnesting\n∈ [1, b]. Three strategies are considered:\nNaive curriculum: increase\nlength\nfirst until reaching\na\n; then increase\nnesting\nand reset\nlength\nto 1; repeat this process until both reach maximum.\nMix curriculum: sample\nlength\n~ [1, a] and\nnesting\n~ [1, b]\nCombined: naive + mix.\nThey noticed that combined strategy always outperformed the naive curriculum and would generally (but not always) outperform the mix strategy — indicating that it is quite important to mix in easy tasks during training to\navoid forgetting\n.\nProcedural content generation (\nPCG\n) is a popular approach for creating video games of various levels of difficulty. PCG involves algorithmic randomness and a heavy dose of human expertise in designing game elements and dependencies among them. Procedurally generated levels have been introduced into several benchmark environments for evaluating whether an RL agent can generalize to a new level that it is not trained on (\nmeta-RL\n!), such as\nGVGAI\n, OpenAI\nCoinRun\nand\nProcgen benchmark\n. Using GVGAI,\nJustesen, et al. (2018)\ndemonstrated that an RL policy can easily overfit to a specific game but training over a simple curriculum that grows the task difficulty together with the model performance helps its generalization to new human-designed levels. Similar results are also found in CoinRun (\nCobbe, et al. 2018\n). POET (\nWang et al, 2019\n) is another example for leveraging evolutionary algorithm and procedural generated game levels to improve RL generalization, which I’ve described in details in my\nmeta-RL post\n.\nTo follow the curriculum learning approaches described above, generally we need to figure out two problems in the training procedure:\nDesign a metric to quantify how hard a task is so that we can sort tasks accordingly.\nProvide a sequence of tasks with an increasing level of difficulty to the model during training.\nHowever, the order of tasks does not have to be sequential. In our Rubik’s cube paper (\nOpenAI et al, 2019\n), we depended on\nAutomatic domain randomization\n(\nADR\n) to generate a curriculum by growing a distribution of environments with increasing complexity. The difficulty of each task (i.e. solving a Rubik’s cube in a set of environments) depends on the randomization ranges of various environmental parameters. Even with a simplified assumption that all the environmental parameters are uncorrelated, we were able to create a decent curriculum for our robot hand to learn the task.\nTeacher-Guided Curriculum\n#\nThe idea of\nAutomatic Curriculum Learning\nwas proposed by\nGraves, et al. 2017\nslightly earlier. It considers a $N$-task curriculum as an\n$N$-armed bandit\nproblem and an adaptive policy which learns to optimize the returns from this bandit.\nTwo categories of learning signals have been considered in the paper:\nLoss-driven progress: the loss function change before and after one gradient update. This type of reward signals tracks the speed of the learning process, because the greatest task loss decrease is equivalent to the fastest learning.\nComplex-driven progress: the KL divergence between posterior and prior distribution over network weights. This type of learning signals are inspired by the\nMDL\nprinciple, “increasing the model complexity by a certain amount is only worthwhile if it compresses the data by a greater amount”. The model complexity is therefore expected to increase most in response to the model nicely generalizing to training examples.\nThis framework of proposing curriculum automatically through another RL agent was formalized as\nTeacher-Student Curriculum Learning\n(\nTSCL\n;\nMatiisen, et al. 2017\n). In TSCL, a\nstudent\nis an RL agent working on actual tasks while a\nteacher\nagent is a policy for selecting tasks. The student aims to master a complex task that might be hard to learn directly. To make this task easier to learn, we set up the teacher agent to guide the student’s training process by picking proper sub-tasks.\nThe setup of teacher-student curriculum learning. (Image source:\nMatiisen, et al. 2017\n+ my annotation in red.)\nIn the process, the student should learn tasks which:\ncan help the student make fastest learning progress, or\nare at risk of being forgotten.\nNote: The setup of framing the teacher model as an RL problem feels quite similar to Neural Architecture Search (NAS), but differently the RL model in TSCL operates on the task space and NAS operates on the main model architecture space.\nTraining the teacher model is to solve a\nPOMDP\nproblem:\nThe unobserved $s_t$ is the full state of the student model.\nThe observed $o = (x_t^{(1)}, \\dots, x_t^{(N)})$ are a list of scores for $N$ tasks.\nThe action $a$ is to pick on subtask.\nThe reward per step is the score delta.$r_t = \\sum_{i=1}^N x_t^{(i)} - x_{t-1}^{(i)}$ (i.e., equivalent to maximizing the score of all tasks at the end of the episode).\nThe method of estimating learning progress from noisy task scores while balancing exploration vs exploitation can be borrowed from the non-stationary multi-armed bandit problem — use\nε-greedy\n, or\nThompson sampling\n.\nThe core idea, in summary, is to use one policy to propose tasks for another policy to learn better. Interestingly, both works above (in the discrete task space) found that uniformly sampling from all tasks is a surprisingly strong benchmark.\nWhat if the task space is continuous?\nPortelas, et al. (2019)\nstudied a continuous teacher-student framework, where the teacher has to sample parameters from continuous task space to generate a learning curriculum. Given a newly sampled parameter $p$, the absolute learning progress (short for ALP) is measured as $\\text{ALP}_p = \\vert r - r_\\text{old} \\vert$, where $r$ is the episodic reward associated with $p$ and $r_\\text{old}$ is the reward associated with $p_\\text{old}$. Here, $p_\\text{old}$ is a previous sampled parameter closest to $p$ in the task space, which can be retrieved by nearest neighbor. Note that how this ALP score is different from learning signals in\nTSCL\nor\nGrave, et al. 2017\nabove: ALP score measures the reward difference between two tasks rather than performance at two time steps of the same task.\nOn top of the task parameter space, a Gaussian mixture model is trained to fit the distribution of $\\text{ALP}_p$ over $p$. ε-greedy is used when sampling the tasks: with some probability, sampling a random task; otherwise sampling proportionally to ALP score from the GMM model.\nThe algorithm of ALP-GMM (absolute learning progress Gaussian mixture model). (Image source:\nPortelas, et al., 2019\n)\nCurriculum through Self-Play\n#\nDifferent from the teacher-student framework, two agents are doing very different things. The teacher learns to pick a task for the student without any knowledge of the actual task content. What if we want to make both train on the main task directly? How about even make them compete with each other?\nSukhbaatar, et al. (2017)\nproposed a framework for automatic curriculum learning through\nasymmetric self-play\n. Two agents, Alice and Bob, play the same task with different goals: Alice challenges Bob to achieve the same state and Bob attempts to complete it as fast as he can.\nIllustration of the self-play setup when training two agents. The example task is\nMazeBase\n: An agent is asked to reach a goal flag in a maze with a light switch, a key and a wall with a door. Toggling the key switch can open or close the door and Turning off the light makes only the glowing light switch available to the agent. (Image source:\nSukhbaatar, et al. 2017\n)\nLet us consider Alice and Bob as two separate copies for one RL agent trained in the same environment but with different brains. Each of them has independent parameters and loss objective. The self-play-driven training consists of two types of episodes:\nIn the\nself-play episode\n, Alice alters the state from $s_0$ to $s_t$ and then Bob is asked to return the environment to its original state $s_0$ to get an internal reward.\nIn the\ntarget task episode\n, Bob receives an external reward if he visits the target flag.\nNote that since B has to repeat the actions between the same pair of $(s_0, s_t)$ of A, this framework only works in reversible or resettable environments.\nAlice should learn to push Bob out of his comfort zone, but not give him impossible tasks. Bob’s reward is set as $R_B = -\\gamma t_B$ and Alice’s reward is $R_A = \\gamma \\max(0, t_B - t_A)$, where $t_B$ is the total time for B to complete the task, $t_A$ is the time until Alice performs the STOP action and $\\gamma$ is a scalar constant to rescale the reward to be comparable with the external task reward. If B fails a task, $t_B = t_\\max - t_A$.\nBoth policies are goal-conditioned. The losses imply:\nB wants to finish a task asap.\nA prefers tasks that take more time of B.\nA does not want to take too many steps when B is failing.\nIn this way, the interaction between Alice and Bob automatically builds a curriculum of increasingly challenging tasks. Meanwhile, as A has done the task herself before proposing the task to B, the task is guaranteed to be solvable.\nThe paradigm of A suggesting tasks and then B solving them does sound similar to the Teacher-Student framework. However, in asymmetric self-play, Alice, who plays a teacher role, also works on the same task to find challenging cases for Bob, rather than optimizes B’s learning process explicitly.\nAutomatic Goal Generation\n#\nOften RL policy needs to be able to perform over a set of tasks. The goal should be carefully chosen so that at every training stage, it would not be too hard or too easy for the current policy. A goal $g \\in \\mathcal{G}$ can be defined as a set of states $S^g$ and a goal is considered as achieved whenever an agent arrives at any of those states.\nThe approach of Generative Goal Learning (\nFlorensa, et al. 2018\n) relies on a\nGoal GAN\nto generate desired goals automatically. In their experiment, the reward is very sparse, just a binary flag for whether a goal is achieved or not and the policy is conditioned on goal,\n$$\n\\begin{aligned}\n\\pi^{*}(a_t\\vert s_t, g) &= \\arg\\max_\\pi \\mathbb{E}_{g\\sim p_g(.)} R^g(\\pi) \\\\\n\\text{where }R^g(\\pi) &= \\mathbb{E}_\\pi(.\\mid s_t, g) \\mathbf{1}[\\exists t \\in [1,\\dots, T]: s_t \\in S^g]\n\\end{aligned}\n$$\nHere $R^g(\\pi)$ is the expected return, also equivalent to the success probability. Given sampled trajectories from the current policy, as long as any state belongs to the goal set, the return will be positive.\nTheir approach iterates through 3 steps until the policy converges:\nLabel a set of goals based on whether they are at the appropriate level of difficulty for the current policy.\nThe set of goals at the appropriate level of difficulty are named\nGOID\n(short for “Goals of Intermediate Difficulty”).\n$\\text{GOID}_i := \\{g : R_\\text{min} \\leq R^g(\\pi_i) \\leq R_\\text{max} \\} \\subseteq G$\nHere $R_\\text{min}$ and $R_\\text{max}$ can be interpreted as a minimum and maximum probability of reaching a goal over T time-steps.\nTrain a Goal GAN model using labelled goals from step 1 to produce new goals\nUse these new goals to train the policy, improving its coverage objective.\nThe Goal GAN generates a curriculum automatically:\nGenerator $G(z)$: produces a new goal. => expected to be a goal uniformly sampled from $GOID$ set.\nDiscriminator $D(g)$: evaluates whether a goal can be achieved. => expected to tell whether a goal is from $GOID$ set.\nThe Goal GAN is constructed similar to LSGAN (Least-Squared GAN;\nMao et al., (2017)\n), which has better stability of learning compared to vanilla GAN. According to LSGAN, we should minimize the following losses for $D$ and $G$ respectively:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{LSGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{LSGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nwhere $a$ is the label for fake data, $b$ for real data, and $c$ is the value that $G$ wants $D$ to believe for fake data. In LSGAN paper’s experiments, they used $a=-1, b=1, c=0$.\nThe Goal GAN introduces an extra binary flag $y_b$ indicating whether a goal $g$ is real ($y_g = 1$) or fake ($y_g = 0$) so that the model can use negative samples for training:\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{GoalGAN}(D) &= \\frac{1}{2} \\mathbb{E}_{g \\sim p_\\text{data}(g)} [ (D(g) - b)^2 + (1-y_g) (D(g) - a)^2] + \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - a)^2] \\\\\n\\mathcal{L}_\\text{GoalGAN}(G) &= \\frac{1}{2} \\mathbb{E}_{z \\sim p_z(z)} [ (D(G(z)) - c)^2]\n\\end{aligned}\n$$\nThe algorithm of Generative Goal Learning. (Image source: (\nFlorensa, et al. 2018\n)\nFollowing the same idea,\nRacaniere & Lampinen, et al. (2019)\ndesigns a method to make the objectives of goal generator more sophisticated. Their method contains three components, same as generative goal learning above:\nSolver\n/Policy $\\pi$: In each episode, the solver gets a goal $g$ at the beginning and get a single binary reward $R^g$ at the end.\nJudge\n/Discriminator $D(.)$: A classifier to predict the binary reward (whether goal can be achieved or not); precisely it outputs the logit of a probability of achieving the given goal, $\\sigma(D(g)) = p(R^g=1\\vert g)$, where $\\sigma$ is the sigmoid function.\nSetter\n/Generator $G(.)$: The goal setter takes as input a desired feasibility score $f \\in \\text{Unif}(0, 1)$ and generates $g = G(z, f)$, where the latent variable $z$ is sampled by $z \\sim \\mathcal{N}(0, I)$. The goal generator is designed to reversible, so $G^{-1}$ can map backwards from a goal $g$ to a latent $z = G^{-1}(g, f)$\nThe generator is optimized with three objectives:\nGoal\nvalidity\n: The proposed goal should be achievable by an expert policy. The corresponding generative loss is designed to increase the likelihood of generating goals that the solver policy has achieved before (like in\nHER\n).\n$\\mathcal{L}_\\text{val}$ is the negative log-likelihood of generated goals that have been solved by the solver in the past.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{val} = \\mathbb{E}_{\\substack{\n  g \\sim \\text{ achieved by solver}, \\\\\n  \\xi \\in \\text{Uniform}(0, \\delta), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ -\\log p(G^{-1}(g + \\xi, f)) \\big]\n\\end{align*}\n$$\nGoal\nfeasibility\n: The proposed goal should be achievable by the current policy; that is, the level of difficulty should be appropriate.\n$\\mathcal{L}_\\text{feas}$ is the output probability by the judge model $D$ on the generated goal $G(z, f)$ should match the desired $f$.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{feas} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ D(G(z, f)) - \\sigma^{-1}(f)^2 \\big]\n\\end{align*}\n$$\nGoal\ncoverage\n: We should maximize the entropy of generated goals to encourage diverse goal and to improve the coverage over the goal space.\n$$\n\\begin{align*}\n\\mathcal{L}_\\text{cov} = \\mathbb{E}_{\\substack{\n  z \\in \\mathcal{N}(0, 1), \\\\\n  f \\in \\text{Uniform}(0, 1)\n}} \\big[ \\log p(G(z, f)) \\big]\n\\end{align*}\n$$\nTheir experiments showed complex environments require all three losses above. When the environment is changing between episodes, both the goal generator and the discriminator need to be conditioned on environmental observation to produce better results. If there is a desired goal distribution, an additional loss can be added to match a desired goal distribution using Wasserstein distance. Using this loss, the generator can push the solver toward mastering the desired tasks more efficiently.\nTraining schematic for the (a) solver/policy, (b) judge/discriminator, and (c) setter/goal generator models. (Image source:\nRacaniere & Lampinen, et al., 2019\n)\nSkill-Based Curriculum\n#\nAnother view is to decompose what an agent is able to complete into a variety of skills and each skill set could be mapped into a task. Let’s imagine when an agent interacts with the environment in an unsupervised manner, is there a way to discover useful skills from such interaction and further build into the solutions for more complicated tasks through a curriculum?\nJabri, et al. (2019)\ndeveloped an automatic curriculum,\nCARML\n(short for “Curricula for Unsupervised Meta-Reinforcement Learning”), by modeling unsupervised trajectories into a latent skill space, with a focus on training\nmeta-RL\npolicies (i.e. can transfer to unseen tasks). The setting of training environments in CARML is similar to\nDIAYN\n. Differently, CARML is trained on pixel-level observations but DIAYN operates on the true state space. An RL algorithm $\\pi_\\theta$, parameterized by $\\theta$, is trained via unsupervised interaction formulated as a CMP combined with a learned reward function $r$. This setting naturally works for the meta-learning purpose, since a customized reward function can be given only at the test time.\nAn illustration of CARML, containing two steps: (1) organizing experiential data into the latent skill space; (2) meta-training the policy with the reward function constructed from the learned skills. (Image source:\nJabri, et al 2019\n)\nCARML is framed as a\nvariational Expectation-Maximization (EM)\n.\n(1)\nE-Step\n: This is the stage for organizing experiential data. Collected trajectories are modeled with a mixture of latent components forming the\nbasis\nof\nskills\n.\nLet $z$ be a latent task variable and $q_\\phi$ be a variational distribution of $z$, which could be a mixture model with discrete $z$ or a VAE with continuous $z$. A variational posterior $q_\\phi(z \\vert s)$ works like a classifier, predicting a skill given a state, and we would like to maximize $q_\\phi(z \\vert s)$ to discriminate between data produced by different skills as much as possible. In E-step, $q_\\phi$ is fitted to a set of trajectories produced by $\\pi_\\theta$.\nPrecisely, given a trajectory $\\tau = (s_1,\\dots,s_T)$, we would like to find $\\phi$ such that\n$$\n\\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\log q_\\phi(\\tau \\vert z) \\big]\n= \\max_\\phi \\mathbb{E}_{z\\sim q_\\phi(z)} \\big[ \\sum_{s_i \\in \\tau} \\log q_\\phi(s_i \\vert z) \\big]\n$$\nA simplifying assumption is made here to ignore the order of states in one trajectory.\n(2)\nM-Step\n: This is the stage for doing meta-RL training with $\\pi_\\theta$. The learned skill space is considered as a training task distribution. CARML is agnostic to the type of meta-RL algorithm for policy parameter updates.\nGiven a trajectory $\\tau$, it makes sense for the policy to maximize the mutual information between $\\tau$ and $z$, $I(\\tau;z) = H(\\tau) - H(\\tau \\vert z)$, because:\nmaximizing $H(\\tau)$ => diversity in the policy data space; expected to be large.\nminimizing $H(\\tau \\vert z)$ => given a certain skill, the behavior should be restricted; expected to be small.\nThen we have,\n$$\n\\begin{aligned}\nI(\\tau; z) \n&= \\mathcal{H}(z) - \\mathcal{H}(z \\vert s_1,\\dots, s_T) \\\\\n&\\geq \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(z) - \\mathcal{H}(z\\vert s)] & \\scriptstyle{\\text{; discard the order of states.}} \\\\\n&= \\mathbb{E}_{s \\in \\tau} [\\mathcal{H}(s_t) - \\mathcal{H}(s\\vert z)] & \\scriptstyle{\\text{; by definition of MI.}} \\\\\n&= \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\log q_\\phi(s|z) - \\log \\pi_\\theta(s)] \\\\\n&\\approx \\mathbb{E}_{z\\sim q_\\phi(z), s\\sim \\pi_\\theta(s|z)} [\\color{green}{\\log q_\\phi(s|z) - \\log q_\\phi(s)}] & \\scriptstyle{\\text{; assume learned marginal distr. matches policy.}}\n\\end{aligned}\n$$\nWe can set the reward as $\\log q_\\phi(s \\vert z) - \\log q_\\phi(s)$, as shown in the\nred\npart in the equation above. In order to balance between task-specific exploration (as in\nred\nbelow) and latent skill matching (as in\nblue\nbelow) , a parameter $\\lambda \\in [0, 1]$ is added. Each realization of $z \\sim q_\\phi(z)$ induces a reward function $r_z(s)$ (remember that reward + CMP => MDP) as follows:\n$$\n\\begin{aligned}\nr_z(s)\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s) \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log \\frac{q_\\phi(s|z) q_\\phi(z)}{q_\\phi(z|s)} \\\\\n&= \\lambda \\log q_\\phi(s|z) - \\log q_\\phi(s|z) - \\log q_\\phi(z) + \\log q_\\phi(z|s) \\\\\n&= (\\lambda - 1) \\log \\color{red}{q_\\phi(s|z)} + \\color{blue}{\\log q_\\phi(z|s)} + C\n\\end{aligned}\n$$\nThe algorithm of CARML. (Image source:\nJabri, et al 2019\n)\nLearning a latent skill space can be done in different ways, such as in\nHausman, et al. 2018\n. The goal of their approach is to learn a task-conditioned policy, $\\pi(a \\vert s, t^{(i)})$, where $t^{(i)}$ is from a discrete list of $N$ tasks, $\\mathcal{T} = [t^{(1)}, \\dots, t^{(N)}]$. However, rather than learning $N$ separate solutions, one per task, it would be nice to learn a latent skill space so that each task could be represented in a distribution over skills and thus skills are\nreused between tasks\n. The policy is defined as $\\pi_\\theta(a \\vert s,t) = \\int \\pi_\\theta(a \\vert z,s,t) p_\\phi(z \\vert t)\\mathrm{d}z$, where $\\pi_\\theta$ and $p_\\phi$ are policy and embedding networks to learn, respectively. If $z$ is discrete, i.e. drawn from a set of $K$ skills, then the policy becomes a mixture of $K$ sub-policies. The policy training uses\nSAC\nand the dependency on $z$ is introduced in the entropy term.\nCurriculum through Distillation\n#\n[I was thinking of the name of this section for a while, deciding between cloning, inheritance, and distillation. Eventually, I picked distillation because it sounds the coolest B-)]\nThe motivation for the\nprogressive neural network\n(\nRusu et al. 2016\n) architecture is to efficiently transfer learned skills between different tasks and in the meantime avoid catastrophic forgetting. The curriculum is realized through a set of progressively stacked neural network towers (or “columns”, as in the paper).\nA progressive network has the following structure:\nIt starts with a single column containing $L$ layers of neurons, in which the corresponding activation layers are labelled as $h^{(1)}_i, i=1, \\dots, L$. We first train this single-column network for one task to convergence, achieving parameter config $\\theta^{(1)}$.\nOnce switch to the next task, we need to add a new column to adapt to the new context while freezing $\\theta^{(1)}$ to lock down the learned skills from the previous task. The new column has activation layers labelled as $h^{(2)}_i, i=1, \\dots, L$, and parameters $\\theta^{(2)}$.\nStep 2 can be repeated with every new task. The $i$-th layer activation in the $k$-th column depends on the previous activation layers in all the existing columns:\n$$\n h^{(k)}_i = f(W^{(k)}_i h^{(k)}_{i-1} + \\sum_{j < k} U_i^{(k:j)} h^{(j)}_{i-1})\n $$\nwhere $W^{(k)}_i$ is the weight matrix of the layer $i$ in the column $k$; $U_i^{(k:j)}, j < k$ are the weight matrices for projecting the layer $i-1$ of the column $j$ to the layer $i$ of column $k$ ($ j < k $). The above weights matrices should be learned. $f(.)$ is a non-linear activation function by choice.\nThe progressive neural network architecture. (Image source:\nRusu, et al. 2017\n)\nThe paper experimented with Atari games by training a progressive network on multiple games to check whether features learned in one game can transfer to another. That is indeed the case. Though interestingly, learning a high dependency on features in the previous columns does not always indicate good transfer performance on the new task. One hypothesis is that features learned from the old task might introduce biases into the new task, leading to policy getting trapped in a sub-optimal solution. Overall, the progressive network works better than only fine-tuning the top layer and can achieve similar transfer performance as fine-tuning the entire network.\nOne use case for the progressive network is to do sim2real transfer (\nRusu, et al. 2017\n), in which the first column is trained in simulator with a lot of samples and then the additional columns (could be for different real-world tasks) are added and trained with a few real data samples.\nCzarnecki, et al. (2018)\nproposed another RL training framework,\nMix & Match\n(short for\nM&M\n) to provide curriculum through coping knowledge between agents. Given a sequence of agents from simple to complex, $\\pi_1, \\dots, \\pi_K$, each parameterized with some shared weights (e.g. by shared some lower common layers). M&M trains a mixture of agents, but only the final performance of the most complex one $\\pi_K$ matters.\nIn the meantime, M&M learns a categorical distribution $c \\sim \\text{Categorical}(1, \\dots, K \\vert \\alpha)$ with\npmf\n$p(c=i) = \\alpha_i$ probability to pick which policy to use at a given time. The mixed M&M policy is a simple weighted sum: $\\pi_\\text{mm}(a \\vert s) = \\sum_{i=1}^K \\alpha_i \\pi_i(a \\vert s)$. Curriculum learning is realized by dynamically adjusting $\\alpha_i$, from $\\alpha_K=0$ to $\\alpha_K=1$. The tuning of $\\alpha$ can be manual or through\npopulation-based training\n.\nTo encourage cooperation rather than competition among policies, besides the RL loss $\\mathcal{L}_\\text{RL}$, another\ndistillation\n-like loss $\\mathcal{L}_\\text{mm}(\\theta)$ is added. The knowledge transfer loss $\\mathcal{L}_\\text{mm}(\\theta)$ measures the KL divergence between two policies, $\\propto D_\\text{KL}(\\pi_{i}(. \\vert s) | \\pi_j(. \\vert s))$ for $i < j$. It encourages complex agents to match the simpler ones early on. The final loss is $\\mathcal{L} = \\mathcal{L}_\\text{RL}(\\theta \\vert \\pi_\\text{mm}) + \\lambda \\mathcal{L}_\\text{mm}(\\theta)$.\nThe Mix & Match architecture for training a mixture of policies.  (Image source:\nCzarnecki, et al., 2018\n)\nCitation\n#\nCited as:\nWeng, Lilian. (Jan 2020). Curriculum for reinforcement learning. Lil’Log. https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/.\nOr\n@article{weng2020curriculum,\n  title   = \"Curriculum for Reinforcement Learning\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2020\",\n  month   = \"Jan\",\n  url     = \"https://lilianweng.github.io/posts/2020-01-29-curriculum-rl/\"\n}\nReferences\n#\n[1] Jeffrey L. Elman.\n“Learning and development in neural networks: The importance of starting small.”\nCognition 48.1 (1993): 71-99.\n[2] Yoshua Bengio, et al.\n“Curriculum learning.”\nICML 2009.\n[3] Daphna Weinshall, Gad Cohen, and Dan Amir.\n“Curriculum learning by transfer learning: Theory and experiments with deep networks.”\nICML 2018.\n[4] Wojciech Zaremba and Ilya Sutskever.\n“Learning to execute.”\narXiv preprint arXiv:1410.4615 (2014).\n[5] Tambet Matiisen, et al.\n“Teacher-student curriculum learning.”\nIEEE Trans. on neural networks and learning systems (2017).\n[6] Alex Graves, et al.\n“Automated curriculum learning for neural networks.”\nICML 2017.\n[7]  Remy Portelas, et al.\nTeacher algorithms for curriculum learning of Deep RL in continuously parameterized environments\n. CoRL 2019.\n[8] Sainbayar Sukhbaatar, et al.\n“Intrinsic Motivation and Automatic Curricula via Asymmetric Self-Play.”\nICLR 2018.\n[9] Carlos Florensa, et al.\n“Automatic Goal Generation for Reinforcement Learning Agents”\nICML 2019.\n[10] Sebastien Racaniere & Andrew K. Lampinen, et al.\n“Automated Curriculum through Setter-Solver Interactions”\nICLR 2020.\n[11] Allan Jabri, et al.\n“Unsupervised Curricula for Visual Meta-Reinforcement Learning”\nNeuriPS 2019.\n[12] Karol Hausman, et al.\n“Learning an Embedding Space for Transferable Robot Skills “\nICLR 2018.\n[13] Josh Merel, et al.\n“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”\narXiv preprint arXiv:1911.06636 (2019).\n[14] OpenAI, et al.\n“Solving Rubik’s Cube with a Robot Hand.”\narXiv preprint arXiv:1910.07113 (2019).\n[15] Niels Justesen, et al.\n“Illuminating Generalization in Deep Reinforcement Learning through Procedural Level Generation”\nNeurIPS 2018 Deep RL Workshop.\n[16] Karl Cobbe, et al.\n“Quantifying Generalization in Reinforcement Learning”\narXiv preprint arXiv:1812.02341 (2018).\n[17] Andrei A. Rusu et al.\n“Progressive Neural Networks”\narXiv preprint arXiv:1606.04671 (2016).\n[18] Andrei A. Rusu et al.\n“Sim-to-Real Robot Learning from Pixels with Progressive Nets.”\nCoRL 2017.\n[19] Wojciech Marian Czarnecki, et al.\n“Mix & Match – Agent Curricula for Reinforcement Learning.”\nICML 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:43:47Z",
            "title": "Curriculum for Reinforcement Learning | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/18b05e29ab9d/code/body-000.txt",
                "chars": 262,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "http_403",
                "url": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1802.03796",
                "bytes": 585421,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6faa67cb3f93d77c9d67.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1410.4615",
                "bytes": 559518,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a33b0ab1229e8af644d2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.10729",
                "bytes": 999159,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/09fa801246d0c67848b3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1812.02341",
                "bytes": 7003398,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/9e7f2dbe5f93a5d5e4a2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.01753",
                "bytes": 2970636,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b1d64aa9e85c6a88437.pdf"
              },
              {
                "status": "http_404",
                "url": "https://arxiv.org/pdf/1910.07113.",
                "retried_at": "2026-10-20T17:55:56Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1704.03003",
                "bytes": 3091441,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b98bef9914392e12f875.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.00183",
                "bytes": 1347985,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/79adfbe28098dc1e1722.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07224",
                "bytes": 2628539,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f72a60e37e01560d1e27.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.05407",
                "bytes": 2032765,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/f4e7d6c2102fc058dc62.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1705.06366",
                "bytes": 6654321,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3bc7353a8badf27f9df4.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1611.04076",
                "bytes": 3719760,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/7af911a9191b6055b1a3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.12892",
                "bytes": 2506625,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/a8a071c792508aea939d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1707.01495",
                "bytes": 2464277,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/81859ed20fbb79d50eec.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1912.04226",
                "bytes": 3425807,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0b8a67f584549b501f6b.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1606.04671",
                "bytes": 4278357,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/3304a794e8bdd5c42143.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1610.04286",
                "bytes": 1087389,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/b715f19efae8d26a11d0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.01780",
                "bytes": 4106903,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5c9572e1111a7e6fdcb1.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1511.06295",
                "bytes": 727329,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/270be775129eb54c13ef.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1911.06636",
                "bytes": 5806364,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/e62ae132fefd8cc55d44.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.07113",
                "bytes": 5194320,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/2ef619bdd5bd429418f2.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 32251,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_403；http_404",
            "raw_html": "attachments/18b05e29ab9d/pages/source.html",
            "local_html": "attachments/18b05e29ab9d/pages/article.html",
            "body_base_path": "attachments/18b05e29ab9d/pages/",
            "body_markdown_path": "attachments/18b05e29ab9d/pages/article.md",
            "links": [
              {
                "href": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.128.4487&rep=rep1&type=pdf",
                "label": "Elman 1993",
                "type": "a"
              },
              {
                "href": "https://www.researchgate.net/profile/Y_Bengio/publication/221344862_Curriculum_learning/links/546cd2570cf2193b94c577ac/Curriculum-learning.pdf",
                "label": "Bengio, et al. (2009)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1802.03796",
                "label": "Weinshall, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1410.4615",
                "label": "Zaremba & Sutskever (2014)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Procedural_generation",
                "label": "PCG",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-06-23-meta-rl/",
                "label": "meta-RL",
                "type": "a"
              },
              {
                "href": "http://www.gvgai.net/",
                "label": "GVGAI",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/quantifying-generalization-in-reinforcement-learning/",
                "label": "CoinRun",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/procgen-benchmark/",
                "label": "Procgen benchmark",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.10729",
                "label": "Justesen, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1812.02341",
                "label": "Cobbe, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.01753",
                "label": "Wang et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113.",
                "label": "OpenAI et al, 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1704.03003",
                "label": "Graves, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-01-23-multi-armed-bandit/",
                "label": "$N$-armed bandit",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Minimum_description_length",
                "label": "MDL",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.00183",
                "label": "Matiisen, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Partially_observable_Markov_decision_process",
                "label": "POMDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07224",
                "label": "Portelas, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.05407",
                "label": "Sukhbaatar, et al. (2017)",
                "type": "a"
              },
              {
                "href": "https://github.com/facebook/MazeBase",
                "label": "MazeBase",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1705.06366",
                "label": "Florensa, et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1611.04076",
                "label": "Mao et al., (2017)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.12892",
                "label": "Racaniere & Lampinen, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1707.01495",
                "label": "HER",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1912.04226",
                "label": "Jabri, et al. (2019)",
                "type": "a"
              },
              {
                "href": "https://chrischoy.github.io/research/Expectation-Maximization-and-Variational-Inference/",
                "label": "variational Expectation-Maximization (EM)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Basis_(linear_algebra)",
                "label": "basis",
                "type": "a"
              },
              {
                "href": "https://openreview.net/forum?id=rk07ZXZRb",
                "label": "Hausman, et al. 2018",
                "type": "a"
              },
              {
                "href": "http://127.0.0.1:4000/lil-log/2018/04/07/policy-gradient-algorithms.html",
                "label": "SAC",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1606.04671",
                "label": "Rusu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1610.04286",
                "label": "Rusu, et al. 2017",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.01780",
                "label": "Czarnecki, et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Probability_mass_function",
                "label": "pmf",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/",
                "label": "population-based training",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1511.06295",
                "label": "distillation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1911.06636",
                "label": "“Reusable neural skill embeddings for vision-guided whole body movement and object manipulation”",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.07113",
                "label": "“Solving Rubik’s Cube with a Robot Hand.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
          "status": "partial",
          "article_id": "6d3d9dca0d80",
          "local_path": "series-follow/1601/repair/bc5c14725294dbccfbb0.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
              "bytes": 117546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/834dca5b0e8f45a5caae.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
              "bytes": 2066932,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/db79205a3fdc6b1972ac.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
              "bytes": 330686,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f4bbdd9860111196027c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
              "bytes": 77027,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7663a2768e6a5304e97d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
              "bytes": 92546,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c0097767c26c92046b06.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
              "bytes": 710268,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6a8653bd53396d46c1fa.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
              "bytes": 1618413,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ec2093ad281b035abb92.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
              "bytes": 292184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5c3e06f69064d46da7a3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
              "bytes": 372187,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f8d914d42f0dceb916fe.png"
            }
          ],
          "article": {
            "id": "6d3d9dca0d80",
            "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "source_excel_row": 1602,
            "source_url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "bytes": 117546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-834dca5b0e8f45a5caae.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-gradient-vector-pixel-location.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "bytes": 2066932,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-db79205a3fdc6b1972ac.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "bytes": 330686,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f4bbdd9860111196027c.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2004-sobel-operator.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "bytes": 77027,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-7663a2768e6a5304e97d.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/HOG-histogram-creation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "bytes": 92546,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-c0097767c26c92046b06.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/block_histogram.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "bytes": 710268,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-6a8653bd53396d46c1fa.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/image-segmentation-indoor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "bytes": 1618413,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-ec2093ad281b035abb92.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "bytes": 292184,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-5c3e06f69064d46da7a3.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/manu-2013-segmentation.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "bytes": 372187,
                "reused": true,
                "local_path": "attachments/6d3d9dca0d80/images/body-f8d914d42f0dceb916fe.png",
                "src": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/selective-search-algorithm.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "I’ve never worked in the field of computer vision and has no idea how the magic could work when an autonomous car is configured to tell apart a stop sign from a pedestrian in a red hat. To motivate myself to look into the maths behind object recognition and detection algorithms, I’m writing a few posts on this topic “Object Detection for Dummies”. This post, part 1, starts with super rudimentary concepts in image processing and a few methods for image segmentation. Nothing related to deep neural networks yet. Deep learning models for object detection and recognition will be discussed in\nPart 2\nand\nPart 3\n.\nDisclaimer: When I started, I was using “object recognition” and “object detection” interchangeably. I don’t think they are the same: the former is more about telling whether an object exists in an image while the latter needs to spot where the object is. However, they are highly related and many object recognition algorithms lay the foundation for detection.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nImage Gradient Vector\n#\nFirst of all, I would like to make sure we can distinguish the following terms. They are very similar, closely related, but not exactly the same.\nDerivative\nDirectional Derivative\nGradient\nValue type\nScalar\nScalar\nVector\nDefinition\nThe rate of change of a function $f(x,y,z,…)$ at a point $(x_0,y_0,z_0,…)$, which is the slope of the tangent line at the point.\nThe instantaneous rate of change of $f(x,y,z, …)$ in the direction of an unit vector $\\vec{u}$.\nIt points in the direction of the greatest rate of increase of the function, containing all the partial derivative information of a multivariable function.\nIn the image processing, we want to know the direction of colors changing from one extreme to the other (i.e. black to white on a grayscale image). Therefore, we want to measure “gradient” on pixels of colors. The gradient on an image is discrete because each pixel is independent and cannot be further split.\nThe\nimage gradient vector\nis defined as a metric for every individual pixel, containing the pixel color changes in both x-axis and y-axis. The definition is aligned with the gradient of a continuous multi-variable function, which is a vector of partial derivatives of all the variables. Suppose f(x, y) records the color of the pixel at location (x, y), the gradient vector of the pixel (x, y) is defined as follows:\n$$\n\\begin{align*}\n\\nabla f(x, y)\n= \\begin{bmatrix}\n  g_x \\\\\n  g_y\n\\end{bmatrix}\n= \\begin{bmatrix}\n  \\frac{\\partial f}{\\partial x} \\\\[6pt]\n  \\frac{\\partial f}{\\partial y}\n\\end{bmatrix}\n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n\\end{align*}\n$$\nThe $\\frac{\\partial f}{\\partial x}$ term is the partial derivative on the x-direction, which is computed as the color difference between the adjacent pixels on the left and right of the target, f(x+1, y) - f(x-1, y). Similarly, the $\\frac{\\partial f}{\\partial y}$ term is the partial derivative on the y-direction, measured as f(x, y+1) - f(x, y-1), the color difference between the adjacent pixels above and below the target.\nThere are two important attributes of an image gradient:\nMagnitude\nis the L2-norm of the vector, $g = \\sqrt{ g_x^2 + g_y^2 }$.\nDirection\nis the arctangent of the ratio between the partial derivatives on two directions, $\\theta = \\arctan{(g_y / g_x)}$.\nTo compute the gradient vector of a target pixel at location (x, y), we need to know the colors of its four neighbors (or eight surrounding pixels depending on the kernel).\nThe gradient vector of the example in is:\n$$\n\\begin{align*}\n\\nabla f \n= \\begin{bmatrix}\n  f(x+1, y) - f(x-1, y)\\\\\n  f(x, y+1) - f(x, y-1)\n\\end{bmatrix}\n= \\begin{bmatrix}\n  55-105\\\\\n  90-40\n\\end{bmatrix}\n= \\begin{bmatrix}\n  -50\\\\\n  50\n\\end{bmatrix}\n\\end{align*}\n$$\nThus,\nthe magnitude is $\\sqrt{50^2 + (-50)^2} = 70.7107$, and\nthe direction is $\\arctan{(-50/50)} = -45^{\\circ}$.\nRepeating the gradient computation process for every pixel iteratively is too slow. Instead, it can be well translated into applying a convolution operator on the entire image matrix, labeled as $\\mathbf{A}$ using one of the specially designed convolutional kernels.\nLet’s start with the x-direction of the example in Fig 1. using the kernel $[-1,0,1]$ sliding over the x-axis; $\\ast$ is the convolution operator:\n$$\n\\begin{align*}\n\\mathbf{G}_x &= \n[-1, 0, 1] \\ast [105, 255, 55] = -105 + 0 + 55 = -50\n\\end{align*}\n$$\nSimilarly, on the y-direction, we adopt the kernel $[+1, 0, -1]^\\top$:\n$$\n\\begin{align*}\n\\mathbf{G}_y &= \n[+1, 0, -1]^\\top \\ast\n\\begin{bmatrix}\n  90\\\\\n  255\\\\\n  40\n\\end{bmatrix} \n= 90 + 0 - 40 = 50\n\\end{align*}\n$$\nTry this in python:\nimport\nnumpy\nas\nnp\nimport\nscipy.signal\nas\nsig\ndata\n=\nnp\n.\narray([[\n0\n,\n105\n,\n0\n], [\n40\n,\n255\n,\n90\n], [\n0\n,\n55\n,\n0\n]])\nG_x\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n,\n0\n,\n1\n]]), mode\n=\n'valid'\n)\nG_y\n=\nsig\n.\nconvolve2d(data, np\n.\narray([[\n-\n1\n], [\n0\n], [\n1\n]]), mode\n=\n'valid'\n)\nThese two functions return\narray([[0], [-50], [0]])\nand\narray([[0, 50, 0]])\nrespectively. (Note that in the numpy array representation, 40 is shown in front of 90, so -1 is listed before 1 in the kernel correspondingly.)\nCommon Image Processing Kernels\n#\nPrewitt operator\n: Rather than only relying on four directly adjacent neighbors, the Prewitt operator utilizes eight surrounding pixels for smoother results.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-1 & 0 & +1 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +1 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -1 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nSobel operator\n: To emphasize the impact of directly adjacent pixels more, they get assigned with higher weights.\n$$\n\\mathbf{G}_x = \\begin{bmatrix}\n-1 & 0 & +1 \\\\\n-2 & 0 & +2 \\\\\n-1 & 0 & +1\n\\end{bmatrix} \\ast \\mathbf{A} \\text{ and }\n\\mathbf{G}_y = \\begin{bmatrix}\n+1 & +2 & +1 \\\\\n0 & 0 & 0 \\\\\n-1 & -2 & -1\n\\end{bmatrix} \\ast \\mathbf{A}\n$$\nDifferent kernels are created for different goals, such as edge detection, blurring, sharpening and many more. Check\nthis wiki page\nfor more examples and references.\nExample: Manu in 2004\n#\nLet’s run a simple experiment on the photo of Manu Ginobili in 2004 [[Download Image]({{ ‘/assets/data/manu-2004.jpg’ | relative_url }}){:target=\"_blank\"}] when he still had a lot of hair. For simplicity, the photo is converted to grayscale first. For colored images, we just need to repeat the same process in each color channel respectively.\nManu Ginobili in 2004 with hair. (Image source:\nManu Ginobili's bald spot through the years\n)\nimport\nnumpy\nas\nnp\nimport\nscipy\nimport\nscipy.signal\nas\nsig\n# With mode=\"L\", we force the image to be parsed in the grayscale, so it is\n# actually unnecessary to convert the photo color beforehand.\nimg\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2004.jpg\"\n, mode\n=\n\"L\"\n)\n# Define the Sobel operator kernels.\nkernel_x\n=\nnp\n.\narray([[\n-\n1\n,\n0\n,\n1\n],[\n-\n2\n,\n0\n,\n2\n],[\n-\n1\n,\n0\n,\n1\n]])\nkernel_y\n=\nnp\n.\narray([[\n1\n,\n2\n,\n1\n], [\n0\n,\n0\n,\n0\n], [\n-\n1\n,\n-\n2\n,\n-\n1\n]])\nG_x\n=\nsig\n.\nconvolve2d(img, kernel_x, mode\n=\n'same'\n)\nG_y\n=\nsig\n.\nconvolve2d(img, kernel_y, mode\n=\n'same'\n)\n# Plot them!\nfig\n=\nplt\n.\nfigure()\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\n# Actually plt.imshow() can handle the value scale well even if I don't do\n# the transformation (G_x + 255) / 2.\nax1\n.\nimshow((G_x\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax1\n.\nset_xlabel(\n\"Gx\"\n)\nax2\n.\nimshow((G_y\n+\n255\n)\n/\n2\n, cmap\n=\n'gray'\n); ax2\n.\nset_xlabel(\n\"Gy\"\n)\nplt\n.\nshow()\nApply Sobel operator kernel on the example image.\nYou might notice that most area is in gray. Because the difference between two pixel is between -255 and 255 and we need to convert them back to [0, 255] for the display purpose.\nA simple linear transformation ($\\mathbf{G}$ + 255)/2 would interpret all the zeros (i.e., constant colored background shows no change in gradient) as 125 (shown as gray).\nHistogram of Oriented Gradients (HOG)\n#\nThe Histogram of Oriented Gradients (HOG) is an efficient way to extract features out of the pixel colors for building an object recognition classifier. With the knowledge of image gradient vectors, it is not hard to understand how HOG works. Let’s start!\nHow HOG works\n#\nPreprocess the image, including resizing and color normalization.\nCompute the gradient vector of every pixel, as well as its magnitude and direction.\nDivide the image into many 8x8 pixel cells. In each cell, the magnitude values of these 64 cells are binned and cumulatively added into 9 buckets of unsigned direction (no sign, so 0-180 degree rather than 0-360 degree; this is a practical choice based on empirical experiments).\nFor better robustness, if the direction of the gradient vector of a pixel lays between two buckets, its magnitude does not all go into the closer one but proportionally split between two. For example, if a pixel’s gradient vector has magnitude 8 and degree 15, it is between two buckets for degree 0 and 20 and we would assign 2 to bucket 0 and 6 to bucket 20.\nThis interesting configuration makes the histogram much more stable when small distortion is applied to the image.\nHow to split one gradient vector's magnitude if its degress is between two degree bins. (Image source: https://www.learnopencv.com/histogram-of-oriented-gradients/)\nThen we slide a 2x2 cells (thus 16x16 pixels) block across the image. In each block region, 4 histograms of 4 cells are concatenated into one-dimensional vector of 36 values and then normalized to have an unit weight.\nThe final HOG feature vector is the concatenation of all the block vectors. It can be fed into a classifier like SVM for learning object recognition tasks.\nExample: Manu in 2004\n#\nLet’s reuse the same example image in the previous section. Remember that we have computed $\\mathbf{G}_x$ and $\\mathbf{G}_y$ for the whole image.\nN_BUCKETS\n=\n9\nCELL_SIZE\n=\n8\n# Each cell is 8x8 pixels\nBLOCK_SIZE\n=\n2\n# Each block is 2x2 cells\ndef\nassign_bucket_vals\n(m, d, bucket_vals):\nleft_bin\n=\nint(d\n/\n20.\n)\n# Handle the case when the direction is between [160, 180)\nright_bin\n=\n(int(d\n/\n20.\n)\n+\n1\n)\n%\nN_BUCKETS\nassert\n0\n<=\nleft_bin\n<\nright_bin\n<\nN_BUCKETS\nleft_val\n=\nm\n*\n(right_bin\n*\n20\n-\nd)\n/\n20\nright_val\n=\nm\n*\n(d\n-\nleft_bin\n*\n20\n)\n/\n20\nbucket_vals[left_bin]\n+=\nleft_val\nbucket_vals[right_bin]\n+=\nright_val\ndef\nget_magnitude_hist_cell\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target cell.\ncell_x\n=\nG_x[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\ncell_y\n=\nG_y[loc_x:loc_x\n+\nCELL_SIZE, loc_y:loc_y\n+\nCELL_SIZE]\nmagnitudes\n=\nnp\n.\nsqrt(cell_x\n*\ncell_x\n+\ncell_y\n*\ncell_y)\ndirections\n=\nnp\n.\nabs(np\n.\narctan(cell_y\n/\ncell_x)\n*\n180\n/\nnp\n.\npi)\nbuckets\n=\nnp\n.\nlinspace(\n0\n,\n180\n, N_BUCKETS\n+\n1\n)\nbucket_vals\n=\nnp\n.\nzeros(N_BUCKETS)\nmap(\nlambda\n(m, d): assign_bucket_vals(m, d, bucket_vals),\nzip(magnitudes\n.\nflatten(), directions\n.\nflatten())\n)\nreturn\nbucket_vals\ndef\nget_magnitude_hist_block\n(loc_x, loc_y):\n# (loc_x, loc_y) defines the top left corner of the target block.\nreturn\nreduce(\nlambda\narr1, arr2: np\n.\nconcatenate((arr1, arr2)),\n[get_magnitude_hist_cell(x, y)\nfor\nx, y\nin\nzip(\n[loc_x, loc_x\n+\nCELL_SIZE, loc_x, loc_x\n+\nCELL_SIZE],\n[loc_y, loc_y, loc_y\n+\nCELL_SIZE, loc_y\n+\nCELL_SIZE],\n)]\n)\nThe following code simply calls the functions to construct a histogram and plot it.\n# Random location [200, 200] as an example.\nloc_x\n=\nloc_y\n=\n200\nydata\n=\nget_magnitude_hist_block(loc_x, loc_y)\nydata\n=\nydata\n/\nnp\n.\nlinalg\n.\nnorm(ydata)\nxdata\n=\nrange(len(ydata))\nbucket_names\n=\nnp\n.\ntile(np\n.\narange(N_BUCKETS), BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(ydata)\n==\nN_BUCKETS\n*\n(BLOCK_SIZE\n*\nBLOCK_SIZE)\nassert\nlen(bucket_names)\n==\nlen(ydata)\nplt\n.\nfigure(figsize\n=\n(\n10\n,\n3\n))\nplt\n.\nbar(xdata, ydata, align\n=\n'center'\n, alpha\n=\n0.8\n, width\n=\n0.9\n)\nplt\n.\nxticks(xdata, bucket_names\n*\n20\n, rotation\n=\n90\n)\nplt\n.\nxlabel(\n'Direction buckets'\n)\nplt\n.\nylabel(\n'Magnitude'\n)\nplt\n.\ngrid(ls\n=\n'--'\n, color\n=\n'k'\n, alpha\n=\n0.1\n)\nplt\n.\ntitle(\n\"HOG of block at [\n%d\n,\n%d\n]\"\n%\n(loc_x, loc_y))\nplt\n.\ntight_layout()\nIn the code above, I use the block with top left corner located at [200, 200] as an example and here is the final normalized histogram of this block. You can play with the code to change the block location to be identified by a sliding window.\nDemonstration of a HOG histogram for one block.\nThe code is mostly for demonstrating the computation process. There are many off-the-shelf libraries with HOG algorithm implemented, such as\nOpenCV\n,\nSimpleCV\nand\nscikit-image\n.\nImage Segmentation (Felzenszwalb’s Algorithm)\n#\nWhen there exist multiple objects in one image (true for almost every real-world photos), we need to identify a region that potentially contains a target object so that the classification can be executed more efficiently.\nFelzenszwalb and Huttenlocher (\n2004\n) proposed an algorithm for segmenting an image into similar regions using a graph-based approach. It is also the initialization method for Selective Search (a popular region proposal algorithm) that we are gonna discuss later.\nSay, we use a undirected graph $G=(V, E)$ to represent an input image. One vertex $v_i \\in V$ represents one pixel. One edge $e = (v_i, v_j) \\in E$ connects two vertices $v_i$ and $v_j$. Its associated weight $w(v_i, v_j)$ measures the dissimilarity between $v_i$ and $v_j$. The dissimilarity can be quantified in dimensions like color, location, intensity, etc. The higher the weight, the less similar two pixels are. A segmentation solution $S$ is a partition of $V$ into multiple connected components, $\\{C\\}$. Intuitively similar pixels should belong to the same components while dissimilar ones are assigned to different components.\nGraph Construction\n#\nThere are two approaches to constructing a graph out of an image.\nGrid Graph\n: Each pixel is only connected with surrounding neighbours (8 other cells in total). The edge weight is the absolute difference between the intensity values of the pixels.\nNearest Neighbor Graph\n: Each pixel is a point in the feature space (x, y, r, g, b), in which (x, y) is the pixel location and (r, g, b) is the color values in RGB. The weight is the Euclidean distance between two pixels’ feature vectors.\nKey Concepts\n#\nBefore we lay down the criteria for a good graph partition (aka image segmentation), let us define a couple of key concepts:\nInternal difference\n: $Int(C) = \\max_{e\\in MST(C, E)} w(e)$, where $MST$ is the minimum spanning tree of the components. A component $C$ can still remain connected even when we have removed all the edges with weights < $Int(C)$.\nDifference between two components\n: $Dif(C_1, C_2) = \\min_{v_i \\in C_1, v_j \\in C_2, (v_i, v_j) \\in E} w(v_i, v_j)$. $Dif(C_1, C_2) = \\infty$ if there is no edge in-between.\nMinimum internal difference\n: $MInt(C_1, C_2) = min(Int(C_1) + \\tau(C_1), Int(C_2) + \\tau(C_2))$, where $\\tau(C) = k / \\vert C \\vert$ helps make sure we have a meaningful threshold for the difference between components. With a higher $k$, it is more likely to result in larger components.\nThe quality of a segmentation is assessed by a pairwise region comparison predicate defined for given two regions $C_1$ and $C_2$:\n$$\nD(C_1, C_2) = \n\\begin{cases}\n  \\text{True} & \\text{ if } Dif(C_1, C_2) > MInt(C_1, C_2) \\\\\n  \\text{False} & \\text{ otherwise}\n\\end{cases}\n$$\nOnly when the predicate holds True, we consider them as two independent components; otherwise the segmentation is too fine and they probably should be merged.\nHow Image Segmentation Works\n#\nThe algorithm follows a bottom-up procedure. Given $G=(V, E)$ and $|V|=n, |E|=m$:\nEdges are sorted by weight in ascending order, labeled as $e_1, e_2, \\dots, e_m$.\nInitially, each pixel stays in its own component, so we start with $n$ components.\nRepeat for $k=1, \\dots, m$:\nThe segmentation snapshot at the step $k$ is denoted as $S^k$.\nWe take  the k-th edge in the order, $e_k = (v_i, v_j)$.\nIf $v_i$ and $v_j$ belong to the same component, do nothing and thus $S^k = S^{k-1}$.\nIf $v_i$ and $v_j$ belong to two different components $C_i^{k-1}$ and $C_j^{k-1}$ as in the segmentation $S^{k-1}$, we want to merge them into one if $w(v_i, v_j) \\leq MInt(C_i^{k-1}, C_j^{k-1})$; otherwise do nothing.\nIf you are interested in the proof of the segmentation properties and why it always exists, please refer to the\npaper\n.\nAn indoor scene with segmentation detected by the grid graph construction in Felzenszwalb's graph-based segmentation algorithm (k=300).\nExample: Manu in 2013\n#\nThis time I would use the photo of old Manu Ginobili in 2013 [[Image]({{ ‘/assets/data/manu-2013.jpg’ | relative_url }})] as the example image when his bald spot has grown up strong. Still for simplicity, we use the picture in grayscale.\nManu Ginobili in 2013 with bald spot. (Image source:\nManu Ginobili's bald spot through the years\n)\nRather than coding from scratch, let us apply\nskimage.segmentation.felzenszwalb\nto the image.\nimport\nskimage.segmentation\nfrom\nmatplotlib\nimport\npyplot\nas\nplt\nimg2\n=\nscipy\n.\nmisc\n.\nimread(\n\"manu-2013.jpg\"\n, mode\n=\n\"L\"\n)\nsegment_mask1\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n100\n)\nsegment_mask2\n=\nskimage\n.\nsegmentation\n.\nfelzenszwalb(img2, scale\n=\n1000\n)\nfig\n=\nplt\n.\nfigure(figsize\n=\n(\n12\n,\n5\n))\nax1\n=\nfig\n.\nadd_subplot(\n121\n)\nax2\n=\nfig\n.\nadd_subplot(\n122\n)\nax1\n.\nimshow(segment_mask1); ax1\n.\nset_xlabel(\n\"k=100\"\n)\nax2\n.\nimshow(segment_mask2); ax2\n.\nset_xlabel(\n\"k=1000\"\n)\nfig\n.\nsuptitle(\n\"Felsenszwalb's efficient graph based image segmentation\"\n)\nplt\n.\ntight_layout()\nplt\n.\nshow()\nThe code ran two versions of Felzenszwalb’s algorithms as shown in The left k=100 generates a finer-grained segmentation with small regions where Manu’s bald spot is identified. The right one k=1000 outputs a coarser-grained segmentation where regions tend to be larger.\nFelsenszwalb's efficient graph-based image segmentation is applied on the photo of Manu in 2013.\nSelective Search\n#\nSelective search is a common algorithm to provide region proposals that potentially contain objects. It is built on top of the image segmentation output and use region-based characteristics (NOTE: not just attributes of a single pixel) to do a bottom-up hierarchical grouping.\nHow Selective Search Works\n#\nAt the initialization stage, apply Felzenszwalb and Huttenlocher’s graph-based image segmentation algorithm to create regions to start with.\nUse a greedy algorithm to iteratively group regions together:\nFirst the similarities between all neighbouring regions are calculated.\nThe two most similar regions are grouped together, and new similarities are calculated between the resulting region and its neighbours.\nThe process of grouping the most similar regions (Step 2) is repeated until the whole image becomes a single region.\nThe detailed algorithm of Selective Search.\nConfiguration Variations\n#\nGiven two regions $(r_i, r_j)$, selective search proposed four complementary similarity measures:\nColor\nsimilarity\nTexture\n: Use algorithm that works well for material recognition such as\nSIFT\n.\nSize\n: Small regions are encouraged to merge early.\nShape\n: Ideally one region can fill the gap of the other.\nBy (i) tuning the threshold $k$ in Felzenszwalb and Huttenlocher’s algorithm, (ii) changing the color space and (iii) picking different combinations of similarity metrics, we can produce a diverse set of Selective Search strategies. The version that produces the region proposals with best quality is configured with (i) a mixture of various initial segmentation proposals, (ii) a blend of multiple color spaces and (iii) a combination of all similarity measures. Unsurprisingly we need to balance between the quality (the model complexity) and the speed.\nCited as:\n@article{weng2017detection1,\n  title   = \"Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/\"\n}\nReferences\n#\n[1] Dalal, Navneet, and Bill Triggs.\n“Histograms of oriented gradients for human detection.”\nComputer Vision and Pattern Recognition (CVPR), 2005.\n[2] Pedro F. Felzenszwalb, and Daniel P. Huttenlocher.\n“Efficient graph-based image segmentation.”\nIntl. journal of computer vision 59.2 (2004): 167-181.\n[3]\nHistogram of Oriented Gradients by Satya Mallick\n[4]\nGradient Vectors by Chris McCormick\n[5]\nHOG Person Detector Tutorial by Chris McCormick",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:44:55Z",
            "title": "Object Detection for Dummies Part 1: Gradient Vector, HOG, and SS | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/6d3d9dca0d80/code/body-000.txt",
                "chars": 239,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-001.txt",
                "chars": 840,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-002.txt",
                "chars": 1510,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-003.txt",
                "chars": 655,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-004.txt",
                "chars": 547,
                "language": "text"
              },
              {
                "file": "attachments/6d3d9dca0d80/code/body-005.txt",
                "chars": 283,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "download_error",
                "url": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "reason": "ConnectTimeout: HTTPConnectionPool(host='cvcl.mit.edu', port=80): Max retries exceeded with url: /SUNSeminar/Felzenszwalb_IJCV04.pdf (Caused by ConnectTimeoutError(<HTTPConnection(host='cvcl.mit.e",
                "retried_at": "2026-10-20T22:24:59Z"
              },
              {
                "status": "ok",
                "url": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "bytes": 490132,
                "reused": true,
                "local_path": "papers/repair/e62fbcd20fd040b4335d.pdf"
              },
              {
                "status": "ok",
                "url": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "bytes": 577941,
                "reused": true,
                "local_path": "papers/repair/93aa482d821738ade913.pdf"
              },
              {
                "status": "invalid_file_type",
                "url": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:56:53Z"
              }
            ],
            "actual_video_files": [],
            "body_chars": 20363,
            "expected_body_images": 9,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；invalid_file_type",
            "raw_html": "attachments/6d3d9dca0d80/pages/source.html",
            "local_html": "attachments/6d3d9dca0d80/pages/article.html",
            "body_base_path": "attachments/6d3d9dca0d80/pages/",
            "body_markdown_path": "attachments/6d3d9dca0d80/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_gradient",
                "label": "image gradient vector",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Prewitt_operator",
                "label": "Prewitt operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Sobel_operator",
                "label": "Sobel operator",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Kernel_(image_processing)",
                "label": "this wiki page",
                "type": "a"
              },
              {
                "href": "http://ftw.usatoday.com/2013/05/manu-ginobilis-bald-spot-through-the-years",
                "label": "Manu Ginobili's bald spot through the years",
                "type": "a"
              },
              {
                "href": "https://github.com/opencv/opencv",
                "label": "OpenCV",
                "type": "a"
              },
              {
                "href": "http://simplecv.org/",
                "label": "SimpleCV",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/",
                "label": "scikit-image",
                "type": "a"
              },
              {
                "href": "http://cvcl.mit.edu/SUNSeminar/Felzenszwalb_IJCV04.pdf",
                "label": "2004",
                "type": "a"
              },
              {
                "href": "http://fcv2011.ulsan.ac.kr/files/announcement/413/IJCV(2004)%20Efficient%20Graph-Based%20Image%20Segmentation.pdf",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "http://scikit-image.org/docs/dev/api/skimage.segmentation.html",
                "label": "skimage.segmentation.felzenszwalb",
                "type": "a"
              },
              {
                "href": "http://www.cs.ubc.ca/~lowe/papers/iccv99.pdf",
                "label": "SIFT",
                "type": "a"
              },
              {
                "href": "https://hal.inria.fr/file/index/docid/548512/filename/hog_cvpr2005.pdf",
                "label": "“Histograms of oriented gradients for human detection.”",
                "type": "a"
              },
              {
                "href": "https://www.learnopencv.com/histogram-of-oriented-gradients/",
                "label": "Histogram of Oriented Gradients by Satya Mallick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/07/gradient-vectors/",
                "label": "Gradient Vectors by Chris McCormick",
                "type": "a"
              },
              {
                "href": "http://mccormickml.com/2013/05/09/hog-person-detector-tutorial/",
                "label": "HOG Person Detector Tutorial by Chris McCormick",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
          "status": "partial",
          "article_id": "b9468080b799",
          "local_path": "series-follow/1601/repair/93da665e04c347feb576.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
              "bytes": 788352,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4bea384db100fbf3fa0e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
              "bytes": 109138,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/227c6111eda2f97ab1f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
              "bytes": 3136069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b0d9d2dda61d5528b14d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
              "bytes": 437592,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e837b0cac457a4dfa174.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
              "bytes": 269669,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/283d484fb68c4e61aa0b.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
              "bytes": 27821,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c7816ecf6f5265465238.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
              "bytes": 432129,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9794f4d3172e6d7ec6e1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
              "bytes": 855836,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ad16881681864ec9a905.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
              "bytes": 1600504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/db8216b190ed77df91ef.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
              "bytes": 98699,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/de07b29467385da73bbf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
              "bytes": 1000184,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/781e719388c2d1788151.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "Object Detection for Dummies Part 3: R-CNN Family",
            "keywords": "目标检测,R-CNN,Faster R-CNN",
            "domain": "图像处理",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "publish_date": "2017-12",
            "corpus_stage": "预训练/SFT",
            "notes": "目标检测R-CNN家族综述",
            "id": "b9468080b799",
            "collected_at": "2026-10-02T14:13:33",
            "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
            "body_markdown": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n[Updated on 2018-12-27: Add\nbbox regression\nand\ntricks\nsections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in\nPart 1\n. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in\nPart 2\n. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nHere is a list of papers covered in this post ;)\nModel\nGoal\nResources\nR-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFast R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nFaster R-CNN\nObject recognition\n[\npaper\n][\ncode\n]\nMask R-CNN\nImage segmentation\n[\npaper\n][\ncode\n]\nR-CNN\n#\nR-CNN (\nGirshick et al., 2014\n) is short for “Region-based Convolutional Neural Networks”. The main idea is composed of two steps. First, using\nselective search\n, it identifies a manageable number of bounding-box object region candidates (“region of interest” or “RoI”). And then it extracts CNN features from each region independently for classification.\nThe architecture of R-CNN. (Image source:\nGirshick et al., 2014\n)\nModel Workflow\n#\nHow R-CNN works can be summarized as follows:\nPre-train\na CNN network on image classification tasks; for example, VGG or ResNet trained on\nImageNet\ndataset. The classification task involves N classes.\nNOTE: You can find a pre-trained\nAlexNet\nin Caffe Model\nZoo\n. I don’t think you can\nfind it\nin Tensorflow, but Tensorflow-slim model\nlibrary\nprovides pre-trained ResNet, VGG, and others.\nPropose category-independent regions of interest by selective search (~2k candidates per image). Those regions may contain target objects and they are of different sizes.\nRegion candidates are\nwarped\nto have a fixed size as required by CNN.\nContinue fine-tuning the CNN on warped proposal regions for K + 1 classes; The additional one class refers to the background (no object of interest). In the fine-tuning stage, we should use a much smaller learning rate and the mini-batch oversamples the positive cases because most proposed regions are just background.\nGiven every image region, one forward propagation through the CNN generates a feature vector. This feature vector is then consumed by a\nbinary SVM\ntrained for\neach class\nindependently.\nThe positive samples are proposed regions with IoU (intersection over union) overlap threshold >= 0.3, and negative samples are irrelevant others.\nTo reduce the localization errors, a regression model is trained to correct the predicted detection window on bounding box correction offset using CNN features.\nBounding Box Regression\n#\nGiven a predicted bounding box coordinate $\\mathbf{p} = (p_x, p_y, p_w, p_h)$ (center coordinate, width, height) and its corresponding ground truth box coordinates $\\mathbf{g} = (g_x, g_y, g_w, g_h)$ , the regressor is configured to learn scale-invariant transformation between two centers and log-scale transformation between widths and heights. All the transformation functions take $\\mathbf{p}$ as input.\n$$\n\\begin{aligned}\n\\hat{g}_x &= p_w d_x(\\mathbf{p}) + p_x \\\\\n\\hat{g}_y &= p_h d_y(\\mathbf{p}) + p_y \\\\\n\\hat{g}_w &= p_w \\exp({d_w(\\mathbf{p})}) \\\\\n\\hat{g}_h &= p_h \\exp({d_h(\\mathbf{p})})\n\\end{aligned}\n$$\nIllustration of transformation between predicted and ground truth bounding boxes.\nAn obvious benefit of applying such transformation is that all the bounding box correction functions, $d_i(\\mathbf{p})$ where $i \\in \\{ x, y, w, h \\}$, can take any value between [-∞, +∞]. The targets for them to learn are:\n$$\n\\begin{aligned}\nt_x &= (g_x - p_x) / p_w \\\\\nt_y &= (g_y - p_y) / p_h \\\\\nt_w &= \\log(g_w/p_w) \\\\\nt_h &= \\log(g_h/p_h)\n\\end{aligned}\n$$\nA standard regression model can solve the problem by minimizing the SSE loss with regularization:\n$$\n\\mathcal{L}_\\text{reg} = \\sum_{i \\in \\{x, y, w, h\\}} (t_i - d_i(\\mathbf{p}))^2 + \\lambda \\|\\mathbf{w}\\|^2\n$$\nThe regularization term is critical here and RCNN paper picked the best λ by cross validation. It is also noteworthy that not all the predicted bounding boxes have corresponding ground truth boxes. For example, if there is no overlap, it does not make sense to run bbox regression. Here, only a predicted box with a nearby ground truth box with at least 0.6 IoU is kept for training the bbox regression model.\nCommon Tricks\n#\nSeveral tricks are commonly used in RCNN and other detection models.\nNon-Maximum Suppression\nLikely the model is able to find multiple bounding boxes for the same object. Non-max suppression helps avoid repeated detection of the same instance. After we get a set of matched bounding boxes for the same object category:\nSort all the bounding boxes by confidence score.\nDiscard boxes with low confidence scores.\nWhile\nthere is any remaining bounding box, repeat the following:\nGreedily select the one with the highest score.\nSkip the remaining boxes with high IoU (i.e. > 0.5) with previously selected one.\nMultiple bounding boxes detect the car in the image. After non-maximum suppression, only the best remains and the rest are ignored as they have large overlaps with the selected one. (Image source:\nDPM paper\n)\nHard Negative Mining\nWe consider bounding boxes without objects as negative examples. Not all the negative examples are equally hard to be identified. For example, if it holds pure empty background, it is likely an “\neasy negative\n”; but if the box contains weird noisy texture or partial object, it could be hard to be recognized and these are “\nhard negative\n”.\nThe hard negative examples are easily misclassified. We can explicitly find those false positive samples during the training loops and include them in the training data so as to improve the classifier.\nSpeed Bottleneck\n#\nLooking through the R-CNN learning steps, you could easily find out that training an R-CNN model is expensive and slow, as the following steps involve a lot of work:\nRunning selective search to propose 2000 region candidates for every image;\nGenerating the CNN feature vector for every image region (N images * 2000).\nThe whole process involves three models separately without much shared computation: the convolutional neural network for image classification and feature extraction; the top SVM classifier for identifying target objects; and the regression model for tightening region bounding boxes.\nFast R-CNN\n#\nTo make R-CNN faster, Girshick (\n2015\n) improved the training procedure by unifying three independent models into one jointly trained framework and increasing shared computation results, named\nFast R-CNN\n. Instead of extracting CNN feature vectors independently for each region proposal, this model aggregates them into one CNN forward pass over the entire image and the region proposals share this feature matrix. Then the same feature matrix is branched out to be used for learning the object classifier and the bounding-box regressor. In conclusion, computation sharing speeds up R-CNN.\nThe architecture of Fast R-CNN. (Image source:\nGirshick, 2015\n)\nRoI Pooling\n#\nIt is a type of max pooling to convert features in the projected region of the image of any size, h x w, into a small fixed window, H x W. The input region is divided into H x W grids, approximately every subwindow of size h/H x w/W. Then apply max-pooling in each grid.\nRoI pooling (Image source:\nStanford CS231n slides\n.)\nModel Workflow\n#\nHow Fast R-CNN works is summarized as follows; many steps are same as in R-CNN:\nFirst, pre-train a convolutional neural network on image classification tasks.\nPropose regions by selective search (~2k candidates per image).\nAlter the pre-trained CNN:\nReplace the last max pooling layer of the pre-trained CNN with a\nRoI pooling\nlayer. The RoI pooling layer outputs fixed-length feature vectors of region proposals. Sharing the CNN computation makes a lot of sense, as many region proposals of the same images are highly overlapped.\nReplace the last fully connected layer and the last softmax layer (K classes) with a fully connected layer and softmax over K + 1 classes.\nFinally the model branches into two output layers:\nA softmax estimator of K + 1 classes (same as in R-CNN, +1 is the “background” class), outputting a discrete probability distribution per RoI.\nA bounding-box regression model which predicts offsets relative to the original RoI for each of K classes.\nLoss Function\n#\nThe model is optimized for a loss combining two tasks (classification + localization):\n|\nSymbol\n|\nExplanation\n|\n| $u$ | True class label, $ u \\in 0, 1, \\dots, K$; by convention, the catch-all background class has $u = 0$. |\n| $p$ | Discrete probability distribution (per RoI) over K + 1 classes: $p = (p_0, \\dots, p_K)$, computed by a softmax over the K + 1 outputs of a fully connected layer. |\n| $v$ | True bounding box $ v = (v_x, v_y, v_w, v_h) $. |\n| $t^u$ | Predicted bounding box correction, $t^u = (t^u_x, t^u_y, t^u_w, t^u_h)$. See\nabove\n. |\n{:.info}\nThe loss function sums up the cost of classification and bounding box prediction: $\\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box}$. For “background” RoI, $\\mathcal{L}_\\text{box}$ is ignored by the indicator function $\\mathbb{1} [u \\geq 1]$, defined as:\n$$\n\\mathbb{1} [u >= 1] = \\begin{cases}\n    1  & \\text{if } u \\geq 1\\\\\n    0  & \\text{otherwise}\n\\end{cases}\n$$\nThe overall loss function is:\n$$\n\\begin{align*}\n\\mathcal{L}(p, u, t^u, v) &= \\mathcal{L}_\\text{cls} (p, u) + \\mathbb{1} [u \\geq 1] \\mathcal{L}_\\text{box}(t^u, v) \\\\\n\\mathcal{L}_\\text{cls}(p, u) &= -\\log p_u \\\\\n\\mathcal{L}_\\text{box}(t^u, v) &= \\sum_{i \\in \\{x, y, w, h\\}} L_1^\\text{smooth} (t^u_i - v_i)\n\\end{align*}\n$$\nThe bounding box loss $\\mathcal{L}_{box}$ should measure the difference between $t^u_i$ and $v_i$ using a\nrobust\nloss function. The\nsmooth L1 loss\nis adopted here and it is claimed to be less sensitive to outliers.\n$$\nL_1^\\text{smooth}(x) = \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases}\n$$\nThe plot of smooth L1 loss, $y = L\\_1^\\text{smooth}(x)$. (Image source:\nlink\n)\nSpeed Bottleneck\n#\nFast R-CNN is much faster in both training and testing time. However, the improvement is not dramatic because the region proposals are generated separately by another model and that is very expensive.\nFaster R-CNN\n#\nAn intuitive speedup solution is to integrate the region proposal algorithm into the CNN model.\nFaster R-CNN\n(\nRen et al., 2016\n) is doing exactly this: construct a single, unified model composed of RPN (region proposal network) and fast R-CNN with shared convolutional feature layers.\nAn illustration of Faster R-CNN model. (Image source:\nRen et al., 2016\n)\nModel Workflow\n#\nPre-train a CNN network on image classification tasks.\nFine-tune the RPN (region proposal network) end-to-end for the region proposal task, which is initialized by the pre-train image classifier. Positive samples have IoU (intersection-over-union) > 0.7, while negative samples have IoU < 0.3.\nSlide a small n x n spatial window over the conv feature map of the entire image.\nAt the center of each sliding window, we predict multiple regions of various scales and ratios simultaneously. An anchor is a combination of (sliding window center, scale, ratio). For example, 3 scales + 3 ratios => k=9 anchors at each sliding position.\nTrain a Fast R-CNN object detection model using the proposals generated by the current RPN\nThen use the Fast R-CNN network to initialize RPN training. While keeping the shared convolutional layers, only fine-tune the RPN-specific layers. At this stage, RPN and the detection network have shared convolutional layers!\nFinally fine-tune the unique layers of Fast R-CNN\nStep 4-5 can be repeated to train RPN and Fast R-CNN alternatively if needed.\nLoss Function\n#\nFaster R-CNN is optimized for a multi-task loss function, similar to fast R-CNN.\n|\nSymbol\n|\nExplanation\n|\n| $p_i$     | Predicted probability of anchor i being an object. |\n| $p^*_i$   | Ground truth label (binary) of whether anchor i is an object. |\n| $t_i$     | Predicted four parameterized coordinates. |\n| $t^*_i$   | Ground truth coordinates. |\n| $N_\\text{cls}$ | Normalization term, set to be mini-batch size (~256) in the paper. |\n| $N_\\text{box}$ | Normalization term, set to the number of anchor locations (~2400) in the paper. |\n| $\\lambda$ | A balancing parameter, set to be ~10 in the paper (so that both $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ terms are roughly equally weighted). |\n{:.info}\nThe multi-task loss function combines the losses of classification and bounding box regression:\n$$\n\\begin{align*}\n\\mathcal{L} &= \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} \\\\\n\\mathcal{L}(\\{p_i\\}, \\{t_i\\}) &= \\frac{1}{N_\\text{cls}} \\sum_i \\mathcal{L}_\\text{cls} (p_i, p^*_i) + \\frac{\\lambda}{N_\\text{box}} \\sum_i p^*_i \\cdot L_1^\\text{smooth}(t_i - t^*_i) \\\\\n\\end{align*}\n$$\nwhere $\\mathcal{L}_\\text{cls}$ is the log loss function over two classes, as we can easily translate a multi-class classification into a binary classification by predicting a sample being a target object versus not. $L_1^\\text{smooth}$ is the smooth L1 loss.\n$$\n\\mathcal{L}_\\text{cls} (p_i, p^*_i) = - p^*_i \\log p_i - (1 - p^*_i) \\log (1 - p_i)\n$$\nMask R-CNN\n#\nMask R-CNN (\nHe et al., 2017\n) extends Faster R-CNN to pixel-level\nimage segmentation\n. The key point is to decouple the classification and the pixel-level mask prediction tasks. Based on the framework of\nFaster R-CNN\n, it added a third branch for predicting an object mask in parallel with the existing branches for classification and localization. The mask branch is a small fully-connected network applied to each RoI, predicting a segmentation mask in a pixel-to-pixel manner.\nMask R-CNN is Faster R-CNN model with image segmentation. (Image source:\nHe et al., 2017\n)\nBecause pixel-level segmentation requires much more fine-grained alignment than bounding boxes, mask R-CNN improves the RoI pooling layer (named “RoIAlign layer”) so that RoI can be better and more precisely mapped to the regions of the original image.\nPredictions by Mask R-CNN on COCO test set. (Image source:\nHe et al., 2017\n)\nRoIAlign\n#\nThe RoIAlign layer is designed to fix the location misalignment caused by quantization in the RoI pooling. RoIAlign removes the hash quantization, for example, by using x/16 instead of [x/16], so that the extracted features can be properly aligned with the input pixels.\nBilinear interpolation\nis used for computing the floating-point location values in the input.\nA region of interest is mapped **accurately** from the original image onto the feature map without rounding up to integers. (Image source:\nlink\n)\nLoss Function\n#\nThe multi-task loss function of Mask R-CNN combines the loss of classification, localization and segmentation mask: $ \\mathcal{L} = \\mathcal{L}_\\text{cls} + \\mathcal{L}_\\text{box} + \\mathcal{L}_\\text{mask}$, where $\\mathcal{L}_\\text{cls}$ and $\\mathcal{L}_\\text{box}$ are same as in Faster R-CNN.\nThe mask branch generates a mask of dimension m x m for each RoI and each class; K classes in total. Thus, the total output is of size $K \\cdot m^2$. Because the model is trying to learn a mask for each class, there is no competition among classes for generating masks.\n$\\mathcal{L}_\\text{mask}$ is defined as the average binary cross-entropy loss, only including k-th mask if the region is associated with the ground truth class k.\n$$\n\\mathcal{L}_\\text{mask} = - \\frac{1}{m^2} \\sum_{1 \\leq i, j \\leq m} \\big[ y_{ij} \\log \\hat{y}^k_{ij} + (1-y_{ij}) \\log (1- \\hat{y}^k_{ij}) \\big]\n$$\nwhere $y_{ij}$ is the label of a cell (i, j) in the true mask for the region of size m x m; $\\hat{y}_{ij}^k$ is the predicted value of the same cell in the mask learned for the ground-truth class k.\nSummary of Models in the R-CNN family\n#\nHere I illustrate model designs of R-CNN, Fast R-CNN, Faster R-CNN and Mask R-CNN. You can track how one model evolves to the next version by comparing the small differences.\nCited as:\n@article{weng2017detection3,\n  title   = \"Object Detection for Dummies Part 3: R-CNN Family\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2017\",\n  url     = \"https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/\"\n}\nReference\n#\n[1] Ross Girshick, Jeff Donahue, Trevor Darrell, and Jitendra Malik.\n“Rich feature hierarchies for accurate object detection and semantic segmentation.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 580-587. 2014.\n[2] Ross Girshick.\n“Fast R-CNN.”\nIn Proc. IEEE Intl. Conf. on computer vision, pp. 1440-1448. 2015.\n[3] Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun.\n“Faster R-CNN: Towards real-time object detection with region proposal networks.”\nIn Advances in neural information processing systems (NIPS), pp. 91-99. 2015.\n[4] Kaiming He, Georgia Gkioxari, Piotr Dollár, and Ross Girshick.\n“Mask R-CNN.”\narXiv preprint arXiv:1703.06870, 2017.\n[5] Joseph Redmon, Santosh Divvala, Ross Girshick, and Ali Farhadi.\n“You only look once: Unified, real-time object detection.”\nIn Proc. IEEE Conf. on computer vision and pattern recognition (CVPR), pp. 779-788. 2016.\n[6]\n“A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN”\nby Athelas.\n[7] Smooth L1 Loss:\nhttps://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
            "metadata": {
              "title": "Object Detection for Dummies Part 3: R-CNN Family | Lil'Log",
              "description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "keywords": "object-detection, object-recognition, vision-model",
              "author": "Lilian Weng",
              "og:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "og:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
              "twitter:card": "summary",
              "twitter:title": "Object Detection for Dummies Part 3: R-CNN Family",
              "twitter:description": "[Updated on 2018-12-20: Remove YOLO here. Part 4 will cover multiple fast object detection algorithms, including YOLO.]\n\n[Updated on 2018-12-27: Add bbox regression and tricks sections for R-CNN.]\nIn the series of “Object Detection for Dummies”, we started with basic concepts in image processing, such as gradient vectors and HOG, in Part 1. Then we introduced classic convolutional neural network architecture designs for classification and pioneer models for object recognition, Overfeat and DPM, in Part 2. In the third post of this series, we are about to review a set of models in the R-CNN (“Region-based CNN”) family.",
              "article:section": "posts",
              "article:published_time": "2017-12-31T00:00:00+00:00",
              "article:modified_time": "2017-12-31T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/b9468080b799/code/body-000.txt",
                "chars": 267,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "bytes": 788352,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-4bea384db100fbf3fa0e.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "bytes": 109138,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-227c6111eda2f97ab1f2.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/RCNN-bbox-regression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "bytes": 3136069,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-b0d9d2dda61d5528b14d.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/non-max-suppression.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "bytes": 437592,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-e837b0cac457a4dfa174.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/fast-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "bytes": 269669,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-283d484fb68c4e61aa0b.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-pooling.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "bytes": 27821,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-c7816ecf6f5265465238.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/l1-smooth.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "bytes": 432129,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-9794f4d3172e6d7ec6e1.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/faster-RCNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "bytes": 855836,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-ad16881681864ec9a905.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "bytes": 1600504,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-db8216b190ed77df91ef.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/mask-rcnn-examples.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "bytes": 98699,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-de07b29467385da73bbf.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/roi-align.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "bytes": 1000184,
                "reused": false,
                "local_path": "attachments/b9468080b799/images/body-781e719388c2d1788151.png",
                "src": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/rcnn-family-summary.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1311.2524",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1504.08083",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/fast-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1506.01497",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn",
                "label": "code",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1703.06870",
                "label": "paper",
                "type": "a"
              },
              {
                "href": "https://github.com/CharlesShang/FastMaskRCNN",
                "label": "code",
                "type": "a"
              },
              {
                "href": "http://image-net.org/index",
                "label": "ImageNet",
                "type": "a"
              },
              {
                "href": "https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet",
                "label": "AlexNet",
                "type": "a"
              },
              {
                "href": "https://github.com/caffe2/caffe2/wiki/Model-Zoo",
                "label": "Zoo",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/issues/1394",
                "label": "find it",
                "type": "a"
              },
              {
                "href": "https://github.com/tensorflow/models/tree/master/research/slim",
                "label": "library",
                "type": "a"
              },
              {
                "href": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "label": "DPM paper",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1504.08083.pdf",
                "label": "2015",
                "type": "a"
              },
              {
                "href": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "label": "Stanford CS231n slides",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1506.01497.pdf",
                "label": "Ren et al., 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1703.06870.pdf",
                "label": "He et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Bilinear_interpolation",
                "label": "Bilinear interpolation",
                "type": "a"
              },
              {
                "href": "https://blog.athelas.com/a-brief-history-of-cnns-in-image-segmentation-from-r-cnn-to-mask-r-cnn-34ea83205de4",
                "label": "link",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "label": "“Rich feature hierarchies for accurate object detection and semantic segmentation.”",
                "type": "a"
              },
              {
                "href": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "label": "“Faster R-CNN: Towards real-time object detection with region proposal networks.”",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "“You only look once: Unified, real-time object detection.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:37Z",
            "source_url": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
            "papers": [
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1311.2524",
                "bytes": 6537772,
                "reused": false,
                "local_path": "papers/repair/5a971c9318fd8ef99b6d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/6389d2bce9bb81657bc7.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/713fc776568d336b3d68.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/664bbc784da30edacdb6.pdf"
              },
              {
                "status": "http_404",
                "url": "http://lear.inrialpes.fr/~oneata/reading_group/dpm.pdf",
                "retried_at": "2026-10-20T18:02:44Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1504.08083.pdf",
                "bytes": 731121,
                "reused": false,
                "local_path": "papers/repair/95f875d1b93587451953.pdf"
              },
              {
                "status": "ok",
                "url": "http://cs231n.stanford.edu/slides/2016/winter1516_lecture8.pdf",
                "bytes": 5264822,
                "reused": false,
                "local_path": "papers/repair/6704307d3926afe480a0.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": false,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1506.01497.pdf",
                "bytes": 6913803,
                "reused": false,
                "local_path": "papers/repair/9037a5243698d57ca173.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1703.06870.pdf",
                "bytes": 7723886,
                "reused": false,
                "local_path": "papers/repair/2f0eeff44085ec6f68ba.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf",
                "bytes": 1847626,
                "reused": false,
                "local_path": "papers/repair/99bf7bde4d6390550327.pdf"
              },
              {
                "status": "ok",
                "url": "http://papers.nips.cc/paper/5638-faster-r-cnn-towards-real-time-object-detection-with-region-proposal-networks.pdf",
                "bytes": 761683,
                "reused": false,
                "local_path": "papers/repair/b13d014f28dadd2b7070.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": false,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 17566,
            "expected_body_images": 11,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/b9468080b799/pages/source.html",
            "local_html": "attachments/b9468080b799/pages/article.html",
            "body_base_path": "attachments/b9468080b799/pages/",
            "body_markdown_path": "attachments/b9468080b799/pages/article.md"
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
          "status": "partial",
          "article_id": "466144a71db1",
          "local_path": "series-follow/1601/repair/42584a00573758a53824.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
              "bytes": 947849,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7b981ee4ba3f0de9c69e.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
              "bytes": 193831,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/d2d51b39b0c71b0793d1.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
              "bytes": 141158,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f004873880c2663f6f27.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
              "bytes": 285879,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b686cd210511644b9482.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
              "bytes": 862890,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/37c5aefd5995be6d0a22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
              "bytes": 155905,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/4e81399abad9997ff29c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
              "bytes": 120909,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/ac3a14a3f394f51725f0.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
              "bytes": 1623681,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bf58d167b991ee5982f3.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
              "bytes": 328470,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7b68e660a804f6fdedfc.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
              "bytes": 77640,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2a4ecbef4a9439ed154d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
              "bytes": 310680,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/955d0dc9f36806474855.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
              "bytes": 905917,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2098115c6b769573d03c.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
              "bytes": 332323,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/90988a475dbc99affc49.png"
            }
          ],
          "article": {
            "id": "466144a71db1",
            "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "bytes": 947849,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b981ee4ba3f0de9c69e.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "bytes": 193831,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-d2d51b39b0c71b0793d1.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-network-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "bytes": 141158,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-f004873880c2663f6f27.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolo-responsible-predictor.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "bytes": 285879,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-b686cd210511644b9482.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-architecture.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "bytes": 862890,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-37c5aefd5995be6d0a22.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-framework.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "bytes": 155905,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-4e81399abad9997ff29c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/SSD-box-scales.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "bytes": 120909,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-ac3a14a3f394f51725f0.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov2-loc-prediction.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "bytes": 1623681,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-bf58d167b991ee5982f3.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/word-tree.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "bytes": 328470,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-7b68e660a804f6fdedfc.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "bytes": 77640,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2a4ecbef4a9439ed154d.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/focal-loss-weights.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "bytes": 310680,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-955d0dc9f36806474855.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/featurized-image-pyramid.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "bytes": 905917,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-2098115c6b769573d03c.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/retina-net.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "bytes": 332323,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/466144a71db1/images/body-90988a475dbc99affc49.png",
                "src": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/yolov3-perf.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [],
            "body_markdown": "In\nPart 3\n, we have reviewed models in the R-CNN family. All of them are region-based object detection algorithms. They can achieve high accuracy but could be too slow for certain applications such as autonomous driving. In Part 4, we only focus on fast object detection models, including SSD, RetinaNet, and models in the YOLO family.\nLinks to all the posts in the series:\n[\nPart 1\n]\n[\nPart 2\n]\n[\nPart 3\n]\n[\nPart 4\n].\nTwo-stage vs One-stage Detectors\n#\nModels in the R-CNN family are all region-based. The detection happens in two stages: (1) First, the model proposes a set of regions of interests by select search or regional proposal network. The proposed regions are sparse as the potential bounding box candidates can be infinite. (2) Then a classifier only processes the region candidates.\nThe other different approach skips the region proposal stage and runs detection directly over a dense sampling of possible locations. This is how a one-stage object detection algorithm works. This is faster and simpler, but might potentially drag down the performance a bit.\nAll the models introduced in this post are one-stage detectors.\nYOLO: You Only Look Once\n#\nThe\nYOLO\nmodel (\n“You Only Look Once”\n;\nRedmon et al., 2016\n) is the very first attempt at building a fast real-time object detector. Because YOLO does not undergo the region proposal step and only predicts over a limited number of bounding boxes, it is able to do inference super fast.\nWorkflow\n#\nPre-train\na CNN network on image classification task.\nSplit an image into $S \\times S$ cells. If an object’s center falls into a cell, that cell is “responsible” for detecting the existence of that object. Each cell predicts (a) the location of $B$ bounding boxes, (b) a confidence score, and (c) a probability of object class conditioned on the existence of an object in the bounding box.\nThe\ncoordinates\nof bounding box are defined by a tuple of 4 values, (center x-coord, center y-coord, width, height) — $(x, y, w, h)$, where $x$ and $y$ are set to be offset of a cell location. Moreover, $x$, $y$, $w$ and $h$ are normalized by the image width and height, and thus all between (0, 1].\nA\nconfidence score\nindicates the likelihood that the cell contains an object:\nPr(containing an object) x IoU(pred, truth)\n; where\nPr\n= probability and\nIoU\n= interaction under union.\nIf the cell contains an object, it predicts a\nprobability\nof this object belonging to every class $C_i, i=1, \\dots, K$:\nPr(the object belongs to the class C_i | containing an object)\n. At this stage, the model only predicts one set of class probabilities per cell, regardless of the number of bounding boxes, $B$.\nIn total, one image contains $S \\times S \\times B$ bounding boxes, each box corresponding to 4 location predictions, 1 confidence score, and K conditional probabilities for object classification. The total prediction values for one image is $S \\times S \\times (5B + K)$, which is the tensor shape of the final conv layer of the model.\nThe final layer of the pre-trained CNN is modified to output a prediction tensor of size $S \\times S \\times (5B + K)$.\nThe workflow of YOLO model. (Image source:\noriginal paper\n)\nNetwork Architecture\n#\nThe base model is similar to\nGoogLeNet\nwith inception module replaced by 1x1 and 3x3 conv layers. The final prediction of shape $S \\times S \\times (5B + K)$ is produced by two fully connected layers over the whole conv feature map.\nThe network architecture of YOLO.\nLoss Function\n#\nThe loss consists of two parts, the\nlocalization loss\nfor bounding box offset prediction and the\nclassification loss\nfor conditional class probabilities. Both parts are computed as the sum of squared errors. Two scale parameters are used to control how much we want to increase the loss from bounding box coordinate predictions ($\\lambda_\\text{coord}$) and how much we want to decrease the loss of confidence score predictions for boxes without objects ($\\lambda_\\text{noobj}$). Down-weighting the loss contributed by background boxes is important as most of the bounding boxes involve no instance. In the paper, the model sets $\\lambda_\\text{coord} = 5$ and $\\lambda_\\text{noobj} = 0.5$.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\lambda_\\text{coord} \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\mathbb{1}_{ij}^\\text{obj} [(x_i - \\hat{x}_i)^2 + (y_i - \\hat{y}_i)^2 + (\\sqrt{w_i} - \\sqrt{\\hat{w}_i})^2 + (\\sqrt{h_i} - \\sqrt{\\hat{h}_i})^2 ] \\\\\n\\mathcal{L}_\\text{cls}  &= \\sum_{i=0}^{S^2} \\sum_{j=0}^B \\big( \\mathbb{1}_{ij}^\\text{obj} + \\lambda_\\text{noobj} (1 - \\mathbb{1}_{ij}^\\text{obj})\\big) (C_{ij} - \\hat{C}_{ij})^2 + \\sum_{i=0}^{S^2} \\sum_{c \\in \\mathcal{C}} \\mathbb{1}_i^\\text{obj} (p_i(c) - \\hat{p}_i(c))^2\\\\\n\\mathcal{L} &= \\mathcal{L}_\\text{loc} + \\mathcal{L}_\\text{cls}\n\\end{aligned}\n$$\nNOTE: In the original YOLO paper, the loss function uses $C_i$ instead of $C_{ij}$ as confidence score. I made the correction based on my own understanding, since every bounding box should have its own confidence score. Please kindly let me if you do not agree. Many thanks.\nwhere,\n$\\mathbb{1}_i^\\text{obj}$: An indicator function of whether the cell i contains an object.\n$\\mathbb{1}_{ij}^\\text{obj}$: It indicates whether the j-th bounding box of the cell i is “responsible” for the object prediction (see Fig. 3).\n$C_{ij}$: The confidence score of cell i,\nPr(containing an object) * IoU(pred, truth)\n.\n$\\hat{C}_{ij}$: The predicted confidence score.\n$\\mathcal{C}$: The set of all classes.\n$p_i(c)$: The conditional probability of whether cell i contains an object of class $c \\in \\mathcal{C}$.\n$\\hat{p}_i(c)$: The predicted conditional class probability.\nAt one location, in cell i, the model proposes B bounding box candidates and the one that has highest overlap with the ground truth is the \"responsible\" predictor.\nThe loss function only penalizes classification error if an object is present in that grid cell, $\\mathbb{1}_i^\\text{obj} = 1$. It also only penalizes bounding box coordinate error if that predictor is “responsible” for the ground truth box, $\\mathbb{1}_{ij}^\\text{obj} = 1$.\nAs a one-stage object detector, YOLO is super fast, but it is not good at recognizing irregularly shaped objects or a group of small objects due to a limited number of bounding box candidates.\nSSD: Single Shot MultiBox Detector\n#\nThe\nSingle Shot Detector\n(\nSSD\n;\nLiu et al, 2016\n) is one of the first attempts at using convolutional neural network’s pyramidal feature hierarchy for efficient detection of objects of various sizes.\nImage Pyramid\n#\nSSD uses the\nVGG-16\nmodel pre-trained on ImageNet as its base model for extracting useful image features.\nOn top of VGG16, SSD adds several conv feature layers of decreasing sizes. They can be seen as a\npyramid representation\nof images at different scales. Intuitively large fine-grained feature maps at earlier levels are good at capturing small objects and small coarse-grained feature maps can detect large objects well. In SSD, the detection happens in every pyramidal layer, targeting at objects of various sizes.\nThe model architecture of SSD.\nWorkflow\n#\nUnlike YOLO, SSD does not split the image into grids of arbitrary size but predicts offset of predefined\nanchor boxes\n(this is called “default boxes” in the paper) for every location of the feature map. Each box has a fixed size and position relative to its corresponding cell. All the anchor boxes tile the whole feature map in a convolutional manner.\nFeature maps at different levels have different receptive field sizes. The anchor boxes on different levels are rescaled so that one feature map is only responsible for objects at one particular scale. For example, in Fig. 5 the dog can only be detected in the 4x4 feature map (higher level) while the cat is just captured by the 8x8 feature map (lower level).\nThe SSD framework. (a) The training data contains images and ground truth boxes for every object. (b) In a fine-grained feature maps (8 x 8), the anchor boxes of different aspect ratios correspond to smaller area of the raw input. (c) In a coarse-grained feature map (4 x 4), the anchor boxes cover larger area of the raw input. (Image source:\noriginal paper\n)\nThe width, height and the center location of an anchor box are all normalized to be (0, 1). At a location $(i, j)$ of the $\\ell$-th feature layer of size $m \\times n$, $i=1,\\dots,n, j=1,\\dots,m$, we have a unique linear scale proportional to the layer level and 5 different box aspect ratios (width-to-height ratios), in addition to a special scale (why we need this? the paper didn’t explain. maybe just a heuristic trick) when the aspect ratio is 1. This gives us 6 anchor boxes in total per feature cell.\n$$\n\\begin{aligned}\n\\text{level index: } &\\ell = 1, \\dots, L \\\\\n\\text{scale of boxes: } &s_\\ell = s_\\text{min} + \\frac{s_\\text{max} - s_\\text{min}}{L - 1} (\\ell - 1) \\\\\n\\text{aspect ratio: } &r \\in \\{1, 2, 3, 1/2, 1/3\\}\\\\\n\\text{additional scale: } & s'_\\ell = \\sqrt{s_\\ell s_{\\ell + 1}} \\text{ when } r = 1 \\text{thus, 6 boxes in total.}\\\\\n\\text{width: } &w_\\ell^r = s_\\ell \\sqrt{r} \\\\\n\\text{height: } &h_\\ell^r = s_\\ell / \\sqrt{r} \\\\\n\\text{center location: } & (x^i_\\ell, y^j_\\ell) = (\\frac{i+0.5}{m}, \\frac{j+0.5}{n})\n\\end{aligned}\n$$\nAn example of how the anchor box size is scaled up with the layer index $\\ell$ for $L=6, s\\_\\text{min} = 0.2, s\\_\\text{max} = 0.9$. Only the boxes of aspect ratio $r=1$ are illustrated.\nAt every location, the model outputs 4 offsets and $c$ class probabilities by applying a $3 \\times 3 \\times p$ conv filter (where $p$ is the number of channels in the feature map) for every one of $k$ anchor boxes. Therefore, given a feature map of size $m \\times n$, we need $kmn(c+4)$ prediction filters.\nLoss Function\n#\nSame as YOLO, the loss function is the sum of a localization loss and a classification loss.\n$\\mathcal{L} = \\frac{1}{N}(\\mathcal{L}_\\text{cls} + \\alpha \\mathcal{L}_\\text{loc})$\nwhere $N$ is the number of matched bounding boxes and $\\alpha$ balances the weights between two losses, picked by cross validation.\nThe\nlocalization loss\nis a\nsmooth L1 loss\nbetween the predicted bounding box correction and the true values. The coordinate correction transformation is same as what\nR-CNN\ndoes in\nbounding box regression\n.\n$$\n\\begin{aligned}\n\\mathcal{L}_\\text{loc} &= \\sum_{i,j} \\sum_{m\\in\\{x, y, w, h\\}} \\mathbb{1}_{ij}^\\text{match}\n L_1^\\text{smooth}(d_m^i - t_m^j)^2\\\\\nL_1^\\text{smooth}(x) &= \\begin{cases}\n    0.5 x^2             & \\text{if } \\vert x \\vert < 1\\\\\n    \\vert x \\vert - 0.5 & \\text{otherwise}\n\\end{cases} \\\\\nt^j_x &= (g^j_x - p^i_x) / p^i_w \\\\\nt^j_y &= (g^j_y - p^i_y) / p^i_h \\\\\nt^j_w &= \\log(g^j_w / p^i_w) \\\\\nt^j_h &= \\log(g^j_h / p^i_h)\n\\end{aligned}\n$$\nwhere $\\mathbb{1}_{ij}^\\text{match}$ indicates whether the $i$-th bounding box with coordinates $(p^i_x, p^i_y, p^i_w, p^i_h)$ is matched to the $j$-th ground truth box with coordinates $(g^j_x, g^j_y, g^j_w, g^j_h)$ for any object. $d^i_m, m\\in\\{x, y, w, h\\}$ are the predicted correction terms. See\nthis\nfor how the transformation works.\nThe\nclassification loss\nis a softmax loss over multiple classes (\nsoftmax_cross_entropy_with_logits\nin tensorflow):\n$$\n\\mathcal{L}_\\text{cls} = -\\sum_{i \\in \\text{pos}} \\mathbb{1}_{ij}^k \\log(\\hat{c}_i^k) - \\sum_{i \\in \\text{neg}} \\log(\\hat{c}_i^0)\\text{, where }\\hat{c}_i^k = \\text{softmax}(c_i^k)\n$$\nwhere $\\mathbb{1}_{ij}^k$ indicates whether the $i$-th bounding box and the $j$-th ground truth box are matched for an object in class $k$. $\\text{pos}$ is the set of matched bounding boxes ($N$ items in total) and  $\\text{neg}$ is the set of negative examples. SSD uses\nhard negative mining\nto select easily misclassified negative examples to construct this $\\text{neg}$ set: Once all the anchor boxes are sorted by objectiveness confidence score, the model picks the top candidates for training so that neg:pos is at most 3:1.\nYOLOv2 / YOLO9000\n#\nYOLOv2\n(\nRedmon & Farhadi, 2017\n) is an enhanced version of YOLO.\nYOLO9000\nis built on top of YOLOv2 but trained with joint dataset combining the COCO detection dataset and the top 9000 classes from ImageNet.\nYOLOv2 Improvement\n#\nA variety of modifications are applied to make YOLO prediction more accurate and faster, including:\n1. BatchNorm helps\n: Add\nbatch norm\non all the convolutional layers, leading to significant improvement over convergence.\n2. Image resolution matters\n: Fine-tuning the base model with\nhigh resolution\nimages improves the detection performance.\n3. Convolutional anchor box detection\n: Rather than predicts the bounding box position with fully-connected layers over the whole feature map, YOLOv2 uses\nconvolutional layers\nto predict locations of\nanchor boxes\n, like in faster R-CNN. The prediction of spatial locations and class probabilities are decoupled. Overall, the change leads to a slight decrease in mAP, but an increase in recall.\n4. K-mean clustering of box dimensions\n: Different from faster R-CNN that uses hand-picked sizes of anchor boxes, YOLOv2 runs k-mean clustering on the training data to find good priors on anchor box dimensions. The distance metric is designed to\nrely on IoU scores\n:\n$$\n\\text{dist}(x, c_i) = 1 - \\text{IoU}(x, c_i), i=1,\\dots,k\n$$\nwhere $x$ is a ground truth box candidate and $c_i$ is one of the centroids. The best number of centroids (anchor boxes) $k$ can be chosen by the\nelbow method\n.\nThe anchor boxes generated by clustering provide better average IoU conditioned on a fixed number of boxes.\n5. Direct location prediction\n: YOLOv2 formulates the bounding box prediction in a way that it would\nnot diverge\nfrom the center location too much. If the box location prediction can place the box in any part of the image, like in regional proposal network, the model training could become unstable.\nGiven the anchor box of size $(p_w, p_h)$ at the grid cell with its top left corner at $(c_x, c_y)$, the model predicts the offset and the scale, $(t_x, t_y, t_w, t_h)$ and the corresponding predicted bounding box $b$ has center $(b_x, b_y)$ and size $(b_w, b_h)$. The confidence score is the sigmoid ($\\sigma$) of another output $t_o$.\n$$\n\\begin{aligned}\nb_x &= \\sigma(t_x) + c_x\\\\\nb_y &= \\sigma(t_y) + c_y\\\\\nb_w &= p_w e^{t_w}\\\\\nb_h &= p_h e^{t_h}\\\\\n\\text{Pr}(\\text{object}) &\\cdot \\text{IoU}(b, \\text{object}) = \\sigma(t_o)\n\\end{aligned}\n$$\nYOLOv2 bounding box location prediction. (Image source:\noriginal paper\n)\n6. Add fine-grained features\n: YOLOv2 adds a passthrough layer to bring\nfine-grained features\nfrom an earlier layer to the last output layer. The mechanism of this passthrough layer is similar to\nidentity mappings in ResNet\nto extract higher-dimensional features from previous layers. This leads to 1% performance increase.\n7. Multi-scale training\n: In order to train the model to be robust to input images of different sizes, a\nnew size\nof input dimension is\nrandomly sampled\nevery 10 batches. Since conv layers of YOLOv2 downsample the input dimension by a factor of 32, the newly sampled size is a multiple of 32.\n8. Light-weighted base model\n: To make prediction even faster, YOLOv2 adopts a light-weighted base model, DarkNet-19, which has 19 conv layers and 5 max-pooling layers. The key point is to insert avg poolings and 1x1 conv filters between 3x3 conv layers.\nYOLO9000: Rich Dataset Training\n#\nBecause drawing bounding boxes on images for object detection is much more expensive than tagging images for classification, the paper proposed a way to combine small object detection dataset with large ImageNet so that the model can be exposed to a much larger number of object categories. The name of YOLO9000 comes from the top 9000 classes in ImageNet. During joint training, if an input image comes from the classification dataset, it only backpropagates the classification loss.\nThe detection dataset has much fewer and more general labels and, moreover, labels cross multiple datasets are often not mutually exclusive. For example, ImageNet has a label “Persian cat” while in COCO the same image would be labeled as “cat”. Without mutual exclusiveness, it does not make sense to apply softmax over all the classes.\nIn order to efficiently merge ImageNet labels (1000 classes, fine-grained) with COCO/PASCAL (< 100 classes, coarse-grained), YOLO9000 built a hierarchical tree structure with reference to\nWordNet\nso that general labels are closer to the root and the fine-grained class labels are leaves. In this way, “cat” is the parent node of “Persian cat”.\nThe WordTree hierarchy merges labels from COCO and ImageNet. Blue nodes are COCO labels and red nodes are ImageNet labels. (Image source:\noriginal paper\n)\nTo predict the probability of a class node, we can follow the path from the node to the root:\nPr(\"persian cat\" | contain a \"physical object\") \n= Pr(\"persian cat\" | \"cat\") \n  Pr(\"cat\" | \"animal\") \n  Pr(\"animal\" | \"physical object\") \n  Pr(contain a \"physical object\")    # confidence score.\nNote that\nPr(contain a \"physical object\")\nis the confidence score, predicted separately in the bounding box detection pipeline. The path of conditional probability prediction can stop at any step, depending on which labels are available.\nRetinaNet\n#\nThe\nRetinaNet\n(\nLin et al., 2018\n) is a one-stage dense object detector. Two crucial building blocks are\nfeaturized image pyramid\nand the use of\nfocal loss\n.\nFocal Loss\n#\nOne issue for object detection model training is an extreme imbalance between background that contains no object and foreground that holds objects of interests.\nFocal loss\nis designed to assign more weights on hard, easily misclassified examples (i.e. background with noisy texture or partial object) and to down-weight easy examples (i.e. obviously empty background).\nStarting with a normal cross entropy loss for binary classification,\n$$\n\\text{CE}(p, y) = -y\\log p - (1-y)\\log(1-p)\n$$\nwhere $y \\in \\{0, 1\\}$ is a ground truth binary label, indicating whether a bounding box contains a object, and $p \\in [0, 1]$ is the predicted probability of objectiveness (aka confidence score).\nFor notational convenience,\n$$\n\\text{let } p_t = \\begin{cases}\np    & \\text{if } y = 1\\\\\n1-p  & \\text{otherwise}\n\\end{cases},\n\\text{then } \\text{CE}(p, y)=\\text{CE}(p_t) = -\\log p_t\n$$\nEasily classified examples with large $p_t \\gg 0.5$, that is, when $p$ is very close to 0 (when y=0) or 1 (when y=1), can incur a loss with non-trivial magnitude. Focal loss explicitly adds a weighting factor $(1-p_t)^\\gamma, \\gamma \\geq 0$ to each term in cross entropy so that the weight is small when $p_t$ is large and therefore easy examples are down-weighted.\n$$\n\\text{FL}(p_t) = -(1-p_t)^\\gamma \\log p_t\n$$\nThe focal loss focuses less on easy examples with a factor of $(1-p\\_t)^\\gamma$. (Image source:\noriginal paper\n)\nFor a better control of the shape of the weighting function (see Fig. 10.), RetinaNet uses an $\\alpha$-balanced variant of the focal loss, where $\\alpha=0.25, \\gamma=2$ works the best.\n$$\n\\text{FL}(p_t) = -\\alpha (1-p_t)^\\gamma \\log p_t\n$$\nThe plot of focal loss weights $\\alpha (1-p\\_t)^\\gamma$ as a function of $p\\_t$, given different values of $\\alpha$ and $\\gamma$.\nFeaturized Image Pyramid\n#\nThe\nfeaturized image pyramid\n(\nLin et al., 2017\n) is the backbone network for RetinaNet. Following the same approach by\nimage pyramid\nin SSD, featurized image pyramids provide a basic vision component for object detection at different scales.\nThe key idea of feature pyramid network is demonstrated in The base structure contains a sequence of\npyramid levels\n, each corresponding to one network\nstage\n. One stage contains multiple convolutional layers of the same size and the stage sizes are scaled down by a factor of 2. Let’s denote the last layer of the $i$-th stage as $C_i$.\nThe illustration of the featurized image pyramid module. (Replot based on figure 3 in\nFPN paper\n)\nTwo pathways connect conv layers:\nBottom-up pathway\nis the normal feedforward computation.\nTop-down pathway\ngoes in the inverse direction, adding coarse but semantically stronger feature maps back into the previous pyramid levels of a larger size via lateral connections.\nFirst, the higher-level features are upsampled spatially coarser to be 2x larger. For image upscaling, the paper used nearest neighbor upsampling. While there are many\nimage upscaling algorithms\nsuch as using\ndeconv\n, adopting another image scaling method might or might not improve the performance of RetinaNet.\nThe larger feature map undergoes a 1x1 conv layer to reduce the channel dimension.\nFinally, these two feature maps are merged by element-wise addition.\nThe lateral connections only happen at the last layer in stages, denoted as $\\{C_i\\}$, and the process continues until the finest (largest) merged feature map is generated. The prediction is made out of every merged map after a 3x3 conv layer, $\\{P_i\\}$.\nAccording to ablation studies, the importance rank of components of the featurized image pyramid design is as follows:\n1x1 lateral connection\n> detect object across multiple layers  > top-down enrichment > pyramid representation (compared to only check the finest layer).\nModel Architecture\n#\nThe featurized pyramid is constructed on top of the ResNet architecture. Recall that\nResNet\nhas 5 conv blocks (= network stages / pyramid levels). The last layer of the $i$-th pyramid level, $C_i$, has resolution $2^i$ lower than the raw input dimension.\nRetinaNet utilizes feature pyramid levels $P_3$ to $P_7$:\n$P_3$ to $P_5$ are computed from the corresponding ResNet residual stage from $C_3$ to $C_5$. They are connected by both top-down and bottom-up pathways.\n$P_6$ is obtained via a 3×3 stride-2 conv on top of $C_5$\n$P_7$ applies ReLU and a 3×3 stride-2 conv on $P_6$.\nAdding higher pyramid levels on ResNet improves the performance for detecting large objects.\nSame as in SSD, detection happens in all pyramid levels by making a prediction out of every merged feature map. Because predictions share the same classifier and the box regressor, they are all formed to have the same channel dimension d=256.\nThere are A=9 anchor boxes per level:\nThe base size corresponds to areas of $32^2$ to $512^2$ pixels on $P_3$ to $P_7$ respectively. There are three size ratios, $\\{2^0, 2^{1/3}, 2^{2/3}\\}$.\nFor each size, there are three aspect ratios {1/2, 1, 2}.\nAs usual, for each anchor box, the model outputs a class probability for each of $K$ classes in the classification subnet and regresses the offset from this anchor box to the nearest ground truth object in the box regression subnet. The classification subnet adopts the focal loss introduced above.\nThe RetinaNet model architecture uses a\nFPN\nbackbone on top of ResNet. (Image source: the\nFPN\npaper)\nYOLOv3\n#\nYOLOv3\nis created by applying a bunch of design tricks on YOLOv2. The changes are inspired by recent advances in the object detection world.\nHere are a list of changes:\n1. Logistic regression for confidence scores\n: YOLOv3 predicts an confidence score for each bounding box using\nlogistic regression\n, while YOLO and YOLOv2 uses sum of squared errors for classification terms (see the\nloss function\nabove). Linear regression of offset prediction leads to a decrease in mAP.\n2. No more softmax for class prediction\n: When predicting class confidence, YOLOv3 uses\nmultiple independent logistic classifier\nfor each class rather than one softmax layer. This is very helpful especially considering that one image might have multiple labels and not all the labels are guaranteed to be mutually exclusive.\n3. Darknet + ResNet as the base model\n: The new Darknet-53 still relies on successive 3x3 and 1x1 conv layers, just like the original dark net architecture, but has residual blocks added.\n4. Multi-scale prediction\n: Inspired by image pyramid, YOLOv3 adds several conv layers after the base feature extractor model and makes prediction at three different scales among these conv layers. In this way, it has to deal with many more bounding box candidates of various sizes overall.\n5. Skip-layer concatenation\n: YOLOv3 also adds cross-layer connections between two prediction layers (except for the output layer) and earlier finer-grained feature maps. The model first up-samples the coarse feature maps and then merges it with the previous features by concatenation. The combination with finer-grained information makes it better at detecting small objects.\nInterestingly, focal loss does not help YOLOv3, potentially it might be due to the usage of $\\lambda_\\text{noobj}$ and $\\lambda_\\text{coord}$ — they increase the loss from bounding box location predictions and decrease the loss from confidence predictions for background boxes.\nOverall YOLOv3 performs better and faster than SSD, and worse than RetinaNet but 3.8x faster.\nThe comparison of various fast object detection models on speed and mAP performance. (Image source:\nfocal loss\npaper with additional labels from the\nYOLOv3\npaper.)\nCited as:\n@article{weng2018detection4,\n  title   = \"Object Detection Part 4: Fast Detection Models\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2018\",\n  url     = \"https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/\"\n}\nReference\n#\n[1] Joseph Redmon, et al.\n“You only look once: Unified, real-time object detection.”\nCVPR 2016.\n[2] Joseph Redmon and Ali Farhadi.\n“YOLO9000: Better, Faster, Stronger.”\nCVPR 2017.\n[3] Joseph Redmon, Ali Farhadi.\n“YOLOv3: An incremental improvement.”\n.\n[4] Wei Liu et al.\n“SSD: Single Shot MultiBox Detector.”\nECCV 2016.\n[5] Tsung-Yi Lin, et al.\n“Feature Pyramid Networks for Object Detection.”\nCVPR 2017.\n[6] Tsung-Yi Lin, et al.\n“Focal Loss for Dense Object Detection.”\nIEEE transactions on pattern analysis and machine intelligence, 2018.\n[7]\n“What’s new in YOLO v3?”\nby  Ayoosh Kathuria on “Towards Data Science”, Apr 23, 2018.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:43Z",
            "title": "Object Detection Part 4: Fast Detection Models | Lil'Log",
            "audio": [],
            "code_blocks": [
              {
                "file": "attachments/466144a71db1/code/body-000.txt",
                "chars": 195,
                "language": "text"
              },
              {
                "file": "attachments/466144a71db1/code/body-001.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "papers": [
              {
                "status": "ok",
                "url": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "bytes": 1270136,
                "reused": true,
                "local_path": "papers/repair/326369cb8bd278bd904e.pdf"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "retried_at": "2026-10-20T17:55:04Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1512.02325",
                "bytes": 2494225,
                "reused": true,
                "local_path": "papers/repair/b5f5e9ca4f7f92190f2f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1409.1556",
                "bytes": 200010,
                "reused": true,
                "local_path": "papers/repair/01560c40deef0c339e01.pdf"
              },
              {
                "status": "ok",
                "url": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "bytes": 132365,
                "reused": true,
                "local_path": "papers/repair/75b4690976ed5ab1f64d.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.08242",
                "bytes": 5256083,
                "reused": true,
                "local_path": "papers/repair/1288fc7e9385e0345e39.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1708.02002",
                "bytes": 1297358,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/c9512e3ffac1aabce76e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1612.03144",
                "bytes": 789142,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/0cd1e11096f8a72ff39b.pdf"
              },
              {
                "status": "ok",
                "url": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "bytes": 2241388,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/5bc4175dabe4accf71a9.pdf"
              },
              {
                "status": "ok",
                "url": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "bytes": 5392639,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/edb99b1cb9792a271703.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 25701,
            "expected_body_images": 13,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "http_404",
            "raw_html": "attachments/466144a71db1/pages/source.html",
            "local_html": "attachments/466144a71db1/pages/article.html",
            "body_base_path": "attachments/466144a71db1/pages/",
            "body_markdown_path": "attachments/466144a71db1/pages/article.md",
            "links": [
              {
                "href": "https://lilianweng.github.io/posts/2017-12-31-object-recognition-part-3/",
                "label": "Part 3",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-10-29-object-recognition-part-1/",
                "label": "Part 1",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-12-15-object-recognition-part-2/",
                "label": "Part 2",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/",
                "label": "Part 4",
                "type": "a"
              },
              {
                "href": "https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf",
                "label": "Redmon et al., 2016",
                "type": "a"
              },
              {
                "href": "https://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf",
                "label": "GoogLeNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1512.02325",
                "label": "Liu et al, 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1409.1556",
                "label": "VGG-16",
                "type": "a"
              },
              {
                "href": "https://github.com/rbgirshick/py-faster-rcnn/files/764206/SmoothL1Loss.1.pdf",
                "label": "smooth L1 loss",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits",
                "label": "softmax_cross_entropy_with_logits",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.08242",
                "label": "Redmon & Farhadi, 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Elbow_method_(clustering)",
                "label": "elbow method",
                "type": "a"
              },
              {
                "href": "https://wordnet.princeton.edu/",
                "label": "WordNet",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1708.02002",
                "label": "Lin et al., 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1612.03144",
                "label": "Lin et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Image_scaling",
                "label": "image upscaling algorithms",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/api_docs/python/tf/layers/conv2d_transpose",
                "label": "deconv",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2018-12-27-object-recognition-part-4/TBA",
                "label": "ResNet",
                "type": "a"
              },
              {
                "href": "https://pjreddie.com/media/files/papers/YOLOv3.pdf",
                "label": "YOLOv3",
                "type": "a"
              },
              {
                "href": "http://openaccess.thecvf.com/content_cvpr_2017/papers/Redmon_YOLO9000_Better_Faster_CVPR_2017_paper.pdf",
                "label": "“YOLO9000: Better, Faster, Stronger.”",
                "type": "a"
              },
              {
                "href": "https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b",
                "label": "“What’s new in YOLO v3?”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
          "status": "partial",
          "article_id": "e63a1e66232d",
          "local_path": "series-follow/1601/repair/b1aa14adf7d8adb2ac0a.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
              "bytes": 189766,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/afc61371a02b455239c2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
              "bytes": 13941,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9d81c38b488b3632ed8d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
              "bytes": 339657,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c3b89516ea58d513c6e4.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
              "bytes": 46457,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5e6d7c0353c6dcedff22.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
              "bytes": 55893,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7f08154f4714c6af05cf.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
              "bytes": 77504,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/c47361447354e9dc9408.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
              "bytes": 141447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/128df9c78ce434cf9940.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
              "bytes": 42173,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/f5c3b685a188e7a1f7ea.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
              "bytes": 87321,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bb941fda00c0e424d832.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
              "bytes": 1969955,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/1c06e799c7666968bc4d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
              "bytes": 709079,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/35ad6bb4c9b5f2023552.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
              "bytes": 313503,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/69879f285ee667db6764.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
              "bytes": 157401,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/2ee071176ef01990b7b2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
              "bytes": 134727,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/b639597a6e7d3aecf854.png"
            }
          ],
          "article": {
            "id": "e63a1e66232d",
            "url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "source_excel_row": 1601,
            "source_url": "https://lilianweng.github.io/posts/2017-06-21-overview/",
            "is_paid_flag": "",
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "bytes": 189766,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-afc61371a02b455239c2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/ANN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "bytes": 13941,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-9d81c38b488b3632ed8d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/data_size_vs_model_performance.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "bytes": 339657,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c3b89516ea58d513c6e4.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/visual_cortex_system.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "bytes": 46457,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-5e6d7c0353c6dcedff22.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/lenet.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "bytes": 55893,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-7f08154f4714c6af05cf.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/RNN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "bytes": 77504,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-c47361447354e9dc9408.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/LSTM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "bytes": 141447,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-128df9c78ce434cf9940.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/rnn_shakespeare.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "bytes": 42173,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-f5c3b685a188e7a1f7ea.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/seq2seq_gmail.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "bytes": 87321,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-bb941fda00c0e424d832.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "bytes": 1969955,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-1c06e799c7666968bc4d.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/autoencoder_experiment.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "bytes": 709079,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-35ad6bb4c9b5f2023552.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_paper.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "bytes": 313503,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-69879f285ee667db6764.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/alphago_model.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "bytes": 157401,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-2ee071176ef01990b7b2.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/GAN.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "bytes": 134727,
                "reused": false,
                "content_type": "image/png",
                "local_path": "attachments/e63a1e66232d/images/body-b639597a6e7d3aecf854.png",
                "src": "https://lilianweng.github.io/posts/2017-06-21-overview/deep_learning_toolkits.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "videos": [
              {
                "url": "https://www.youtube.com/watch?v=vFr3K2DORc8",
                "src": "https://youtu.be/vFr3K2DORc8",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-vFr3K2DORc8.mp4",
                "bytes": 753957028,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "14106.021000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=F1ka6a13S9I",
                "src": "https://youtu.be/F1ka6a13S9I",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-F1ka6a13S9I.mp4",
                "bytes": 456526601,
                "valid": true,
                "height": 720,
                "width": 1280,
                "duration": "4787.481000",
                "reused": false
              },
              {
                "url": "https://www.youtube.com/watch?v=uAu3jQWaN6E",
                "src": "https://youtu.be/uAu3jQWaN6E",
                "status": "ok",
                "kind": "single_video",
                "local_path": "attachments/e63a1e66232d/videos/repair-uAu3jQWaN6E.mp4",
                "bytes": 183061332,
                "valid": true,
                "height": 1080,
                "width": 1920,
                "duration": "438.401000",
                "reused": false
              }
            ],
            "body_markdown": "(The post was originated from my talk for\nWiMLDS x Fintech meetup\nhosted by\nAffirm\n.)\nI believe many of you have watched or heard of the\ngames\nbetween AlphaGo and professional Go player\nLee Sedol\nin 2016. Lee has the highest rank of nine dan and many world championships. No doubt, he is one of the best Go players in the world, but he\nlost by 1-4\nin this series versus AlphaGo. Before this, Go was considered to be an intractable game for computers to master, as its simple rules lay out an exponential number of variations in the board positions, many more than what in Chess. This event surely highlighted 2016 as a big year for AI. Because of AlphaGo, much attention has been attracted to the progress of AI.\nMeanwhile, many companies are spending resources on pushing the edges of AI applications, that indeed have the potential to change or even revolutionize how we are gonna live. Familiar examples include self-driving cars, chatbots, home assistant devices and many others. One of the secret receipts behind the progress we have had in recent years is deep learning.\nWhy Does Deep Learning Work Now?\n#\nDeep learning models, in simple words, are large and deep artificial neural nets. A neural network (“NN”) can be well presented in a\ndirected acyclic graph\n: the input layer takes in signal vectors; one or multiple hidden layers process the outputs of the previous layer. The initial concept of a neural network can be traced back to more than\nhalf a century ago\n. But why does it work now? Why do people start talking about them all of a sudden?\nA three-layer artificial neural network. (Image source:\nhttp://cs231n.github.io/convolutional-networks/#conv\n)\nThe reason is surprisingly simple:\nWe have a lot\nmore data\n.\nWe have\nmuch powerful computers\n.\nA large and deep neural network has many more layers + many more nodes in each layer, which results in exponentially many more parameters to tune. Without enough data, we cannot learn parameters efficiently. Without powerful computers, learning would be too slow and insufficient.\nHere is an interesting plot presenting the relationship between the data scale and the model performance, proposed by Andrew Ng in his “\nNuts and Bolts of Applying Deep Learning\n” talk. On a small dataset, traditional algorithms (Regression, Random Forests, SVM, GBM, etc.) or statistical learning does a great job, but once the data scale goes up to the sky, the large NN outperforms others. Partially because compared to a traditional ML model, a neural network model has many more parameters and has the capability to learn complicated nonlinear patterns. Thus we expect the model to pick the most helpful features by itself without too much expert-involved manual feature engineering.\nThe data scale versus the model performance. (Recreated based on:\nhttps://youtu.be/F1ka6a13S9I\n)\nDeep Learning Models\n#\nNext, let’s go through a few classical deep learning models.\nConvolutional Neural Network\n#\nConvolutional neural networks, short for “CNN”, is a type of feed-forward artificial neural networks, in which the connectivity pattern between its neurons is inspired by the organization of the visual cortex system. The primary visual cortex (V1) does edge detection out of the raw visual input from the retina. The secondary visual cortex (V2), also called prestriate cortex, receives the edge features from V1 and extracts simple visual properties such as orientation, spatial frequency, and color. The visual area V4 handles more complicated object attributes. All the processed visual features flow into the final logic unit, inferior temporal gyrus (IT), for object recognition. The shortcut between V1 and V4 inspires a special type of CNN with connections between non-adjacent layers: Residual Net (\nHe, et al. 2016\n) containing “Residual Block” which supports some input of one layer to be passed to the component two layers later.\nIllustration of the human visual cortex system. (Image source:\nWang & Raj 2017\n)\nConvolution is a mathematical term, here referring to an operation between two matrices. The convolutional layer has a fixed small matrix defined, also called kernel or filter. As the kernel is sliding, or convolving, across the matrix representation of the input image, it is computing the element-wise multiplication of the values in the kernel matrix and the original image values.\nSpecially designed kernels\ncan process images for common purposes like blurring, sharpening, edge detection and many others, fast and efficiently.\nThe LeNet architecture consists of two sets of convolutional, activation, and pooling layers, followed by a fully-connected layer, activation, another fully-connected layer, and finally a softmax classifier (Image source:\nhttp://deeplearning.net/tutorial/lenet.html\n)\nConvolutional\nand\npooling\n(or “sub-sampling” in Fig. 4) layers act like the V1, V2 and V4 visual cortex units, responding to feature extraction. The object recognition reasoning happens in the later fully-connected layers which consume the extracted features.\nRecurrent Neural Network\n#\nA sequence model is usually designed to transform an input sequence into an output sequence that lives in a different domain. Recurrent neural network, short for “RNN”, is suitable for this purpose and has shown tremendous improvement in problems like handwriting recognition, speech recognition, and machine translation (\nSutskever et al. 2011\n,\nLiwicki et al. 2007\n).\nA recurrent neural network model is born with the capability to process long sequential data and to tackle tasks with context spreading in time. The model processes one element in the sequence at one time step. After computation, the newly updated unit state is passed down to the next time step to facilitate the computation of the next element. Imagine the case when an RNN model reads all the Wikipedia articles, character by character, and then it can predict the following words given the context.\nA recurrent neural network with one hidden unit (left) and its unrolling version in time (right). The unrolling version illustrates what happens in time: $s\\_{t-1}$, $s\\_{t}$, and $s\\_{t+1}$ are the same unit with different states at different time steps $t-1$, $t$, and $t+1$. (Image source:\nLeCun, Bengio, and Hinton, 2015\n;\nFig. 5\n)\nHowever, simple perceptron neurons that linearly combine the current input element and the last unit state may easily lose the long-term dependencies. For example, we start a sentence with “Alice is working at …” and later after a whole paragraph, we want to start the next sentence with “She” or “He” correctly. If the model forgets the character’s name “Alice”, we can never know. To resolve the issue, researchers created a special neuron with a much more complicated internal structure for memorizing long-term context, named\n“Long-short term memory (LSTM)”\ncell. It is smart enough to learn for how long it should memorize the old information, when to forget, when to make use of the new data, and how to combine the old memory with new input. This\nintroduction\nis so well written that I recommend everyone with interest in LSTM to read it. It has been officially promoted in the\nTensorflow documentation\n;-)\nThe structure of a LSTM cell. (Image source:\nhttp://colah.github.io/posts/2015-08-Understanding-LSTMs\n)\nTo demonstrate the power of RNNs,\nAndrej Karpathy\nbuilt a character-based language model using RNN with LSTM cells.  Without knowing any English vocabulary beforehand, the model could learn the relationship between characters to form words and then the relationship between words to form sentences. It could achieve a decent performance even without a huge set of training data.\nA character-based recurrent neural network model writes like a Shakespeare. (Image source:\nhttp://karpathy.github.io/2015/05/21/rnn-effectiveness\n)\nRNN: Sequence-to-Sequence Model\n#\nThe\nsequence-to-sequence model\nis an extended version of RNN, but its application field is distinguishable enough that I would like to list it in a separated section. Same as RNN, a sequence-to-sequence model operates on sequential data, but particularly it is commonly used to develop chatbots or personal assistants, both generating meaningful response for input questions. A sequence-to-sequence model consists of two RNNs, encoder and decoder. The encoder learns the contextual information from the input words and then hands over the knowledge to the decoder side through a “\ncontext vector\n” (or “thought vector”, as shown in Fig 8.). Finally, the decoder consumes the context vector and generates proper responses.\nA sequence-to-sequence model for generating Gmail auto replies. (Image source:\nhttps://research.googleblog.com/2015/11/computer-respond-to-this-email.html\n)\nAutoencoders\n#\nDifferent from the previous models, autoencoders are for unsupervised learning. It is designed to learn a\nlow-dimensional\nrepresentation of a\nhigh-dimensional\ndata set, similar to what\nPrincipal Components Analysis (PCA)\ndoes. The autoencoder model tries to learn an approximation function $ f(x) \\approx x $ to reproduce the input data. However, it is restricted by a bottleneck layer in the middle with a very small number of nodes. With limited capacity, the model is forced to form a very efficient encoding of the data, that is essentially the low-dimensional code we learned.\nAn autoencoder model has a bottleneck layer with only a few neurons. (Image source: Geoffrey Hinton’s Coursera class\n\"Neural Networks for Machine Learning\"\n-\nWeek 15\n)\nHinton and Salakhutdinov\nused autoencoders to compress documents on a variety of topics. As shown in Fig 10, when both PCA and autoencoder were applied to reduce the documents onto two dimensions, autoencoder demonstrated a much better outcome. With the help of autoencoder, we can do efficient data compression to speed up the information retrieval including both documents and images.\nThe outputs of PCA (left) and autoencoder (right) when both try to compress documents into two numbers. (Image source:\nHinton & Salakhutdinov 2006\n)\nReinforcement (Deep) Learning\n#\nSince I started my post with AlphaGo, let us dig a bit more on why AlphaGo worked out.\nReinforcement learning (“RL”)\nis one of the secrets behind its success. RL is a subfield of machine learning which allows machines and software agents to automatically determine the optimal behavior within a given context, with a goal to maximize the long-term performance measured by a given metric.\nAlphaGo neural network training pipeline and architecture. (Image source:\nSilver et al. 2016\n)\nThe AlphaGo system starts with a supervised learning process to train a fast rollout policy and a policy network, relying on the manually curated training dataset of professional players’ games. It learns what is the best strategy given the current position on the game board. Then it applies reinforcement learning by setting up self-play games. The RL policy network gets improved when it wins more and more games against previous versions of the policy network. In the self-play stage, AlphaGo becomes stronger and stronger by playing against itself without requiring additional external training data.\nGenerative Adversarial Network\n#\nGenerative adversarial network\n, short for “GAN”, is a type of deep generative models. GAN is able to create new examples after learning through the real data.  It is consist of two models competing against each other in a zero-sum game framework. The famous deep learning researcher\nYann LeCun\ngave it a super high praise: Generative Adversarial Network is the most interesting idea in the last ten years in machine learning. (See the Quora question:\n“What are some recent and potentially upcoming breakthroughs in deep learning?”\n)\nThe architecture of a generative adversarial network. (Image source:\nhttp://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html\n)\nIn the\noriginal GAN paper\n, GAN was proposed to generate meaningful images after learning from real photos. It comprises two independent models: the\nGenerator\nand the\nDiscriminator\n. The generator produces fake images and sends the output to the discriminator model. The discriminator works like a judge, as it is optimized for identifying the real photos from the fake ones. The generator model is trying hard to cheat the discriminator while the judge is trying hard not to be cheated. This interesting zero-sum game between these two models motivates both to develop their designed skills and improve their functionalities. Eventually, we take the generator model for producing new images.\nToolkits and Libraries\n#\nAfter learning all these models, you may start wondering how you can implement the models and use them for real. Fortunately, we have many open source toolkits and libraries for building deep learning models.\nTensorflow\nis fairly new but has attracted a lot of popularity. It turns out, TensorFlow was\nthe most forked Github project of 2015\n. All that happened in a period of 2 months after its release in Nov 2015.\nHow to Learn?\n#\nIf you are very new to the field and willing to devote some time to studying deep learning in a more systematic way, I would recommend you to start with the book\nDeep Learning\nby Ian Goodfellow, Yoshua Bengio, and Aaron Courville. The Coursera course\n“Neural Networks for Machine Learning”\nby Geoffrey Hinton (\nGodfather of deep learning!\n). The content for the course was prepared around 2006, pretty old, but it helps you build up a solid foundation for understanding deep learning models and expedite further exploration.\nMeanwhile, maintain your curiosity and passion. The field is making progress every day. Even classical or widely adopted deep learning models may just have been proposed 1-2 years ago. Reading academic papers can help you learn stuff in depth and keep up with the cutting-edge findings.\nUseful resources\n#\nGoogle Scholar:\nhttp://scholar.google.com\narXiv cs section:\nhttps://arxiv.org/list/cs/recent\nUnsupervised Feature Learning and Deep Learning Tutorial\nTensorflow Tutorials\nData Science Weekly\nKDnuggets\nTons of blog posts and online tutorials\nRelated\nCousera\ncourses\nawesome-deep-learning-papers\nBlog posts mentioned\n#\nExplained Visually: Image Kernels\nUnderstanding LSTM Networks\nThe Unreasonable Effectiveness of Recurrent Neural Networks\nComputer, respond to this email.\nInteresting blogs worthy of checking\n#\nwww.wildml.com\ncolah.github.io\nkarpathy.github.io\nblog.openai.com\nPapers mentioned\n#\n[1] He, Kaiming, et al.\n“Deep residual learning for image recognition.”\nProc. IEEE Conf. on computer vision and pattern recognition. 2016.\n[2] Wang, Haohan, Bhiksha Raj, and Eric P. Xing.\n“On the Origin of Deep Learning.”\narXiv preprint arXiv:1702.07800, 2017.\n[3] Sutskever, Ilya, James Martens, and Geoffrey E. Hinton.\n“Generating text with recurrent neural networks.”\nProc. of the 28th Intl. Conf. on Machine Learning (ICML). 2011.\n[4] Liwicki, Marcus, et al.\n“A novel approach to on-line handwriting recognition based on bidirectional long short-term memory networks.”\nProc. of 9th Intl. Conf. on Document Analysis and Recognition. 2007.\n[5] LeCun, Yann, Yoshua Bengio, and Geoffrey Hinton.\n“Deep learning.”\nNature 521.7553 (2015): 436-444.\n[6] Hochreiter, Sepp, and Jurgen Schmidhuber.\n“Long short-term memory.”\nNeural computation 9.8 (1997): 1735-1780.\n[7] Cho, Kyunghyun. et al.\n“Learning phrase representations using RNN encoder-decoder for statistical machine translation.”\nProc. Conference on Empirical Methods in Natural Language Processing 1724–1734 (2014).\n[8] Hinton, Geoffrey E., and Ruslan R. Salakhutdinov.\n“Reducing the dimensionality of data with neural networks.”\nscience 313.5786 (2006): 504-507.\n[9] Silver, David, et al.\n“Mastering the game of Go with deep neural networks and tree search.”\nNature 529.7587 (2016): 484-489.\n[10] Goodfellow, Ian, et al.\n“Generative adversarial nets.”\nNIPS, 2014.",
            "repair_version": 2,
            "repaired_at": "2026-10-14T11:45:58Z",
            "title": "An Overview of Deep Learning for Curious People | Lil'Log",
            "audio": [],
            "code_blocks": [],
            "papers": [
              {
                "status": "ok",
                "url": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "bytes": 603123,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/ed3b4a363f27c6c78ac0.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800",
                "bytes": 5805767,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/bd56c51399250ef0ff86.pdf"
              },
              {
                "status": "download_error",
                "url": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "reason": "ConnectionError: HTTPConnectionPool(host='machinelearning.wustl.edu', port=80): Max retries exceeded with url: /mlpapers/paper_files/ICML2011Sutskever_524.pdf (Caused by NameResolutionError(\"HTTPCo",
                "retried_at": "2026-10-20T22:23:46Z"
              },
              {
                "status": "invalid_file_type",
                "url": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "content_type": "text/html; charset=utf-8",
                "retried_at": "2026-10-20T17:50:42Z"
              },
              {
                "status": "ok",
                "url": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "bytes": 2083627,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/6fc2936fa52baa80ec2c.pdf"
              },
              {
                "status": "download_error",
                "url": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "reason": "SSLError: HTTPSConnectionPool(host='web.eecs.utk.edu', port=443): Max retries exceeded with url: /~itamar/courses/ECE-692/Bobby_paper1.pdf (Caused by SSLError(SSLCertVerificationError(1, '[S",
                "retried_at": "2026-10-20T22:23:49Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.1078.pdf",
                "bytes": 1142296,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/009ff3a0e4de38cf4fd9.pdf"
              },
              {
                "status": "http_404",
                "url": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "http_404",
                "url": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "retried_at": "2026-10-20T17:50:41Z"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1406.2661.pdf",
                "bytes": 530482,
                "reused": true,
                "local_path": "papers/repair/ee65f498ce3f3e038de2.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1702.07800.pdf",
                "bytes": 5805767,
                "reused": true,
                "local_path": "papers/repair/bd21c9c5b15c3410f312.pdf"
              },
              {
                "status": "ok",
                "url": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "bytes": 2682222,
                "reused": false,
                "content_type": "application/pdf",
                "local_path": "papers/repair/478be2320822b77dc4d3.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 15875,
            "expected_body_images": 14,
            "discovery_status": "ok",
            "delivery_status": "partial",
            "missing_reason": "download_error；http_404；invalid_file_type",
            "raw_html": "attachments/e63a1e66232d/pages/source.html",
            "local_html": "attachments/e63a1e66232d/pages/article.html",
            "body_base_path": "attachments/e63a1e66232d/pages/",
            "body_markdown_path": "attachments/e63a1e66232d/pages/article.md",
            "links": [
              {
                "href": "http://wimlds.org/chapters/about-bay-area/",
                "label": "WiMLDS x Fintech meetup",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2017-06-21-overview/www.affirm.com",
                "label": "Affirm",
                "type": "a"
              },
              {
                "href": "https://youtu.be/vFr3K2DORc8",
                "label": "games",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Lee_Sedol",
                "label": "Lee Sedol",
                "type": "a"
              },
              {
                "href": "https://www.scientificamerican.com/article/how-the-computer-beat-the-go-master/",
                "label": "lost by 1-4",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Directed_acyclic_graph",
                "label": "directed acyclic graph",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/people/eroberts/courses/soco/projects/neural-networks/History/history1.html",
                "label": "half a century ago",
                "type": "a"
              },
              {
                "href": "http://cs231n.github.io/convolutional-networks/",
                "label": "http://cs231n.github.io/convolutional-networks/#conv",
                "type": "a"
              },
              {
                "href": "https://youtu.be/F1ka6a13S9I",
                "label": "Nuts and Bolts of Applying Deep Learning",
                "type": "a"
              },
              {
                "href": "http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf",
                "label": "He, et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1702.07800",
                "label": "Wang & Raj 2017",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels/",
                "label": "Specially designed kernels",
                "type": "a"
              },
              {
                "href": "http://deeplearning.net/tutorial/lenet.html",
                "label": "http://deeplearning.net/tutorial/lenet.html",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/",
                "label": "Convolutional",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/supervised/Pooling/",
                "label": "pooling",
                "type": "a"
              },
              {
                "href": "http://machinelearning.wustl.edu/mlpapers/paper_files/ICML2011Sutskever_524.pdf",
                "label": "Sutskever et al. 2011",
                "type": "a"
              },
              {
                "href": "http://www6.in.tum.de/Main/Publications/Liwicki2007a.pdf",
                "label": "Liwicki et al. 2007",
                "type": "a"
              },
              {
                "href": "http://pages.cs.wisc.edu/~dyer/cs540/handouts/deep-learning-nature2015.pdf",
                "label": "LeCun, Bengio, and Hinton, 2015",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/nature/journal/v521/n7553/fig_tab/nature14539_F5.html",
                "label": "Fig. 5",
                "type": "a"
              },
              {
                "href": "http://web.eecs.utk.edu/~itamar/courses/ECE-692/Bobby_paper1.pdf",
                "label": "“Long-short term memory (LSTM)”",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs/",
                "label": "introduction",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/recurrent",
                "label": "Tensorflow documentation",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "label": "http://colah.github.io/posts/2015-08-Understanding-LSTMs",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness/",
                "label": "Andrej Karpathy",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "label": "http://karpathy.github.io/2015/05/21/rnn-effectiveness",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.1078.pdf",
                "label": "sequence-to-sequence model",
                "type": "a"
              },
              {
                "href": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "label": "https://research.googleblog.com/2015/11/computer-respond-to-this-email.html",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Principal_component_analysis",
                "label": "Principal Components Analysis (PCA)",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks",
                "label": "\"Neural Networks for Machine Learning\"",
                "type": "a"
              },
              {
                "href": "https://www.coursera.org/learn/neural-networks/home/week/15",
                "label": "Week 15",
                "type": "a"
              },
              {
                "href": "https://pdfs.semanticscholar.org/7d76/b71b700846901ac4ac119403aa737a285e36.pdf",
                "label": "Hinton and Salakhutdinov",
                "type": "a"
              },
              {
                "href": "https://www.cs.toronto.edu/~hinton/science.pdf",
                "label": "Hinton & Salakhutdinov 2006",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Reinforcement_learning",
                "label": "Reinforcement learning (“RL”)",
                "type": "a"
              },
              {
                "href": "https://www.nature.com/articles/nature16961",
                "label": "Silver et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1406.2661.pdf",
                "label": "Generative adversarial network",
                "type": "a"
              },
              {
                "href": "http://yann.lecun.com/",
                "label": "Yann LeCun",
                "type": "a"
              },
              {
                "href": "https://www.quora.com/What-are-some-recent-and-potentially-upcoming-breakthroughs-in-deep-learning",
                "label": "“What are some recent and potentially upcoming breakthroughs in deep learning?”",
                "type": "a"
              },
              {
                "href": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "label": "http://www.kdnuggets.com/2017/01/generative-adversarial-networks-hot-topic-machine-learning.html",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/",
                "label": "Tensorflow",
                "type": "a"
              },
              {
                "href": "http://deliprao.com/archives/168",
                "label": "the most forked Github project of 2015",
                "type": "a"
              },
              {
                "href": "https://www.amazon.com/Deep-Learning-Adaptive-Computation-Machine/dp/0262035618/ref=sr_1_1?s=books&ie=UTF8&qid=1499413305&sr=1-1&keywords=deep+learning",
                "label": "Deep Learning",
                "type": "a"
              },
              {
                "href": "https://youtu.be/uAu3jQWaN6E",
                "label": "Godfather of deep learning!",
                "type": "a"
              },
              {
                "href": "http://scholar.google.com/",
                "label": "http://scholar.google.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/list/cs/recent",
                "label": "https://arxiv.org/list/cs/recent",
                "type": "a"
              },
              {
                "href": "http://ufldl.stanford.edu/tutorial/",
                "label": "Unsupervised Feature Learning and Deep Learning Tutorial",
                "type": "a"
              },
              {
                "href": "https://www.tensorflow.org/tutorials/",
                "label": "Tensorflow Tutorials",
                "type": "a"
              },
              {
                "href": "http://coursera.com/",
                "label": "Cousera",
                "type": "a"
              },
              {
                "href": "https://github.com/terryum/awesome-deep-learning-papers",
                "label": "awesome-deep-learning-papers",
                "type": "a"
              },
              {
                "href": "http://setosa.io/ev/image-kernels",
                "label": "Explained Visually: Image Kernels",
                "type": "a"
              },
              {
                "href": "http://www.wildml.com/",
                "label": "www.wildml.com",
                "type": "a"
              },
              {
                "href": "http://colah.github.io/",
                "label": "colah.github.io",
                "type": "a"
              },
              {
                "href": "http://karpathy.github.io/",
                "label": "karpathy.github.io",
                "type": "a"
              },
              {
                "href": "https://blog.openai.com/",
                "label": "blog.openai.com",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/pdf/1702.07800.pdf",
                "label": "“On the Origin of Deep Learning.”",
                "type": "a"
              },
              {
                "href": "http://web.iitd.ac.in/~sumeet/Silver16.pdf",
                "label": "“Mastering the game of Go with deep neural networks and tree search.”",
                "type": "a"
              }
            ],
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            }
          }
        },
        {
          "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
          "status": "ok",
          "article_id": "c811c8fa03ef",
          "local_path": "series-follow/1601/repair/30b6e9434771c5fcef0e.html",
          "images": [
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
              "bytes": 439380,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/cd75f36109d9a8976ce6.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
              "bytes": 581069,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e0cb70b1716fc6541886.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
              "bytes": 124447,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/bae92611d020d867c823.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
              "bytes": 234189,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/5ede211aaa74090777be.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
              "bytes": 1134478,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/037e75ccc6667d3dd676.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
              "bytes": 169121,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/eb009e9e4995ad677d20.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
              "bytes": 238097,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e98d393b3034f7b93c42.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
              "bytes": 3433956,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/931034d1f77fea4a9b89.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
              "bytes": 279963,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/67ca3976dba24dedc5f2.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
              "bytes": 137174,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/e95985488d6654cc5673.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
              "bytes": 884311,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/6291c7ba7f2547d16349.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
              "bytes": 472655,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/49d8a2995980c00d678d.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
              "bytes": 191203,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/a407ab83faa199042c24.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
              "bytes": 237219,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/54c0cf380132c67d2456.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
              "bytes": 986067,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/595316073143c8f09324.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
              "bytes": 334330,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/7f21eb25c4d7577b7655.png"
            },
            {
              "status": "ok",
              "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
              "bytes": 235579,
              "reused": false,
              "content_type": "image/png",
              "local_path": "series-follow/1601/repair/assets/9ff79113319b46733509.png"
            }
          ],
          "article": {
            "source_file": "0930",
            "source_platform": "个人博客",
            "author": "Lilian Weng / Lil'Log",
            "title_listed": "How to Train Really Large Models on Many GPUs?",
            "keywords": "分布式训练,并行,大模型",
            "domain": "机器学习",
            "content_type": "深度技术解析",
            "is_paid_flag": "否",
            "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "publish_date": "2021-09",
            "corpus_stage": "预训练/SFT",
            "notes": "多GPU大规模模型训练技术综述",
            "id": "c811c8fa03ef",
            "collected_at": "2026-10-02T14:12:59",
            "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
            "body_markdown": "[Updated on 2022-03-13: add\nexpert choice routing\n.]\n[Updated on 2022-06-10]:\nGreg\nand I wrote a shorted and upgraded version of this post, published on OpenAI Blog:\n“Techniques for Training Large Neural Networks”\nIn recent years, we are seeing better results on many NLP benchmark tasks with larger pre-trained\nlanguage models\n. How to train large and deep neural networks is challenging, as it demands a large amount of GPU memory and a long horizon of training time.\nHowever an individual GPU worker has limited memory and the sizes of many large models have grown beyond a single GPU. There are several parallelism paradigms to enable model training across multiple GPUs, as well as a variety of model architecture and memory saving designs to help make it possible to train\nvery large\nneural networks.\nTraining Parallelism\n#\nThe main bottleneck for training very large neural network models is the intense demand for a large amount of GPU memory, way above what can be hosted on an individual GPU machine. Besides the model weights (e.g. tens of billions of floating point numbers), it is usually even more expensive to store intermediate computation outputs such as gradients and optimizer states (e.g. momentums & variations in Adam). Additionally training a large model often pairs with a large training corpus and thus a single process may just take forever.\nAs a result, parallelism is necessary. Parallelism can happen at different dimensions, including data, model architecture, and tensor operation.\nData Parallelism\n#\nThe most naive way for\nData parallelism (DP)\nis to copy the same model weights into multiple workers and assign a fraction of data to each worker to be processed at the same time.\nNaive DP cannot work well if the model size is larger than a single GPU node’s memory. Methods like\nGeePS\n(\nCui et al. 2016\n) offload temporarily unused parameters back to CPU to work with limited GPU memory when the model is too big to fit into one machine. The data swapping transfer should happen at the backend and not interfere with training computation.\nAt the end of each minibatch, workers need to synchronize gradients or weights to avoid staleness. There are two main synchronization approaches and both have clear pros & cons.\nBulk synchronous parallels (BSP)\n: Workers sync data at the end of every minibatch. It prevents model weights staleness and good learning efficiency but each machine has to halt and wait for others to send gradients.\nAsynchronous  parallel (ASP)\n: Every GPU worker processes the data asynchronously, no waiting or stalling. However, it can easily lead to stale weights being used and thus lower the statistical learning efficiency. Even though it increases the computation time, it may not speed up training time to convergence.\nSomewhere in the middle is to synchronize gradients globally once every $x$ iterations ($x > 1$). This feature is called “gradient accumulation” in Distribution Data Parallel (\nDDP\n) since Pytorch v1.5 (\nLi et al. 2021\n). Bucketing gradients avoid immediate\nAllReduce\noperations but instead buckets multiple gradients into one\nAllReduce\nto improve throughput. Computation and communication scheduling optimization can be made based on the computation graph.\nPseudo code for Pytorch DDP. (Image source:\nLi et al. 2021\n)\nModel Parallelism\n#\nModel parallelism (MP)\naims to solve the case when the model weights cannot fit into a single node. The computation and model parameters are partitioned across multiple machines. Different from data parallelism where each worker hosts a full copy of the entire model, MP only allocates a fraction of model parameters on one worker and thus both the memory usage and the computation are reduced.\nSince deep neural networks usually contain a stack of vertical layers, it feels straightforward to split a large model by layer, where a small consecutive set of layers are grouped into one partition on one worker. However, a naive implementation for running every data batch through multiple such workers with sequential dependency leads to big bubbles of waiting time and severe under-utilization of computation resources.\nA naive model parallelism setup where the model is vertically split into 4 partitions. Data is processed by one worker at a time due to sequential dependency, leading to large “bubbles” of idle time. (Image source:\nHuang et al. 2019\n)\nPipeline Parallelism\n#\nPipeline parallelism (PP)\ncombines model parallelism with data parallelism to reduce inefficient time “bubbles’’. The main idea is to split one minibatch into multiple microbatches and enable each stage worker to process one microbatch simultaneously. Note that every microbatch needs two passes, one forward and one backward. Inter-worker communication only transfers activations (forward) and gradients (backward). How these passes are scheduled and how the gradients are aggregated vary in different approaches. The number of partitions (workers) is also known as\npipeline depth\n.\nIn\nGPipe\n(\nHuang et al. 2019\n) gradients from multiple microbatches are aggregated and applied synchronously at the end. The synchronous gradient descent guarantees learning consistency and efficiency irrespective of the number of workers. As shown in Fig. 3, bubbles still exist but are much smaller than what’s in Given $m$ evenly split microbatches and $d$ partitions, assuming both forward and backward per microbatch take one unit of time, the fraction of bubble is:\n$$\n1 - \\frac{2md}{(2m + 2(d-1))d} = \\frac{d-1}{m+d-1}\n$$\nThe GPipe paper observed that the bubble overhead is almost negligible if the number of microbatches is more than 4x the number of partitions $m > 4d$ (when\nactivation recomputation\nis applied).\nIllustration of pipeline parallelism in GPipe with 4 microbatches and 4 partitions. GPipe aggregates and updates gradients across devices synchronously at the end of every batch. (Image source:\nHuang et al. 2019\n)\nGPipe achieves almost linear speedup in throughput with the number of devices, although it is not always guaranteed if the model parameters are not evenly distributed across workers.\nPipeDream\n(\nNarayanan et al. 2019\n) schedules each worker to alternatively process the forward and backward passes (\n1F1B\n).\nPipeDream names each model partition “stage” and each stage worker can have multiple replicas to run data parallelism. In this process, PipeDream uses a deterministic round-robin load balancing strategy to assign work among multiple replicas of stages to ensure that the forward and backward passes for the same minibatch happen on the same replica.\nIllustration of `1F1B` microbatch scheduling in PipeDream. (Image source:\nHarlap et al. 2018\n)\nSince PipeDream does not have an end-of-batch global gradient sync across all the workers, an native implementation of 1F1B can easily lead to the forward and backward passes of one microbatch using different versions of model weights, thus lowering the learning efficiency. PipeDream proposed a few designs to tackle this issue:\nWeight stashing\n: Each worker keeps track of several model versions and makes sure that the same version of weights are used in the forward and backward passes given one data batch.\nVertical sync\n(Optional): The version of model weights flows between stage workers together with activations and gradients. Then the computation adopts the corresponding stashed version propagated from the previous worker. This process keeps version consistency across workers. Note that it is asynchronous, different from GPipe.\nAt the beginning of a training run, PipeDream first profiles the computation memory cost and time of each layer in the model and then optimizes a solution for partitioning layers into stages, which is a dynamic programming problem.\nResults for VGG16 on ILSVRC12. (Top) Accuracy vs time. The integer marks the number of stage workers. ASP =  Asynchronous  parallel & BSP = Bulk synchronous parallels. (Bottom) Training time speedup for different parallelism configurations. Straight pipeline refers to pipeline parallelism without data parallelism. (Image source:\nHarlap et al. 2018\n)\nTwo variations of PipeDream were later proposed to reduce the memory footprint by stashed model versions (\nNarayanan et al. 2021\n).\nPipeDream-flush\nadds a globally synchronized pipeline flush periodically, just like GPipe. In this way, it greatly reduces the memory footprint (i.e. only maintain a single version of model weights) by sacrificing a little throughput.\nIllustration of pipeline scheduling in PipeDream-flush. (Image source: (\nNarayanan et al. 2021\n)\nPipeDream-2BW\nmaintains only two versions of model weights, where “2BW” is short for “double-buffered weights”. It generates a new model version every $k$ microbatches and $k$ should be larger than the pipeline depth $d$, $k > d$. A newly updated model version cannot fully replace the old version immediately since some leftover backward passes still depend on the old version. In total only two versions need to be saved so the memory cost is much reduced.\nIllustration of pipeline scheduling in PipeDream-2BW. (Image source: (\nNarayanan et al. 2021\n)\nTensor Parallelism\n#\nBoth model and pipeline parallelisms split a model vertically. OTOH we can horizontally partition the computation for one tensor operation across multiple devices, named\nTensor parallelism (TP)\n.\nLet’s take the transformer as an example given its popularity. The transformer model mainly consists of layers of MLP and self-attention blocks.\nMegatron-LM\n(\nShoeybi et al. 2020\n) adopts a simple way to parallelize intra-layer computation for MLP and self-attention.\nA MLP layer in a transformer contains a GEMM (General matrix multiply) followed by an non-linear GeLU transfer. Let’s split weight matrix $A$ by column:\n$$\n\\begin{aligned}\n\\text{Split }A &= [A_1, A_2] \\\\\nY &=\\text{GeLU}(XA) \\\\\n[Y_1, Y_2] &= [\\text{GeLU}(XA_1), \\text{GeLU}(XA_2)]\n\\end{aligned}\n$$\nThe attention block runs GEMM with query ($Q$), key ($K$), and value weights ($V$) according to the above partitioning in parallel and then combines them with another GEMM to produce the attention head results.\n$$\n\\text{Attention}(X, Q, K, V) = \\text{softmax}(\\frac{(XQ) (XK)^\\top}{\\sqrt{d_k}}) XV\n$$\nIllustration of tensor parallelism for key transformer components proposed in Megatron-LM. (Image source:\nShoeybi et al. 2020\n)\nNarayanan et al. (2021)\ncombined pipeline, tensor and data parallelism with a new pipeline scheduling strategy and named their approach\nPTD-P\n. Instead of only positioning a continuous set of layers (“model chunk”) on a device, each worker can be assigned with multiple chunks of smaller continuous subsets of layers (e.g. device 1 has layers 1, 2, 9, 10; device 2 has layers 3, 4, 11, 12; each has two model chunks). The number of microbatches in one batch should be exactly divided by the number of workers ($m % d = 0$). If there are $v$ model chunks per worker, the pipeline bubble time can be reduced by a multiplier of $v$ compared to a GPipe scheduling.\n(Top) Default `1F1B` pipeline schedule as in PipeDream-flush. (Bottom) Interleaved 1F1B pipeline schedule. First model chunks are in dark colors and second chunks are in light colors. (Image source:\nNarayanan et al. 202)\n)\nMixture-of-Experts (MoE)\n#\nThe\nMixture-of-Experts (MoE)\napproach attracts a lot of attention recently as researchers (mainly from Google) try to push the limit of model size. The core of the idea is\nensembling learning\n:\nCombination of multiple weak learners gives you a strong learner!\nWithin one deep neural network, ensembling can be implemented with a gating mechanism connecting multiple experts (\nShazeer et al., 2017\n). The gating mechanism controls which subset of the network (e.g. which experts) should be activated to produce outputs. The paper named it “sparsely gated mixture-of-experts” (MoE) layer.\nPrecisely one MoE layer contains\n$n$ feed-forward networks as experts $\\{E_i\\}^n_{i=1}$\nA trainable gating network $G$ to learn a probability distribution over $n$ experts so as to route the traffic to a few selected experts.\nDepending on the gating outputs, not every expert has to be evaluated. When the number of experts is too large, we can consider using a two-level hierarchical MoE.\nIllustration of a mixture-of-experts (MoE) layer. Only 2 out of $n$ experts are selected and activated by the gating network. (Image source:\nShazeer et al., 2017\n)\nA simple choice of $G$ is to multiply the input with a trainable weight matrix $G_g$ and then do softmax: $G_\\sigma (x) = \\text{softmax}(x W_g)$. However, this produces a dense control vector for gating and does not help save computation resources because we don’t need to evaluate an expert only when $G^{(i)}(x)=0$. Thus the MoE layer only keeps the top $k$ values. It also adds tunable Gaussian noise into $G$ to improve load balancing. This mechanism is called\nnoisy top-k gating\n.\n$$\n\\begin{aligned} \nG(x) &= \\text{softmax}( \\text{topk}(H(x), k)) \\\\\nH^{(i)}(x) &= (xW_g)^{(i)} + \\epsilon \\cdot \\text{softplus}((xW_\\text{noise})^{(i)} ); \\quad \\epsilon \\sim \\mathcal{N}(0, \\mathbf{1}) \\\\\n\\text{topk}^{(i)}(v, k) &= \\begin{cases} v^{(i)} & \\text{if }v^{(i)}\\text{ is in the top }k\\text{ elements of }v \\\\ -\\infty & \\text{otherwise} \n\\end{cases} \n\\end{aligned}\n$$\nwhere the superscript $v^{(i)}$ denotes the i-th dimension of the vector $v$. The function $\\text{topk}(., k)$ selected the top $k$ dimensions with highest values by setting other dimensions to $-\\infty$.\nTo avoid the self-reinforcing effect that the gating network may favor a few strong experts all the time,\nShazeer et al. (2017)\nproposed a soft constraint via an additional importance loss to encourage all the experts to have the same weights. It is equivalent to the square of the\ncoefficient of variation\nof batchwise average value per expert.\n$$\nL_\\text{aux} = w_\\text{aux} \\cdot \\text{CV}(\\sum_{x \\in X} G(x))^2\n$$\nwhere $ \\text{CV}$ is the coefficient of variation and the loss weight $w_\\text{aux}$ is a hyperparameter to tune.\nBecause every expert network only gets a fraction of training samples (“The shrinking batch problem”), we should try to use a batch size as large as possible in MoE. However, it is restricted by GPU memory. Data parallelism and model parallelism can be applied to improve the throughput.\nTest perplexity on 1-Billion-Word language modeling benchmark. (Left) The model capacity increases from left to right, containing 4, 32, 256, 256, 1024 and 4096 experts. (Right) Performance of the 4 billion parameters MoE model, the largest one in the left figure, under different computation budgets. (Image source:\nShazeer et al., 2017\n)\nGShard\n(\nLepikhin et al., 2020\n) scales the MoE transformer model up to 600 billion parameters with sharding. The MoE transformer replaces every other feed forward layer with a MoE layer. The\nsharded MoE transformer\nonly has the MoE layers sharded across multiple machines, while other layers are simply duplicated.\nThere are several improved designs for the gating function $G$ in GShard:\nExpert capacity\n: The amount of tokens going through one expert should not go above a threshold, named “expert capacity”. If a token is routed to experts that have reached their capacity, the token would be marked “overflowed” and the gating output is changed to a zero vector.\nLocal group dispatching\n: Tokens are evenly partitioned into multiple local groups and the expert capacity is enforced on the group level.\nAuxiliary loss\n: The motivation is similar to the original MoE aux loss. They add an auxiliary loss to minimize the mean square of the fraction of data routed to each expert.\nRandom routing\n: The 2nd-best expert is selected with a probability proportional to its weight; otherwise, GShard follows a random routing, so as to add some randomness.\nPseudo code of the group-level top-2 gating mechanism with auxiliary loss in GShard. (Image source:\nLepikhin et al., 2020\n)\nSwitch Transformer\n(\nFedus et al. 2021\n) scales the model size up to trillions of parameters (!!) by replacing the dense feed forward layer with a\nsparse switch FFN layer\nin which each input is only routed to\none\nexpert network. The auxiliary loss for load balancing is $\\text{loss}_\\text{aux} = w_\\text{aux} \\sum_{i=1}^n f_i p_i$ given $n$ experts, where $f_i$ is the fraction of tokens routed to the $i$-th expert and $p_i$ is the routing probability for expert $i$ predicted by the gating network.\nSwitch transformer. The sparse switch FFN layer is in the blue boxes. (Image source:\nFedus et al. 2021\n)\nTo improve training stability, switch transformer incorporates the following designs:\nSelective precision\n. They showed that selectively casting only a local part of the model to FP32 precision improves stability, while avoiding the expensive communication cost of FP32 tensors. The FP32 precision is only used within the body of the router function and the results are recast to FP16.\nSmaller initialization\n. The initialization of weight matrices is sampled from a truncated normal distribution with mean $\\mu=0$ and stdev $\\sigma = \\sqrt{s/n}$. They also recommended reducing the transformer initialization scale parameter $s=1$ to $s=0.1$.\nUse higher expert dropout\n. Fine-tuning often works with a small dataset. To avoid overfitting, the dropout rate within each expert is increased by a significant amount. Interestingly they found that increasing dropout across all layers lead to poor performance. In the paper, they used a dropout rate 0.1 at non-expert layers but 0.4 within expert FF layers.\nThe switch transformer paper summarized different data and model parallelism strategies for training large models with a nice illustration:\nAn illustration of various parallelism strategies on how (Top) model weights and (Bottom) data are split over multiple GPU cores. In the top row, each color denotes a unique weight matrix. In the bottom row, different colors indicate different sets of tokens.  (Image source:\nFedus et al. 2021\n)\nBoth GShard top-2 and Switch Transformer top-1 depend on\ntoken choice\n, where each token picks the best one or two experts to route through. They both adopt an auxiliary loss to encourage more balanced load allocation but it does not guarantee the best performance. Furthermore, the expert capacity limit may lead to wasted tokens as they would be discarded if an expert reaches its capacity limit.\nExport Choice (EC)\n(\nZhou et al. 2022\n) routing instead enables each expert to select the top-$k$ tokens. In this way, each expert naturally guarantees a fixed capacity and each token may be routed to multiple experts. EC can achieve perfect load balancing and is shown to improve training convergence by 2x.\nGiven $e$ experts and an input matrix $X \\in \\mathbb{R}^{n \\times d}$, the token-to-expert affinity scores are computed by:\n$$\nS = \\text{softmax}(X \\cdot W_g), \\text{where } W_g \\in \\mathbb{R}^{d \\times e}, S \\in \\mathbb{R}^{n \\times e}\n$$\nA token-to-expert assignment is represented by three matrices, $I, G \\in \\mathbb{R}^{e\\times k}$ and $P \\in \\mathbb{R}^{e \\times k \\times n}$. $I[i,j]$ annotates which token is the $j$-th selection by the $i$-th expert. The gating matrix $G$ stores the routing weights of selected tokens. $P$ is the one-hot version of $I$, used to produce the input matrix ($P \\cdot X \\in \\mathbb{R}^{e \\times k \\times d}$) for the gated FFN layer.\n$$\nG, I = \\text{top-k}(S^\\top, k)\\quad P = \\text{one-hot}(I)\n$$\nOne regularization that export choice routing explored is to limit the maximum number of experts per token.\n$$\n\\begin{aligned}\n& \\max_A \\langle S^\\top, A\\rangle + \\lambda H(A) \\\\\n\\text{s.t.} & \n\\forall i: \\sum_{j'} A[i, j'] = k,\\quad\n\\forall j: \\sum_{i'} A[i', j] \\leq b,\\quad\n\\forall i,j: 0 \\leq A[i,j] \\leq 1\n\\end{aligned}\n$$\nwhere each entry $A[i,j]$ in $A \\in \\mathbb{R}^{e \\times n}$ marks whether the $i$-the expert selects the $j$-th token. Solving this is non-trivial. The paper used\nDykstra’s algorithm\nthat runs a sequence of multiple iterative computation steps. Capped expert choice results in a slight decrease in the fine-tuning performance in the experiments.\nThe parameter $k$ is determined by $k=nc/e$, where $n$ is the total number of tokens in one batch and $c$ is a capacity factor indicating the average number of experts used by one token. The paper used $c=2$ in most experiments, but EC with $c=1$ still outperforms the top-1 token choice gating. Interestingly, $c=0.5$ only marginally hurts the training performance.\nOne big drawback of EC is that it does not work when the batch size is too small, neither for auto-regressive text generation, because it needs to know the future tokens to do the top-$k$ selection.\nOther Memory Saving Designs\n#\nCPU Offloading\n#\nWhen the GPU memory is full, one option is to offload temporarily unused data to CPU and read them back when needed later (\nRhu et al. 2016\n). The idea of\nCPU offloading\nis straightforward but is less popular in recent years due to the slowdown it brings into the training time.\nActivation Recomputation\n#\nActivation recomputation\n(also known as “activation checkpointing” or “gradient checkpointing”;\nChen et al. 2016\n) is a smart yet simple idea to reduce memory footprint at the cost of computation time. It reduces the memory cost of training a $\\ell$ layer deep neural net to $O(\\sqrt{\\ell})$, which only additionally consumes an extra forward pass computation per batch.\nLet’s say, we evenly divide an $\\ell$-layer network into $d$ partitions. Only activations at partition boundaries are saved and communicated between workers. Intermediate activations at intra-partition layers are still needed for computing gradients so they are recomputed during backward passes. With activation recomputation, the memory cost for training $M(\\ell)$ is:\n$$\nM(\\ell) \n=\\max_{i=1,\\dots,k} \\underbrace{\\text{cost-of-one-partition}(i)}_\\text{cost of back-propagation on the i-th partition} + \\underbrace{O(d)}_\\text{store intermediate outputs} \n= O(\\frac{\\ell}{d}) + O(d)\n$$\nThe minimum cost is $O(\\sqrt{\\ell})$ at $d=\\sqrt{\\ell}$.\nActivation recompuation trick can give sublinear memory cost with respect to the model size.\nThe memory cost of different memory saving algorithms.\nSharing\n: Memory used by intermediate results is recycled when no longer needed.\nInplace\n: Save the output directly into memory of an input value. (Image source:\nChen et al. 2016\n)\nMixed Precision Training\n#\nNarang & Micikevicius et al. (2018)\nintroduced a method to train models using half-precision floating point (FP16) numbers without losing model accuracy.\nThe procedure of mixed precision training at one layer. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nThree techniques to avoid losing critical information at half-precision:\nFull-precision master copy of weights\n. Maintain a full precision (FP32) copy of model weights that accumulates gradients. The numbers are rounded up to half-precision for forward & backward passes. The motivation is that each gradient update (i.e. gradient times the learning rate) might be too small to be fully contained within the FP16 range (i.e. $2^{-24}$ becomes zero in FP16).\nLoss scaling\n. Scale up the loss to better handle gradients with small magnitudes (See Fig. 16). Scaling up the gradients helps shift them to occupy a larger section towards the right section (containing larger values) of the representable range, preserving values that are otherwise lost.\nArithmetic precision\n. For common network arithmetic (e.g. vector dot-product, reduction by summing up vector elements), we can accumulate the partial results in FP32 and then save the final output as FP16 before saving into memory. Point-wise operations can be executed in either FP16 or FP32.\nThe histogram of gradients in full precision. The left part up to $2^{-24}$ will be zero-ed off once the model switches to FP16. (Image source:\nNarang & Micikevicius, et al. 2018\n)\nIn their experiments, loss scaling is not needed for some networks (e.g. image classification, Faster R-CNN), but necessary for others (e.g. Multibox SSD, big LSTM language model).\nCompression\n#\nIntermediate results often consume a lot of memory, although they are only needed in one forward pass and one backward pass. There is a noticeable temporal gap between these two uses. Thus\nJain et al. (2018)\nproposed a data encoding strategy to compress the intermediate results after the first use in the first pass and then decode it back for back-propagation later.\nTheir system\nGist\nincorporates two encoding schemes:\nLayer-specific lossless encoding\n; focus on ReLU-Pool (“Binarize”) and ReLU-Conv (“Sparse storage and dense computation”) patterns.\nAggressive lossy encoding\n; use delayed precision reduction (DPR). They observed that the first immediate use of feature maps should be kept at high precision but the second use can tolerate lower precision.\nThe experiments showed that Gist can reduce the memory cost by 2x across 5 SOTA image classification DNNs, with an average of 1.8x with only 4% performance overhead.\nMemory Efficient Optimizer\n#\nOptimizers are eager for memory consumption. Take the popular Adam optimizer as an example, it internally needs to maintain momentums and variances, both at the same scale as gradients and model parameters. All out of a sudden, we need to save 4x the memory of model weights.\nSeveral optimizers have been proposed to reduce the memory footprint.\nFor example, instead of storing the full momentums and variations as in Adam,\nAdafactor\n(\nShazeer et al. 2018\n) only tracks the per-row and per-column sums of the moving averages and then estimates the second moments based on these sums.\nSM3\n(\nAnil et al. 2019\n) describes a different adaptive optimization method, leading to largely reduced memory as well.\nZeRO\n(\nZero Redundancy Optimizer\n;\nRajbhandari et al. 2019\n) optimizes the memory used for training large models based on the observation about two major memory consumption of large model training:\nThe majority is occupied by\nmodel states\n, including optimizer states (e.g. Adam momentums and variances), gradients and parameters. Mixed-precision training demands a lot of memory since the optimizer needs to keep a copy of FP32 parameters and other optimizer states, besides the FP16 version.\nThe remaining is consumed by activations, temporary buffers and unusable fragmented memory (named\nresidual states\nin the paper).\nZeRO combines two approaches,\nZeRO-DP\nand\nZeRO-R\n.\nZeRO-DP is an enhanced data parallelism to avoid simple redundancy over model states. It partitions optimizer state, gradients and parameters across multiple data parallel processes via a dynamic communication schedule to minimize the communication volume.\nZeRO-R optimizes the memory consumption of residual states, using partitioned activation recomputation, constant buffer size and on-the-fly memory defragmentation.\nCitation\n#\nCited as:\nWeng, Lilian. (Sep 2021). How to train really large models on many GPUs? Lil’Log. https://lilianweng.github.io/posts/2021-09-25-train-large/.\nOr\n@article{weng2021large,\n  title   = \"How to Train Really Large Models on Many GPUs?\",\n  author  = \"Weng, Lilian\",\n  journal = \"lilianweng.github.io\",\n  year    = \"2021\",\n  month   = \"Sep\",\n  url     = \"https://lilianweng.github.io/posts/2021-09-25-train-large/\"\n}\nReferences\n#\n[1] Li et al.\n“PyTorch Distributed: Experiences on Accelerating Data Parallel Training”\nVLDB 2020.\n[2] Cui et al.\n“GeePS: Scalable deep learning on distributed GPUs with a GPU-specialized parameter server”\nEuroSys 2016\n[3] Shoeybi et al.\n“Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism.”\narXiv preprint arXiv:1909.08053 (2019).\n[4] Narayanan et al.\n“Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM.”\narXiv preprint arXiv:2104.04473 (2021).\n[5] Huang et al.\n“GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism.”\narXiv preprint arXiv:1811.06965 (2018).\n[6] Narayanan et al.\n“PipeDream: Generalized Pipeline Parallelism for DNN Training.”\nSOSP 2019.\n[7] Narayanan et al.\n“Memory-Efficient Pipeline-Parallel DNN Training.”\nICML 2021.\n[8] Shazeer et al.\n“The Sparsely-Gated Mixture-of-Experts Layer Noam.”\narXiv preprint arXiv:1701.06538 (2017).\n[9] Lepikhin et al.\n“GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding.”\narXiv preprint arXiv:2006.16668 (2020).\n[10] Fedus et al.\n“Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity.”\narXiv preprint arXiv:2101.03961 (2021).\n[11] Narang & Micikevicius, et al.\n“Mixed precision training.”\nICLR 2018.\n[12] Chen et al. 2016\n“Training Deep Nets with Sublinear Memory Cost.”\narXiv preprint arXiv:1604.06174 (2016).\n[13] Jain et al.\n“Gist: Efficient data encoding for deep neural network training.”\nISCA 2018.\n[14] Shazeer & Stern.\n“Adafactor: Adaptive learning rates with sublinear memory cost.”\narXiv preprint arXiv:1804.04235 (2018).\n[15] Anil et al.\n“Memory-Efficient Adaptive Optimization.”\narXiv preprint arXiv:1901.11150 (2019).\n[16] Rajbhandari et al.\n“ZeRO: Memory Optimization Towards Training A Trillion Parameter Models Samyam.”\narXiv preprint arXiv:1910.02054 (2019).\n[17] Zhou et al.\n“Mixture-of-Experts with Expert Choice Routing”\narXiv preprint arXiv:2202.09368 (2022).",
            "metadata": {
              "title": "How to Train Really Large Models on Many GPUs? | Lil'Log",
              "description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "keywords": "architecture, transformer, foundation",
              "author": "Lilian Weng",
              "og:title": "How to Train Really Large Models on Many GPUs?",
              "og:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "og:type": "article",
              "og:url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
              "twitter:card": "summary",
              "twitter:title": "How to Train Really Large Models on Many GPUs?",
              "twitter:description": "[Updated on 2022-03-13: add expert choice routing.]\n[Updated on 2022-06-10]: Greg and I wrote a shorted and upgraded version of this post, published on OpenAI Blog: “Techniques for Training Large Neural Networks”",
              "article:section": "posts",
              "article:published_time": "2021-09-24T00:00:00+00:00",
              "article:modified_time": "2021-09-24T00:00:00+00:00"
            },
            "paywall": {
              "listed_paid": false,
              "detected": false,
              "marker": "",
              "public_only": false,
              "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
            },
            "crawl": {
              "success": true,
              "status_code": 200,
              "error": ""
            },
            "code_blocks": [
              {
                "file": "attachments/c811c8fa03ef/code/body-000.txt",
                "chars": 264,
                "language": "text"
              }
            ],
            "images": [
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "bytes": 439380,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-cd75f36109d9a8976ce6.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pytorch-ddp.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "bytes": 581069,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e0cb70b1716fc6541886.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/naive-data-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "bytes": 124447,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-bae92611d020d867c823.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gpipe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "bytes": 234189,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-5ede211aaa74090777be.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "bytes": 1134478,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-037e75ccc6667d3dd676.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-results.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "bytes": 169121,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-eb009e9e4995ad677d20.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-flush.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "bytes": 238097,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e98d393b3034f7b93c42.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/pipedream-2bw.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "bytes": 3433956,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-931034d1f77fea4a9b89.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/Megatron-LM.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "bytes": 279963,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-67ca3976dba24dedc5f2.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/PTD-P-interleaved.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "bytes": 137174,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-e95985488d6654cc5673.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "bytes": 884311,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-6291c7ba7f2547d16349.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/moe-experiments.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "bytes": 472655,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-49d8a2995980c00d678d.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gshard-algo.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "bytes": 191203,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-a407ab83faa199042c24.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "bytes": 237219,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-54c0cf380132c67d2456.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/switch-transformer-parallelism.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "bytes": 986067,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-595316073143c8f09324.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/activation-checkpointing.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "bytes": 334330,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-7f21eb25c4d7577b7655.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/mixed-precision-training.png",
                "alt": "",
                "downloaded": true
              },
              {
                "status": "ok",
                "url": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "bytes": 235579,
                "reused": false,
                "local_path": "attachments/c811c8fa03ef/images/body-9ff79113319b46733509.png",
                "src": "https://lilianweng.github.io/posts/2021-09-25-train-large/gradient-histogram.png",
                "alt": "",
                "downloaded": true
              }
            ],
            "audio": [],
            "videos": [],
            "links": [
              {
                "href": "https://gregbrockman.com/",
                "label": "Greg",
                "type": "a"
              },
              {
                "href": "https://openai.com/blog/techniques-for-training-large-neural-networks/",
                "label": "“Techniques for Training Large Neural Networks”",
                "type": "a"
              },
              {
                "href": "https://lilianweng.github.io/posts/2019-01-31-lm/",
                "label": "language models",
                "type": "a"
              },
              {
                "href": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "label": "Cui et al. 2016",
                "type": "a"
              },
              {
                "href": "https://pytorch.org/tutorials/intermediate/ddp_tutorial.html",
                "label": "DDP",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.15704",
                "label": "Li et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1811.06965",
                "label": "Huang et al. 2019",
                "type": "a"
              },
              {
                "href": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "label": "Narayanan et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1806.03377",
                "label": "Harlap et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.09503",
                "label": "Narayanan et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1909.08053",
                "label": "Shoeybi et al. 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2104.04473",
                "label": "Narayanan et al. (2021)",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Ensemble_learning",
                "label": "ensembling learning",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1701.06538",
                "label": "Shazeer et al., 2017",
                "type": "a"
              },
              {
                "href": "https://en.wikipedia.org/wiki/Coefficient_of_variation",
                "label": "coefficient of variation",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2006.16668",
                "label": "Lepikhin et al., 2020",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2101.03961",
                "label": "Fedus et al. 2021",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/2202.09368",
                "label": "Zhou et al. 2022",
                "type": "a"
              },
              {
                "href": "https://projecteuclid.org/journals/annals-of-probability/volume-13/issue-3/An-Iterative-Procedure-for-Obtaining-I-Projections-onto-the-Intersection/10.1214/aop/1176992918.full",
                "label": "Dykstra’s algorithm",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1602.08124",
                "label": "Rhu et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arvix.org/abs/1604.06174",
                "label": "Chen et al. 2016",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1710.03740",
                "label": "Narang & Micikevicius et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "label": "Jain et al. (2018)",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1804.04235",
                "label": "Shazeer et al. 2018",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1901.11150",
                "label": "Anil et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1910.02054",
                "label": "Rajbhandari et al. 2019",
                "type": "a"
              },
              {
                "href": "https://arxiv.org/abs/1604.06174",
                "label": "“Training Deep Nets with Sublinear Memory Cost.”",
                "type": "a"
              }
            ],
            "repair_version": 2,
            "repaired_at": "2026-10-14T10:51:18Z",
            "source_url": "https://lilianweng.github.io/posts/2021-09-25-train-large/",
            "papers": [
              {
                "status": "ok",
                "url": "https://www.pdl.cmu.edu/PDL-FTP/CloudComputing/GeePS-cui-eurosys16.pdf",
                "bytes": 632686,
                "reused": false,
                "local_path": "papers/repair/52908466880352800110.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.15704",
                "bytes": 1189823,
                "reused": false,
                "local_path": "papers/repair/de67a2fc418e4e979224.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1811.06965",
                "bytes": 539195,
                "reused": false,
                "local_path": "papers/repair/b679a01b9227418fd9a9.pdf"
              },
              {
                "status": "ok",
                "url": "https://cs.stanford.edu/~matei/papers/2019/sosp_pipedream.pdf",
                "bytes": 1093659,
                "reused": false,
                "local_path": "papers/repair/df34f04afbea02133521.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1806.03377",
                "bytes": 629717,
                "reused": false,
                "local_path": "papers/repair/2ff8970af5c2784cd9ff.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.09503",
                "bytes": 2191490,
                "reused": false,
                "local_path": "papers/repair/e138d247bfb6dcf7dea8.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1909.08053",
                "bytes": 3850425,
                "reused": false,
                "local_path": "papers/repair/331df4b1898d1b3265b5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2104.04473",
                "bytes": 1035739,
                "reused": false,
                "local_path": "papers/repair/27509164ea73ad0d546e.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1701.06538",
                "bytes": 544288,
                "reused": true,
                "local_path": "papers/repair/f715adc72d48cc7ef55f.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2006.16668",
                "bytes": 1747868,
                "reused": false,
                "local_path": "papers/repair/1a83e3dc287448c001ca.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2101.03961",
                "bytes": 1304157,
                "reused": false,
                "local_path": "papers/repair/a780b9df79db7592bd38.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/2202.09368",
                "bytes": 605773,
                "reused": true,
                "local_path": "papers/repair/d8e47d8172aa52a16403.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1602.08124",
                "bytes": 2639789,
                "reused": false,
                "local_path": "papers/repair/84f5a94a2ee879df8044.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1710.03740",
                "bytes": 1404641,
                "reused": false,
                "local_path": "papers/repair/ac214b6a40a9661371fb.pdf"
              },
              {
                "status": "ok",
                "url": "https://www.microsoft.com/en-us/research/uploads/prod/2018/04/fiddle-gist-isca18.pdf",
                "bytes": 376198,
                "reused": false,
                "local_path": "papers/repair/743cd4a4899a05f67033.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1804.04235",
                "bytes": 380566,
                "reused": false,
                "local_path": "papers/repair/367ee59650fbf06da8e5.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1901.11150",
                "bytes": 7715288,
                "reused": false,
                "local_path": "papers/repair/f11d7704ae7d73afb205.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1910.02054",
                "bytes": 779206,
                "reused": false,
                "local_path": "papers/repair/f9be62e9c42c011fccb3.pdf"
              },
              {
                "status": "ok",
                "url": "https://arxiv.org/pdf/1604.06174",
                "bytes": 608189,
                "reused": false,
                "local_path": "papers/repair/ab261736da2d952b7190.pdf"
              }
            ],
            "actual_video_files": [],
            "body_chars": 29214,
            "expected_body_images": 17,
            "discovery_status": "ok",
            "delivery_status": "ok",
            "missing_reason": "",
            "raw_html": "attachments/c811c8fa03ef/pages/source.html",
            "local_html": "attachments/c811c8fa03ef/pages/article.html",
            "body_base_path": "attachments/c811c8fa03ef/pages/",
            "body_markdown_path": "attachments/c811c8fa03ef/pages/article.md"
          }
        }
      ],
      "updated_at": "2026-10-14T11:46:20Z",
      "finished": true,
      "remaining": 0,
      "repair_version": 3
    }
  ],
  "count": 13
}