<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://aryamccarthy.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://aryamccarthy.github.io/" rel="alternate" type="text/html" /><updated>2026-10-20T00:43:32+00:00</updated><id>https://aryamccarthy.github.io/feed.xml</id><title type="html">Arya McCarthy</title><subtitle>Research scientist at Google DeepMind. Narrowing the language divide.</subtitle><entry><title type="html">Two thoughts on group theory</title><link href="https://aryamccarthy.github.io/group-theory/" rel="alternate" type="text/html" title="Two thoughts on group theory" /><published>2022-03-26T00:00:00+00:00</published><updated>2022-03-26T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/group-theory</id><content type="html" xml:base="https://aryamccarthy.github.io/group-theory/"><![CDATA[<p>Each semester, I work through one or two textbooks. I’ve just picked up Dummit and Foote’s <em>Abstract Algebra</em> and begun chapter 1. (Weirdly, my math degree never introduced me to abstract algebra.) Two thoughts come to mind.</p>

<h2 id="faces-vertices-edges">Faces, vertices, edges</h2>

<p>First, I had a different route for solving Section 1.2’s problem 10 than the two suggested in the book. It’s not a particularly involved problem, but it’s still interesting.</p>

<!--more-->

<p>The question asks:</p>

<blockquote>
  <p>(10.) Let $G$ be the group of rigid motions in $\mathbb{R}^3$ of a cube. Show that $\lvert G \rvert = 24$.</p>
</blockquote>

<p>The advice given is:</p>

<blockquote>
  <p>[F]ind the number of positions to which an adjacent pair of vertices can be sent. Alternatively, you can find the number of places to which a given face may be sent and, once a face is fixed, the number of positions to which a vertex on that face may be sent.</p>
</blockquote>

<p>It’s worthwhile to see that there are actually three natural perspectives here, not just two. I’ve included my third one at the end.</p>

<ol>
  <li><strong>The vertex perspective.</strong> We can consider the vertices, as suggested. Consider adjacent vertices $i$ and $j$. Their motion will totally determine all other positions. The first vertex $i$ can be sent to 8 possible positions—the 8 vertices, including its initial position. The other vertex $j$ can then move to any of the 3 vertices adjacent to the repositioned $i$. No flips are possible, after all—rigid motions only. There are 8 repositionings of the vertex, with 3 corresponding rotations each. $\lvert G \rvert = 8 \times 3 = 24$.</li>
  <li><strong>The face perspective.</strong> Similarly, consider a given face $f$ and incident vertex $v$. Move $f$ to any of the possible faces, of which 6 exist (including its initial position). To remain incident, $v$ can be in any of 4 positions. Thus there are 6 possible repositionings and 4 rotations. $\lvert G \rvert = 6 \times 4 = 24$.</li>
  <li><strong>The edge perspective.</strong> This one was more natural to me. Consider any edge ${u, v}$ in the cube. It can be moved to any of the 12 edges’ initial positions, including its starting point. There are two orientations of this edge, though: placing $u$ and $v$ in different positions. $\lvert G \rvert = 12 \times 2 = 24$.</li>
</ol>

<p>Of course, these should—and do—all lead to the same answer.</p>

<h2 id="finding-a-cycle-decomposition">Finding a cycle decomposition</h2>

<p>There’s an intro algorithms connection to cycle decomposition which I thought worth sharing.</p>

<p>Cycle decompositions can be found with an algorithm provided in the book, which they (naturally) call the <strong>Cycle Decomposition Algorithm</strong>. Not stated in the book, these cycles are really strongly connected components of the graph. But because each must form a cycle, we don’t need to use an algorithm for strongly connected components. The weakly connected components (WCC) are necessarily strongly connected. We can use a simpler, cheaper algorithm to find the strongly connected components of a graph with this structure—not everything is a nail that needs, e.g., a <a href="https://en.wikipedia.org/wiki/Kosaraju's_algorithm">Kosaraju’s algorithm</a> hammer.
Here’s a WCC algorithm, defined in the vocabulary of abstract algebra.</p>

<p>Excerpted below:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">S_13</span><span class="p">:</span> <span class="n">Permutation</span> <span class="o">=</span> <span class="p">{</span>
    <span class="mi">1</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>  <span class="mi">4</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">6</span><span class="p">:</span> <span class="mi">9</span><span class="p">,</span>
    <span class="mi">7</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>  <span class="mi">8</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">9</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">12</span><span class="p">:</span> <span class="mi">8</span><span class="p">,</span>
    <span class="mi">13</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
<span class="p">}</span>  <span class="c1"># An example permutation of Ω defined in the book.
</span>
<span class="n">decomp</span> <span class="o">=</span> <span class="n">wcc_cycle_decomposition</span><span class="p">(</span><span class="n">S_13</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">format_nicely</span><span class="p">(</span><span class="n">decomp</span><span class="p">))</span>
<span class="c1"># (1 12 8 10 4) (2 13) (5 11 7) (6 9)
</span></code></pre></div></div>

<p>Full code:</p>

<script src="https://gist.github.com/2ce71471df74ab1262eb42fd21e6593b.js"> </script>]]></content><author><name></name></author><summary type="html"><![CDATA[Each semester, I work through one or two textbooks. I’ve just picked up Dummit and Foote’s Abstract Algebra and begun chapter 1. (Weirdly, my math degree never introduced me to abstract algebra.) Two thoughts come to mind. Faces, vertices, edges First, I had a different route for solving Section 1.2’s problem 10 than the two suggested in the book. It’s not a particularly involved problem, but it’s still interesting.]]></summary></entry><entry><title type="html">Semi-amortized variational autoencoders</title><link href="https://aryamccarthy.github.io/kim2018semi/" rel="alternate" type="text/html" title="Semi-amortized variational autoencoders" /><published>2020-04-09T00:00:00+00:00</published><updated>2020-04-09T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/kim2018semi</id><content type="html" xml:base="https://aryamccarthy.github.io/kim2018semi/"><![CDATA[<p>Latent variable models such as variational autoencoders (VAE) have been investigated in language modeling and conditional text generation, because they can handle data uncertainty and increase expressivity. VAEs in particular are optimized with an approach called amortized variational inference (AVI). There’s a gap, though, between what AVI can give and the true log-likelihood objective. (This is in addition to the approximation gap.) The authors (including my former mentor Sam Wiseman) proposed a learning strategy that uses higher-order gradients to combine AVI with stochastic variational inference (SVI). The consequence is that they mitigate posterior collapse, as visualized through saliency mapping.</p>

<!--more-->

<h2 id="background-and-approach">Background and approach</h2>

<p>I doubt anyone could lay out the terrain here better than the first three paragraphs of the paper. When we have an intractable distribution (such as a generative latent variable model \(p_\theta(x) = \int_z p_\theta(x, z) \mathrm{d}z\) where \(z\) is continuous and unobserved), we can use a tractable substitute \(q_\lambda \in Q\) to approximate it, optimizing to select the best member of the family \(Q\). This is called <strong>variational inference</strong>.<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup></p>

<p>Two ways to learn these distributions are <strong>stochastic variational inference (SVI)</strong> and <strong>amortized variational inference (AVI)</strong>. In SVI, we learn parameters \(\lambda\) for every data point (via gradient ascent). You can get a tight fit, but optimizing for every point is expensive. In AVI, we instead use a network shared (amortized) over the dataset to predict data point–specific parameters.</p>

<p><strong>Variational autoencoders</strong> are a type of deep generative model. They are learned with AVI, jointly training the generator and the parameter-predicting network. Unfortuntely, the <strong>amortization gap</strong> between the true log-likelihood and the VAE’s ELBO objective <a href="http://proceedings.mlr.press/v80/cremer18a.html">can be large</a>. (This is distinct from the <em>approximation gap</em> due to the variational family’s inability to fully represent the true distribution.)</p>

<p>While there are a dozen approaches to minimize this gap, this paper presents an exciting one: <strong>semi-amortized variational autoencoders</strong>. Their approach “differentiates <em>through</em> SVI while training the inference network/generative model.” The model combats the <strong>posterior collapse</strong> problem in variational autoencoders for text.</p>

<h3 id="stochastic-variational-inference">Stochastic variational inference</h3>

<p>This is the local approach, learning \(\lambda\) for each \(x\) (or each batch of x’s).</p>

<ol>
  <li>Sample a data point \(x\) from the training data.</li>
  <li>Randomly initialize \(\lambda\).</li>
  <li>Perform gradient updates to improve \(\lambda\) with respect to the ELBO objective, some \(k\) times.</li>
  <li>Now use gradient updates on the generator’s parameters \(\theta\).</li>
</ol>

<h3 id="amortized-variational-inference">Amortized variational inference</h3>

<p>This is the global approach: a shared network \(\mathrm{enc_\phi}\) predicts parameters \(\lambda\) for each point.</p>

<ol>
  <li>Sample a data point \(x\) from the training data.</li>
  <li>Set \(\lambda = \mathrm{enc_\phi}(x)\).</li>
  <li>Perform gradient updates to improve the generator’s parameters \(\theta\) with respect to the ELBO.</li>
  <li>Now use gradient updates on the encoder’s parameters \(\phi\).</li>
</ol>

<h3 id="semi-amortized-vaes">Semi-amortized VAEs</h3>

<p>This combines both approaches, using the encoder to initialize the SVI step.</p>

<ol>
  <li>Sample a data point \(x\) from the training data.</li>
  <li>Set \(\lambda = \mathrm{enc_\phi}(x)\).</li>
  <li>Perform gradient updates to improve \(\lambda\) with respect to the ELBO objective, some \(k\) times.</li>
  <li>Now use gradient updates on the generator’s parameters \(\theta\).</li>
  <li>Now use gradient updates on the encoder’s parameters \(\phi\).</li>
</ol>

<p>This involves backpropagation through gradient descent, as \(\lambda\) has developed a history. The authors appeal to LeCun et al. (1993) and Pearlmutter (1994).</p>

<h2 id="experiments">Experiments</h2>

<h3 id="matching-a-synthetic-distribution">Matching a Synthetic Distribution</h3>

<p>The authors create synthetic 5-character text sequences according to a generative model whose parameters are known. They then fix some of the parameters (the LSTMs that receive inputs from two normal distributions). The goal, then, is to match the remaining parameters. Their approach beats both AVI and SVI, and it achieves a higher lower-bound on the data.</p>

<h3 id="modeling-text">Modeling text</h3>

<p>Same, but real-world data. Their model is an LSTM, fed the variational posterior’s sample at every step.</p>

<h3 id="images">Images</h3>

<p>I was less interested in images, so I won’t summarize this part. While they don’t outperform the state of the art, their improvements are ‘orthogonal’ to the state of the art’s bag of tricks.</p>

<h2 id="discussion">Discussion</h2>

<p>To convince us that the latent variable is useful, they produce a saliency map. Based on the gradient of the likelihood with respect to the latent variable, they can infer which words rely on the variable more or less. It seems important to determining content words, sentence length, and the type of question word.</p>

<p>Still, as the authors note, their model is expensive if the generative model is expensive.</p>

<h2 id="trickshacks">Tricks/hacks</h2>

<p>Every paper with a neural network in it seems to have fifty hidden tricks to keep the whole edifice from falling apart. This paper uses:</p>

<ul>
  <li>Gradient (and Hessian) clipping during training to avoid exploding gradients and Hessians</li>
  <li>KL annealing (a scheduled alteration of the ELBO objective, gradually increasing the weight of the KL term) to mitigate posterior collapse. (<a href="https://arxiv.org/abs/1909.09237">This may not be necessary, if you’re willing to modify the loss function.</a>)</li>
</ul>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>Variational inference gets its name from the <a href="https://en.wikipedia.org/wiki/Calculus_of_variations">calculus of variations</a>, which is all about optimizing over sets of functions. In this case, we’ve picked a set of functions \(Q\), and the function we optimize is a lower bound on the log-likelihood of the data. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[Latent variable models such as variational autoencoders (VAE) have been investigated in language modeling and conditional text generation, because they can handle data uncertainty and increase expressivity. VAEs in particular are optimized with an approach called amortized variational inference (AVI). There’s a gap, though, between what AVI can give and the true log-likelihood objective. (This is in addition to the approximation gap.) The authors (including my former mentor Sam Wiseman) proposed a learning strategy that uses higher-order gradients to combine AVI with stochastic variational inference (SVI). The consequence is that they mitigate posterior collapse, as visualized through saliency mapping.]]></summary></entry><entry><title type="html">Interpolating between types and tokens by estimating power-law generators</title><link href="https://aryamccarthy.github.io/goldwater2006interpolating/" rel="alternate" type="text/html" title="Interpolating between types and tokens by estimating power-law generators" /><published>2020-04-08T00:00:00+00:00</published><updated>2020-04-08T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/goldwater2006interpolating</id><content type="html" xml:base="https://aryamccarthy.github.io/goldwater2006interpolating/"><![CDATA[<p>Your statistical model is trained under the assumption that its training distribution matches the testing distribution. If you want to learn from type-level data like a dictionary or gazetteer, it’s not as simple as appending those to your training data; it skews the distribution. In natural language, words occur with a power-law (Zipfian) distribution. We should have generators that match this. The authors make this by augmenting their generator with a frequency <strong>adaptor</strong>.</p>

<!--more-->

<hr />

<p>We resort to a two-stage language model:</p>

<ol>
  <li>A generator, which produces words (perhaps a uniform multinomial distribution)</li>
  <li>An adaptor, which governs their frequency.</li>
</ol>

<p>Our adaptor of choice is the Pitman–Yor process (PYP), which generalizes the Chinese restaurant process. It’s a way of seating people at tables (or adding new ones) where there’s a preference toward tables which are already crowded. The tables are infinitely expandable; they represent some label or class. The probability of being seated at a given table (put in a given class \(k\)) is gnarly:</p>

\[\Pr(z_i=k \mid \mathbf{z}_{&lt;i}) = 
\begin{cases} 
      \frac{n_k^{\mathbf{z}_{&lt;i}} - a}{i - 1 + b} &amp; 1 \le k \le K(\mathbf{z}_{&lt;i}) \\
      \frac{K(\mathbf{z}_{&lt;i})\,a + b}{i - 1 + b} &amp; k = K(\mathbf{z}_{&lt;i}) + 1
   \end{cases}\]

<p>And what’s worse: it feeds into a bigger equation for the probability of the \(i\)th word, since the labels of the tables are not fixed.</p>

<p>\(\begin{align}
\Pr(w_i = w \mid \mathbf{w}_{&lt;i}, \mathbf{z}_{&lt;i}, \theta)
 &amp;= \sum_k \sum_{\ell_k} \Pr(w_i = w \mid z_i = k, \ell_k) \Pr(\ell_k \mid \mathbf{w}_{&lt;i}, \mathbf{z}_{&lt;i}, \theta) \Pr(z_i=k \mid \mathbf{z}_{&lt;i})\\
  &amp;= \sum_k \sum_{\ell_k} [w_i =  \ell_k] \Pr(\ell_k \mid \mathbf{w}_{&lt;i}, \mathbf{z}_{&lt;i}, \theta) \Pr(z_i=k \mid \mathbf{z}_{&lt;i})\\
&amp;= \sum_{k=1}^{K(\mathbf{z}_{&lt;i})} \frac{n_k^{\mathbf{z}_{&lt;i}}-a}{i - 1 + b} [w = \ell_k] + \frac{K(\mathbf{z}_{&lt;i})a + b}{i - 1 + b}\theta_w
\end{align}\)
Here, \(\theta\) is the parameter for our multinomial distribution. \(K\) is the number of tables so far. \(n_k^{\mathbf{z}_{&lt;i}}\) is the number of people at table \(k\) so far. \(a\) and \(b\) control the power law’s intensity and the preference toward new tables, respectively.</p>

<p>From this, you can get the probability of a <em>sequence</em> of words by summing over all category values \(\mathbf{z}\) and table labelings \(\boldsymbol{\ell}\).</p>

<hr />

<p>When \(a\) approaches 1, the probability of a new table for a token drops to zero—every token gets its own table. Approaching 0 instead gives a type-based system. “The sum is dominated by the seating arrangement that minimizes the total number of tables…in which every word type receives a single table.”</p>

<p>To test their model, the authors use essentially a toy task: English verb segmentation into stem and affix. While they don’t compare to a baseline, they show that whether evaluating on types or tokens, low values of \(a\) helped—a preference toward types.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Your statistical model is trained under the assumption that its training distribution matches the testing distribution. If you want to learn from type-level data like a dictionary or gazetteer, it’s not as simple as appending those to your training data; it skews the distribution. In natural language, words occur with a power-law (Zipfian) distribution. We should have generators that match this. The authors make this by augmenting their generator with a frequency adaptor.]]></summary></entry><entry><title type="html">A Distributional and Orthographic Aggregation Model for English Derivational Morphology</title><link href="https://aryamccarthy.github.io/deutsch2018distributional/" rel="alternate" type="text/html" title="A Distributional and Orthographic Aggregation Model for English Derivational Morphology" /><published>2020-04-07T00:00:00+00:00</published><updated>2020-04-07T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/deutsch2018distributional</id><content type="html" xml:base="https://aryamccarthy.github.io/deutsch2018distributional/"><![CDATA[<p>Derivational morphology is that awkward, messy uncle that nobody really talks about, compared to its golden-boy sibling inflectional morphology. The authors present an improved system for generating derivational forms from their base words.</p>

<!--more-->

<h2 id="their-innovative-model-nearest-neighbor-search-of-word-embeddings">Their innovative model: nearest neighbor search of word embeddings</h2>

<p>Rather than look at the relationship in embedding space between all word pairs using a particular suffix, they look at all pairs using a particular transformation of meaning, like turning a verb into a noun which performs that verb’s action.</p>

<p>They also do a bit of filtering: nearest neighbor search in the embedding space suffers from a hubness problem—some words are everybody’s neighbor. Their heuristic is to take only words that start with the same 4 letters as the base word.</p>

<h2 id="their-seq2seq-model">Their seq2seq model</h2>

<p>There isn’t a perfect match between meaning and derivational suffixes. “-er” in “baker” marks an agent, but “-er” in “burner” marks a patient (the semantic object of the action). The authors collect word forms from a corpus, constraining their sequence-to-sequence word generator such that it only considers forms that they’ve observed.</p>

<p>The authors do rescoring by including both the seq2seq model’s score and the word’s frequency in the corpus as features into a simple neural network (a single-layer perceptron).</p>

<h2 id="other-notes">Other notes</h2>

<ul>
  <li>They found that shortest-path search was not much more expensive than beam search, so why not try it? Does about as well.
    <ul>
      <li>They say shortest path explores far fewer states than beam search. How can this be, when beam search restricts the search space and shortest path is exhaustive?</li>
    </ul>
  </li>
  <li>Nominal transformations were the biggest improvement over the baseline—there are lots of possible affixes, so the dictionary constraint helps restrict them to reasonable ones.</li>
</ul>

<p><strong>Future work.</strong></p>

<ul>
  <li>Label bias. It’s a thing that’ll come up when searching through that trie—it’s called the ‘beam problem’ in MT. A recent proposal ameliorates this by performing a weak form of global scoring.</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[Derivational morphology is that awkward, messy uncle that nobody really talks about, compared to its golden-boy sibling inflectional morphology. The authors present an improved system for generating derivational forms from their base words.]]></summary></entry><entry><title type="html">Word Ordering Without Syntax</title><link href="https://aryamccarthy.github.io/schmaltz2016word/" rel="alternate" type="text/html" title="Word Ordering Without Syntax" /><published>2019-05-26T00:00:00+00:00</published><updated>2019-05-26T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/schmaltz2016word</id><content type="html" xml:base="https://aryamccarthy.github.io/schmaltz2016word/"><![CDATA[<p>This paper was part of the wave that showed how recurrent neural nets could be applied to heaps of tasks. They find that a neural language model without explicit knowledge of syntax is effective at rediscovering the word order of a shuffled sentence.</p>

<!--more-->

<h2 id="problem">Problem</h2>

<p>The problem is pretty straightforward. You’re given the words and punctuation of a sentence, scrambled. Instead of “<em>Papa ate the caviar with a spoon .</em>”, you get “<em>. ate with the a caviar spoon Papa</em>”<sup id="fnref:a" role="doc-noteref"><a href="#fn:a" class="footnote" rel="footnote">1</a></sup>—utterly unintelligible. The challenge is to rediscover the original order.</p>

<p>What makes this challenging is that a sentence of \(N\) words has \(N!\) possible arrangements. It’s NP-hard to evaluate each arrangement individually by brute force, to identify the highest quality.<sup id="fnref:complexity" role="doc-noteref"><a href="#fn:complexity" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="approach">Approach</h2>

<p>The authors believe that explicit syntactic information isn’t the key to reordering. Instead, they claim that the best ordering should be the most probable one according to a language model. They propose two language models: an n-gram model and an <abbr title="Long short-term memory network">LSTM</abbr>.</p>

<p>I assume you’re already familiar with how to produce an n-gram or <abbr title="Long short-term memory network">LSTM</abbr> language model; otherwise, take a look at <a href="http://www.cs.jhu.edu/~jason/465/">JHU’s NLP course</a>. The more interesting part of their approach is the decoding with <strong>beam search</strong>, a compromise between greedy decoding and exhaustive search that is standard in machine translation. The TLDR is that you produce hypotheses about which phrase is next, then keep only the K best before continuing.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">beam_search</span><span class="p">(</span>
        <span class="n">phrases</span><span class="p">:</span> <span class="n">Set</span><span class="p">[</span><span class="n">Phrase</span><span class="p">],</span>  <span class="c1"># Noun phrases or phrases containing one token
</span>        <span class="n">K</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>  <span class="c1"># Beam size
</span>        <span class="n">g</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">Set</span><span class="p">[</span><span class="n">Phrase</span><span class="p">]],</span> <span class="n">Score</span><span class="p">],</span>  <span class="c1"># converts remaining phrases into a score
</span>        <span class="n">model</span>  <span class="c1"># API is given in the GitHub Gist.
</span>    <span class="p">):</span>
    <span class="n">M</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">phrases</span><span class="p">)</span>  <span class="c1"># Number of phrases may not be number of tokens.
</span>    <span class="c1"># Make empty beams.
</span>    <span class="n">beams</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Hypothesis</span><span class="p">]</span> <span class="o">=</span> <span class="p">[[]</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">M</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
    <span class="n">beams</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">Hypothesis</span><span class="p">([],</span> <span class="n">phrases</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">initial_state</span><span class="p">())]</span>

    <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">M</span><span class="p">):</span>  <span class="c1"># keep consuming phrases:
</span>        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">beams</span><span class="p">[</span><span class="n">m</span><span class="p">])):</span>  <span class="c1"># for each hypothesis at this point:
</span>            <span class="n">hypothesis</span> <span class="o">=</span> <span class="n">beams</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">k</span><span class="p">]</span>
            <span class="p">(</span><span class="n">story</span><span class="p">,</span> <span class="n">candidates</span><span class="p">,</span> <span class="n">score</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="o">=</span> <span class="n">astuple</span><span class="p">(</span><span class="n">hypothesis</span><span class="p">)</span>

            <span class="k">for</span> <span class="n">phrase</span> <span class="ow">in</span> <span class="n">candidates</span><span class="p">:</span>
                <span class="c1"># Evaluate the best candidates at this point. Overgenerate, then cull
</span>                
                <span class="n">new_score</span><span class="p">,</span> <span class="n">new_state</span> <span class="o">=</span> <span class="n">score</span><span class="p">,</span> <span class="n">state</span>
                <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">phrase</span><span class="p">:</span>  <span class="c1"># Score this phrase.
</span>                    <span class="n">new_score</span> <span class="o">+=</span> <span class="n">model</span><span class="p">.</span><span class="n">score</span><span class="p">(</span><span class="n">word</span><span class="p">,</span> <span class="n">new_state</span><span class="p">)</span>
                    <span class="n">new_state</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">transition</span><span class="p">(</span><span class="n">word</span><span class="p">,</span> <span class="n">new_state</span><span class="p">)</span>
                <span class="n">j</span> <span class="o">=</span> <span class="n">m</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">phrase</span><span class="p">)</span>

                <span class="n">new_hypothesis</span> <span class="o">=</span> <span class="n">Hypothesis</span><span class="p">(</span><span class="n">story</span> <span class="o">+</span> <span class="p">[</span><span class="n">phrase</span><span class="p">],</span> <span class="n">candidates</span> <span class="o">-</span> <span class="p">{</span><span class="n">phrase</span><span class="p">},</span> <span class="n">new_score</span><span class="p">,</span> <span class="n">new_state</span><span class="p">)</span>
                <span class="n">beams</span><span class="p">[</span><span class="n">j</span><span class="p">].</span><span class="n">append</span><span class="p">(</span><span class="n">new_hypothesis</span><span class="p">)</span>

                <span class="c1"># Extract top K from model.
</span>                <span class="n">ordered</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">beams</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">hyp</span><span class="p">:</span> <span class="n">model</span><span class="p">.</span><span class="n">score_sequence</span><span class="p">(</span><span class="n">hyp</span><span class="p">.</span><span class="n">story</span><span class="p">)</span> <span class="o">+</span> <span class="n">g</span><span class="p">(</span><span class="n">hyp</span><span class="p">.</span><span class="n">candidates</span><span class="p">))</span>
                <span class="n">beams</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">ordered</span><span class="p">[:</span><span class="n">K</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">beams</span>  <span class="c1"># The consumer can take the best from beams[m].
</span>
</code></pre></div></div>

<p>A runnable example (with a dummy model) is available <a href="https://gist.github.com/aryamccarthy/a678289681c4c3f167b0f671797e18be">here</a>.</p>

<h2 id="data">Data</h2>

<p>They use the Penn Treebank as data, and they optionally increase their vocabulary size by also using the <a href="https://catalog.ldc.upenn.edu/LDC2012T21">Annotated Gigaword</a><sup id="fnref:giga" role="doc-noteref"><a href="#fn:giga" class="footnote" rel="footnote">3</a></sup> corpus, a JHU project. They’re actually incredibly lucid about their preprocessing; I’m certain that it could be reproduced rather easily with <code class="language-plaintext highlighter-rouge">grep -w</code>.</p>

<p>The authors try two task settings:</p>

<dl>
  <dt>Words</dt>
  <dd>Words all provided independently of each other.</dd>
  <dt>Words+BNPs</dt>
  <dd>Base noun phrases (those without other noun phrases inside) are also provided.</dd>
</dl>

<h2 id="results">Results</h2>

<p>The models are evaluated with <abbr title="Bilingual evaluation understudy (Papineni et al., 2002)">BLEU</abbr> score. In machine translation, <abbr title="Bilingual evaluation understudy (Papineni et al., 2002)">BLEU</abbr> is grudgingly accepted, but it’s a natural measure for this task—how many n-grams overlap with the reference?</p>

<p>When base noun phrases are included, the n-gram model beats a syntactic model by 5 <abbr title="Bilingual evaluation understudy (Papineni et al., 2002)">BLEU</abbr>, and the <abbr title="Long short-term memory network">LSTM</abbr> beats it by another 5. Omitting knowledge of base noun phrases makes for slightly smaller gains. Adding in Gigaword boosts scores by about 2 points. Larger beams (they tried widths from 11 to 512) also seem to consistently improve performance.</p>

<p>One last objection they refute is that syntax may be more helpful for highly distorted or longer sentences. They find instead that the <abbr title="Long short-term memory network">LSTM</abbr> outperforms the syntactic models over all lengths and distortion amounts. Further, parsing the sentences with the Yara shows that they’re syntactically better than the syntax-guided models.</p>

<p>Followup work by <a href="https://aclweb.org/anthology/W18-6553/">Song, Zhang, and Gildea (2018)</a> show that incorporating the syntactic information into a neural model (the best of both worlds) improves performance further.</p>

<h2 id="tldr">TL;DR</h2>

<p>Syntax models aren’t necessary to learn word order from shuffled words. A neural language model is good enough. As always, more data helps. But it can be cheaply acquired because syntactic annotations are not necessary.</p>

<p><strong>Fun bit:</strong> the unigram heuristic \(g\) they use for down-weighting upcoming characters.</p>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:a" role="doc-endnote">
      <p>Courtesy of this <code class="language-plaintext highlighter-rouge">bash</code> pipeline: <code class="language-plaintext highlighter-rouge">echo "Papa ate the caviar with a spoon ." | tr ' ' '\n' | sort -R | paste -s -d ' ' -</code>. I’m always a fan of people learning more <code class="language-plaintext highlighter-rouge">bash</code> tricks. <a href="#fnref:a" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:complexity" role="doc-endnote">
      <p>See <a href="https://aclweb.org/anthology/J99-4005">Knight (1999)</a>. <a href="#fnref:complexity" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:giga" role="doc-endnote">
      <p>The annotations aren’t necessary for Schmaltz et al.’s method; it’s only for the syntactic models that need it. <a href="#fnref:giga" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[This paper was part of the wave that showed how recurrent neural nets could be applied to heaps of tasks. They find that a neural language model without explicit knowledge of syntax is effective at rediscovering the word order of a shuffled sentence.]]></summary></entry><entry><title type="html">Optimizing Segmentation Granularity for Neural Machine Translation</title><link href="https://aryamccarthy.github.io/salesky2018optimizing/" rel="alternate" type="text/html" title="Optimizing Segmentation Granularity for Neural Machine Translation" /><published>2018-11-06T00:00:00+00:00</published><updated>2018-11-06T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/salesky2018optimizing</id><content type="html" xml:base="https://aryamccarthy.github.io/salesky2018optimizing/"><![CDATA[<p>Byte pair encoding (BPE) is now a standard way to preprocess data in neural machine translation. It combats <strong>data sparsity</strong> by creating a vocabulary of subwords to use instead of words. The subword units may be more common than the words, especially in morphologically rich languages. The question remains <em>how many</em> subwords to use. People tend not to sweep this hyperparameter. This paper does it automatically (for the target-side vocabulary), without adding training time. It doesn’t make a huge improvement in BLEU score, but it’s a fascinating method.</p>

<!--more-->

<hr />

<p>There’s a tradeoff in selecting the optimal hyperparameter. Too small a vocabulary and your model must correctly predict many subwords in a row to produce the intended word. Too large, and you make individual words infrequent.</p>

<p>The proposed method of <strong>incremental BPE</strong> has two parts: a schedule of merge operations and a way to initialize new embeddings for members of the growing vocabulary.</p>

<p>Their schedule for expanding the vocabulary depends on validation loss during training. If validation loss has plateaued, the vocabulary is expanded to the next size in the schedule. (The authors use 10k, 20k, …, 60k.) This supposedly achieves the same performance as grid search.</p>

<p>To initialize the new embeddings, the authors try three approaches:</p>

<ol>
  <li>Random: Initialize the new, merged vocabulary item with a random embedding.</li>
  <li>Average: Take the arithmetic mean of the two merging items’ embeddings as the merged item’s embedding.</li>
  <li>Autoencoder: Train a small network to predict the two items’ embeddings, given those embeddings. The middle hidden layer should be the size of only one embedding. After training the network, this value is used as the new, merged item’s embedding. This one works best.</li>
</ol>

<p><img src="https://aryamccarthy.github.io/images/salesky2018optimizing-autoencoder.png" alt="Autoencoder architecture used for initialization" /></p>

<p>The authors use standard datasets (WMT and IWSLT) for training from English into a morphologically rich language: Czech or German. They found that optimal performance on smaller datasets may come from fewer subword units, and that the same number of units wouldn’t be optimal across datasets.</p>

<p>Their incremental approach would typically underestimate the optimal vocabulary size from the grid search, but the performance beats the sweep result with the same vocabulary size.</p>

<p>Altogether, an interesting and useful paper with the message that fixing a hyperparameter is a bad idea. The fact that it can be effectively tuned inline during training is especially impressive.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Byte pair encoding (BPE) is now a standard way to preprocess data in neural machine translation. It combats data sparsity by creating a vocabulary of subwords to use instead of words. The subword units may be more common than the words, especially in morphologically rich languages. The question remains how many subwords to use. People tend not to sweep this hyperparameter. This paper does it automatically (for the target-side vocabulary), without adding training time. It doesn’t make a huge improvement in BLEU score, but it’s a fascinating method.]]></summary></entry><entry><title type="html">‘Lighter’ Can Still Be Dark: Modeling Comparative Color Descriptions</title><link href="https://aryamccarthy.github.io/winn2018lighter/" rel="alternate" type="text/html" title="‘Lighter’ Can Still Be Dark: Modeling Comparative Color Descriptions" /><published>2018-10-16T00:00:00+00:00</published><updated>2018-10-16T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/winn2018lighter</id><content type="html" xml:base="https://aryamccarthy.github.io/winn2018lighter/"><![CDATA[<p>Sometimes one word on a matter isn’t enough. To describe color, we resort to compositional names: “light blue”, “cherry red”. This paper looks at a group of these: comparative names. Those are names like “duller olive” or “slightly paler”.</p>

<!--more-->

<p>When naming a target color that is similar to a distractor, we use comparative adjectives (<a href="http://www.aclweb.org/anthology/Q17-1023">Monroe et al., 2017</a>). This relates to the notion of codability, or entropy: it takes more bits to distinguish between the two colors, because our broad-level categories don’t manage to distinguish them. The work of Winn and Muresan seeks to ground these comparisons. They want to match each descriptor up to a vector, transforming “blue” + “lighter (given that the color is blue)” = “lighter blue”.</p>

<p>The authors used the data of the <a href="https://blog.xkcd.com/2010/05/03/color-survey-results/">xkcd color survey</a>, which elicited 954 color names from 500 namings and 222,500 user sessions. Many of these were compositional (though not comparative), and each label had on average 600 datapoints. (Sure, but what’s the distribution? No doubt ‘red’ was way more common than ‘filemot’.) Winn and Muresan distilled the data down to 415 tuples like (ʙʟᴜᴇ, ‘lighter’, ʟɪɢʜᴛ ʙʟᴜᴇ), where ʙʟᴜᴇ actually is a <em>set</em> of RGB datapoint. There are 79 unique reference labels (like ʙʟᴜᴇ) and 81 unique comparatives—relatively slim pickings.</p>

<p>The authors make a poor assumption: that you can simply compare the averages of the sets to learn the positions. With that, all you’d need is to average each cluster and compute a vector from centroid to centroid. :-/</p>

<p>Hey, while we’re on silly things that this (somehow) ACL best paper did—RGB coordinates were used in the data collection, sure, but using them to find the vectors encoding the comparatives is relatively meaningless—the distances in RGB space don’t align with perceptual judgments of similarity.</p>

<p>Aaaand now for some reason, since this is an ACL paper, we have to work Word Embeddings into it. We evidently use these to condition our vector on the input word. This is what gives the model an ability to predict new vectors. (But this assumes you a priori know the general category labels and their coordinates.)</p>

<p><img src="https://aryamccarthy.github.io/images/winn2018lighter-architecture.png" alt="network architecture diagram" /></p>

<p><strong>The bottom line</strong></p>

<p>Nobody has done work on grounding comparatives before, the authors contend. But isn’t a comparative only meaningful <em>in the context of a reference color</em>, so we open the door to massive overfitting. This paper feels like a fun blog post, and I’m sure the color and examples made it eye-catching. But there’s not a whole lot of meat to it.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Sometimes one word on a matter isn’t enough. To describe color, we resort to compositional names: “light blue”, “cherry red”. This paper looks at a group of these: comparative names. Those are names like “duller olive” or “slightly paler”.]]></summary></entry><entry><title type="html">An Exploration of Neural Sequence-to-Sequence Architectures for Automatic Post-Editing</title><link href="https://aryamccarthy.github.io/junczys2017exploration/" rel="alternate" type="text/html" title="An Exploration of Neural Sequence-to-Sequence Architectures for Automatic Post-Editing" /><published>2018-10-15T00:00:00+00:00</published><updated>2018-10-15T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/junczys2017exploration</id><content type="html" xml:base="https://aryamccarthy.github.io/junczys2017exploration/"><![CDATA[<p>Automatic post-editing (APE) exists because our translation models are fallible. (Hopefully, they’re also fallible in reliable ways.) Once your translation system has spit out a predicted translation of a sentence, you can feed both the prediction and the original, foreign sentence into your APE system to clean it up, making it feel more human. This paper presents a neural architecture for APE—it’s similar to the <a href="https://aryamccarthy.github.io/bahdanau2015neural/">traditional neural MT architecture</a>, but with dual attention—one over the source, and one over the translation output.</p>

<!--more-->
<hr />

\[\begin{eqnarray}
mt &amp;=&amp; \textrm{MT-SYSTEM}(src) \\
pe &amp;=&amp; \textrm{APE}(mt, src)
\end{eqnarray}\]

<p>Before the age of neural MT, post-editing generally was a phrase-based MT process. An automatically produced alignment would help create a new, “source-context aware”, source text. It would have the tokens of the MT output and the tokens of the original source paired together.</p>

<p>This paper, leaping into the neural age, builds on the standard model (plus a few additions made in the Nematus toolkit—the decoder is wonky, using GRUs out the wazoo). They introduce four model variants. To understand them, we should understand the difference between hard and soft attention. Soft attention means that multiple encoder states can make fractional contributions to picking the output token of the decoder. Hard attention makes you rely on only one state per output token. It’s like the relationship between k-means and a Gaussian mixture model.</p>

<ol>
  <li><strong>Hard, monotonic attention.</strong> This borrows from <a href="http://aclweb.org/anthology/P17-1183">Aharoni and Goldberg</a>’s system for morphological inflection—another string transduction task. The system can predict not only a word, but also a special symbol &lt;STEP&gt; which forces the attention mechanism to advance to the next encoder state. To precompute the &lt;STEP&gt; tokens interleaved into the input, the authors use the Longest Common Subsequence between the MT output and the correct translation.</li>
  <li><strong>Hard and soft attention.</strong> Hard attention meant swapping out the decoder for something without the standard attention mechanism. What if we brought it back? Append the hard attention’s encoder state to the standard (soft) attention’s state.</li>
  <li><strong>Soft dual-attention.</strong> This is the idea of <a href="http://www.aclweb.org/anthology/N16-1004">Zoph and Knight</a>, but expressed more clearly. Let’s compute standard attention over both the source (which was previously unused) and the MT output—each from separate encoders—then concatenate those.</li>
  <li><strong>Hard attention with soft dual-attention.</strong> Strap two of those hard-and-soft mechanisms together.</li>
</ol>

<p>The authors followed the conventions of the 2016 WMT shared task on automatic post-editing, including evaluation by <a href="https://www.cs.umd.edu/~snover/pub/amta06/ter_amta.pdf">Translation Edit Rate (TER)</a>, with the widespread BLEU as only a secondary metric.</p>

<p>They also performed model averaging—taking the best 8 checkpoints from the training process. This regularization, they found, improved performance.</p>

<hr />

<p>Enough about their experimental framework. Let’s dig into error analysis.</p>

<p>They found that their models chose to edit 75–80% of the sentences, no matter what. The majority were improved, while about a quarter of the edited sentences were deteriorated.</p>

<p>The authors present visualizations of their attention matrices.</p>

<blockquote>
  <p>For CGRU-HARD [hard and soft dual-attention], it is interesting to see how the monotonic attention now allows the soft attention mechanism to look around the input sentence more freely or to remain inactive instead of following the monotonic path.</p>
</blockquote>

<p><strong>TLDR:</strong> Use both sequences for APE. Dual attention over both the original source and the MT output that needs editing does better than just editing the output while ignoring the source.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Automatic post-editing (APE) exists because our translation models are fallible. (Hopefully, they’re also fallible in reliable ways.) Once your translation system has spit out a predicted translation of a sentence, you can feed both the prediction and the original, foreign sentence into your APE system to clean it up, making it feel more human. This paper presents a neural architecture for APE—it’s similar to the traditional neural MT architecture, but with dual attention—one over the source, and one over the translation output.]]></summary></entry><entry><title type="html">Neural Arithmetic Logic Units</title><link href="https://aryamccarthy.github.io/trask2018neural/" rel="alternate" type="text/html" title="Neural Arithmetic Logic Units" /><published>2018-08-08T00:00:00+00:00</published><updated>2018-08-08T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/trask2018neural</id><content type="html" xml:base="https://aryamccarthy.github.io/trask2018neural/"><![CDATA[<p><em>It’s time to restart in preparation for the new semester!</em></p>

<p>Neural networks have trouble with things as simple to us as learning the identity function \(f(x) = x\). Within the numerical range they’re trained on, they do fine, but they can’t extrapolate.</p>

<p><img src="https://aryamccarthy.github.io/images/trask2018neural-identity.png" alt="Error is higher outside the training range." /></p>

<!--more-->

<p>The paper proposes two new models that generalize better. The first, for better addition and subtraction, is the <strong>neural accumulator (NAC)</strong>. It’s like a normal linear layer, but there’s no bias, and its weight matrix \(\mathbf{W}\) is only 0’s, 1’s, and −1’s. Well, sort of. Hard constraints are not differentiable. Instead, they express \( \mathbf{W} = \tanh(\mathbf{\hat{W}}) \odot \sigma(\mathbf{\hat{M}}) \). The tanh values range from -1 to 1, the sigmoid ranges from 0 to 1, and the values of both are <em>strongly encouraged</em> toward the extremes, so each element-wise product is pushed to the values we want.</p>

<p>The second is a <strong>neural arithmetic logic unit (NALU)</strong>, christened after the structures you remember from your computer architecture classes. It combines two of these NACs, one of which operates in log-space, so it can perform multiplication and division. (\(\exp(\log(a) + \log(b)) \equiv a \times b\).) A gate controls whether the NALU takes the add/subtract route or the multiply/divide route.</p>

<p>Their results show that normal neural architectures do poorly at generalizing, even if they can handle the simple addition and subtraction. The NAC does just as well, but the NALU is the only variant that learns to extrapolate beyond the range of training values. When the values are fed in sequentially (rather than as one vector), the LSTM and ReLU-activated RNN both learn interpolation, but fail at extrapolation. NALU learns most extrapolation, but it fails <em>miserably</em> on division. (They justify this by the fact that small denominators can tease out the error in generalization ability.)</p>

<p>They also test performance on two other tasks: MNIST digit counting and digit adding. Both involve recognizing images of digits, then using them. (Digit counting involves a swarm of numbers in each picture.) The NAC (designed for addition and subtraction) wins at this. It’s easily incorporated into existing image recognition architectures by replacing the final layer.</p>

<p>Another task is interpreting text representations of numbers, turning them into text. Here, the NALU shines.</p>

<p><strong>The takeaway:</strong></p>

<ul>
  <li>We have a single ‘neuron’ that can better handle math.</li>
  <li>It’s easily integrable into existing image classification networks or text interpretation.</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[It’s time to restart in preparation for the new semester! Neural networks have trouble with things as simple to us as learning the identity function \(f(x) = x\). Within the numerical range they’re trained on, they do fine, but they can’t extrapolate.]]></summary></entry><entry><title type="html">Improving Low Resource Machine Translation using Morphological Glosses</title><link href="https://aryamccarthy.github.io/shearing2018improving/" rel="alternate" type="text/html" title="Improving Low Resource Machine Translation using Morphological Glosses" /><published>2018-06-15T00:00:00+00:00</published><updated>2018-06-15T00:00:00+00:00</updated><id>https://aryamccarthy.github.io/shearing2018improving</id><content type="html" xml:base="https://aryamccarthy.github.io/shearing2018improving/"><![CDATA[<p>Translation models demand oodles of training text. In low-resource languages, we need tricks to circumvent the data famine. Languages with many inflected forms for each base word make the famine even scarcer. This paper presents a trick for feeding the hungry by multiplying our few loaves and fish: glossing words and morphological annotations. (Also—my advisor is on this paper :D .)</p>

<!--more-->

<p>To help our models out, we want to make the source text more similar to the target.</p>

<p>Shearing et al.’s innovation is the inclusion of <strong>morphological glosses</strong>, which makes dictionaries more useful. Dictionaries often list only a principal form for a set of words: “run” but not “running” or “ran”. The authors’ glossing process creates in-place translations of “running” and “ran” from the one for “run” and knowledge about verb tense.</p>

<p>The morphological glosses work into a four-stage pipeline that creates an out-of-order English (English-prime; \(E’\)) from the foreign source text. For each foreign word, do the following:</p>

<ol>
  <li>Analyze the word to get a lemma and morphological tag: <em>comprábamos</em> → <em>comprar</em>, <code class="language-plaintext highlighter-rouge">V;1;PL;PST;IPFV</code></li>
  <li>Look up the lemma in a lemma-to-lemma dictionary: <em>comprar</em> → <em>buy</em></li>
  <li>Convert the morphological features into a morphological gloss: <code class="language-plaintext highlighter-rouge">V;1;PL;PST;IPFV</code> → ‘(we) were <code class="language-plaintext highlighter-rouge">VBG</code>.’</li>
  <li>Replace the placeholder (VBG) with the corresponding form of the English lemma: ‘(we) were <code class="language-plaintext highlighter-rouge">VBG</code>’ + <code class="language-plaintext highlighter-rouge">buy</code> → ‘(we) were buying’</li>
</ol>

<p>At the end, you get <code class="language-plaintext highlighter-rouge">comprábamos</code> → ‘(we) were buying’, which the authors stick into a phrase-based translation model, turning \(E’\) into \(E\).</p>

<p><strong>Little details:</strong></p>

<ul>
  <li>Morph analysis using Kann and Schütze (2016).</li>
  <li>Translate lemmas with PanLex or Wiktionary.</li>
  <li>Manually create glosses.</li>
  <li>Inflect English with Spedt and Daelemans (2012).</li>
  <li>The LORELEI data they use gives multiple definitions for some words. Split these into separate lines, expanding your Bitext.</li>
  <li>Append a gloss-to-gloss identity mapping to the bitext, biasing the aligner toward lining these two up.</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[Translation models demand oodles of training text. In low-resource languages, we need tricks to circumvent the data famine. Languages with many inflected forms for each base word make the famine even scarcer. This paper presents a trick for feeding the hungry by multiplying our few loaves and fish: glossing words and morphological annotations. (Also—my advisor is on this paper :D .)]]></summary></entry></feed>