{
  "version": "https://jsonfeed.org/version/1",
  "title": "gruszka.dev",
  "home_page_url": "https://gruszka.dev/en",
  "feed_url": "https://gruszka.dev/en/tag-ai.json",
  "description": "Things I would like to share",
  "items": [
    {
      "id": "https://gruszka.dev/en/from-neurons-to-memory.html",
      "url": "https://gruszka.dev/en/from-neurons-to-memory.html",
      "title": "From simple neurons to memory - the evolution of language models",
      "content_html": "<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Want to run this code yourself?</strong> All the examples from this post (perceptron, RNN, LSTM) are in a ready-made Jupyter notebook: <a href=\"./from-neurons-to-memory.ipynb\">from-neurons-to-memory.ipynb</a></p>\n</div>\n<p>In the <a href=\"how-computer-reads-text.html\">previous post</a> we walked the whole path from cutting text into tokens, through counting words (TF-IDF), Markov chains, all the way to Word2Vec and meaning vectors. And at the end one fundamental question came up...</p>\n<p><strong>We have word vectors. Great. But how do we build something out of them that understands a sentence? Or a whole paragraph? Or a book?</strong></p>\n<p>Because &quot;Dog bites man&quot; isn't simply &quot;dog&quot; + &quot;bites&quot; + &quot;man&quot;. It's a <strong>sequence</strong> - words follow each other in a specific order, and that order <strong>changes the meaning</strong>. &quot;Dog bites man&quot; and &quot;Man bites dog&quot; are the same words, but completely different stories :D</p>\n<p>And Word2Vec? Word2Vec looks at words <strong>individually</strong>. It has no concept of order. It doesn't know that &quot;not&quot; before &quot;like&quot; changes everything.</p>\n<p>So we need something that can process <strong>sequences</strong>. Something that reads text in order and builds understanding step by step.</p>\n<p>And here begins a fascinating story - because the solution to this problem didn't appear overnight. It was an evolution that lasted several decades. From a single, simple neuron, to complicated memory cells. And each generation solved the previous generation's problem, but created a new one.</p>\n<p>This is the <strong>fourth post in the &quot;Understanding LLM&quot; series</strong>. Today we go deeper into the architecture of neural networks - but relax, still without formulas you can't understand ;-) Instead, there will be plenty of metaphors, diagrams, and real-life examples.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"980\" height=\"326.75\" viewBox=\"0 0 980 326.75\"><rect x=\"0\" y=\"0\" width=\"980\" height=\"326.75\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"0\" y=\"0\" width=\"980.00\" height=\"326.75\" fill=\"#FFFFFF\"/><text x=\"490.00\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"490.00\" dy=\"0.00\">The evolution of neural</tspan><tspan x=\"490.00\" dy=\"21.00\">architectures</tspan></text><line x1=\"30.00\" y1=\"130.00\" x2=\"950.00\" y2=\"130.00\" stroke=\"#94A3B8\" stroke-width=\"3\"/><circle cx=\"90.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"90.00\" y1=\"138.00\" x2=\"90.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"30.00\" y=\"160.00\" width=\"120.00\" height=\"126.75\" rx=\"5\" ry=\"5\" fill=\"#ECECFF\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"90.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"90.00\" dy=\"0.00\">1943</tspan></text><text x=\"90.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"90.00\" dy=\"0.00\">McCulloch &amp;</tspan><tspan x=\"90.00\" dy=\"18.90\">Pitts</tspan><tspan x=\"90.00\" dy=\"18.90\">mathematical</tspan><tspan x=\"90.00\" dy=\"18.90\">model of a</tspan><tspan x=\"90.00\" dy=\"18.90\">neuron</tspan></text><circle cx=\"250.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"250.00\" y1=\"138.00\" x2=\"250.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"190.00\" y=\"160.00\" width=\"120.00\" height=\"80.00\" rx=\"5\" ry=\"5\" fill=\"#FFE6CC\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"250.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"250.00\" dy=\"0.00\">1958</tspan></text><text x=\"250.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"250.00\" dy=\"0.00\">Rosenblatt</tspan><tspan x=\"250.00\" dy=\"18.90\">perceptron</tspan></text><circle cx=\"410.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"410.00\" y1=\"138.00\" x2=\"410.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"350.00\" y=\"160.00\" width=\"120.00\" height=\"88.95\" rx=\"5\" ry=\"5\" fill=\"#D5E8D4\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"410.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"410.00\" dy=\"0.00\">1986</tspan></text><text x=\"410.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"410.00\" dy=\"0.00\">Rumelhart et al.</tspan><tspan x=\"410.00\" dy=\"18.90\">backpropagation</tspan><tspan x=\"410.00\" dy=\"18.90\">+ MLP</tspan></text><circle cx=\"570.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"570.00\" y1=\"138.00\" x2=\"570.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"510.00\" y=\"160.00\" width=\"120.00\" height=\"88.95\" rx=\"5\" ry=\"5\" fill=\"#F8CECC\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"570.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"570.00\" dy=\"0.00\">1986</tspan></text><text x=\"570.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"570.00\" dy=\"0.00\">RNN</tspan><tspan x=\"570.00\" dy=\"18.90\">recurrent</tspan><tspan x=\"570.00\" dy=\"18.90\">networks</tspan></text><circle cx=\"730.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"730.00\" y1=\"138.00\" x2=\"730.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"670.00\" y=\"160.00\" width=\"120.00\" height=\"88.95\" rx=\"5\" ry=\"5\" fill=\"#FFF2CC\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"730.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"730.00\" dy=\"0.00\">1997</tspan></text><text x=\"730.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"730.00\" dy=\"0.00\">Hochreiter &amp;</tspan><tspan x=\"730.00\" dy=\"18.90\">Schmidhuber</tspan><tspan x=\"730.00\" dy=\"18.90\">LSTM</tspan></text><circle cx=\"890.00\" cy=\"130.00\" r=\"8\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"2\"/><line x1=\"890.00\" y1=\"138.00\" x2=\"890.00\" y2=\"160.00\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/><rect x=\"830.00\" y=\"160.00\" width=\"120.00\" height=\"88.95\" rx=\"5\" ry=\"5\" fill=\"#E1D5E7\" stroke=\"#94A3B8\" stroke-width=\"1\"/><text x=\"890.00\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\" font-weight=\"bold\"><tspan x=\"890.00\" dy=\"0.00\">2017</tspan></text><text x=\"890.00\" y=\"200.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"12.599999\" fill=\"#0F172A\"><tspan x=\"890.00\" dy=\"0.00\">Vaswani et al.</tspan><tspan x=\"890.00\" dy=\"18.90\">Transformer</tspan><tspan x=\"890.00\" dy=\"18.90\">(cliffhanger!)</tspan></text></svg></div>\n<p>The narrative of today's post: <strong>&quot;From a single cell to memory - and why that still wasn't enough.&quot;</strong> Let's start from the basics.</p>\n<hr />\n<h2><a href=\"#biological-neuron-vs-artificial---where-does-the-idea-even-come-from\" aria-hidden=\"true\" class=\"anchor\" id=\"biological-neuron-vs-artificial---where-does-the-idea-even-come-from\"></a>Biological neuron vs artificial - where does the idea even come from?</h2>\n<p>Before we get into architectures, let's quickly settle one question you're probably asking yourselves: <strong>why is it even called a &quot;neural network&quot;? What does it have to do with the brain?</strong></p>\n<p>Answer: both a lot, and a little ;-) In the beginning there was inspiration from biology. Take a look:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"797.1526\" height=\"96\" viewBox=\"0 0 797.1526 96\"><rect x=\"0\" y=\"0\" width=\"797.1526\" height=\"96\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 258.340,44.000 L 308.340,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(308.34 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 506.768,44.000 L 556.768,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(556.77 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"556.77\" y=\"8.00\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"668.96\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"668.96\" dy=\"0.00\">⚡ Axon</tspan><tspan x=\"668.96\" dy=\"21.00\">&lt;i&gt;passes it on&lt;/i&gt;</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"133.17\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"133.17\" dy=\"0.00\">🌿 Dendrites</tspan><tspan x=\"133.17\" dy=\"21.00\">&lt;i&gt;receive signals&lt;/i&gt;</tspan></text><rect x=\"308.34\" y=\"8.00\" width=\"198.43\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"407.55\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"407.55\" dy=\"0.00\">🧫 Soma</tspan><tspan x=\"407.55\" dy=\"21.00\">&lt;i&gt;processes&lt;/i&gt;</tspan></text></svg></div>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"857.7152\" height=\"117\" viewBox=\"0 0 857.7152 117\"><rect x=\"0\" y=\"0\" width=\"857.7152\" height=\"117\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 232.384,54.395 L 282.384,54.395\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(282.38 54.40) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 541.376,54.482 L 591.376,54.482\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(591.38 54.48) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"591.38\" y=\"18.46\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"716.55\" y=\"47.46\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"716.55\" dy=\"0.00\">📤 Output</tspan><tspan x=\"716.55\" dy=\"21.00\">&lt;i&gt;activation(sum)&lt;/i&gt;</tspan></text><rect x=\"8.00\" y=\"18.29\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"120.19\" y=\"47.29\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"120.19\" dy=\"0.00\">📥 Inputs x₁, x₂, x₃</tspan><tspan x=\"120.19\" dy=\"21.00\">&lt;i&gt;numbers&lt;/i&gt;</tspan></text><rect x=\"282.38\" y=\"8.00\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"411.88\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"411.88\" dy=\"0.00\">➕ Weighted sum</tspan><tspan x=\"411.88\" dy=\"21.00\">&lt;i&gt;w₁x₁ + w₂x₂ + w₃x₃ +</tspan><tspan x=\"411.88\" dy=\"21.00\">b&lt;/i&gt;</tspan></text></svg></div>\n<p><strong>First diagram</strong> - a real neuron. It has <strong>dendrites</strong> (receive signals from other neurons), a <strong>soma</strong> (the cell body - decides whether to &quot;fire&quot;), and an <strong>axon</strong> (passes the signal on).</p>\n<p><strong>Second diagram</strong> - an artificial neuron. It has <strong>inputs</strong> (numbers), a <strong>weighted sum</strong> (multiplies each input by its &quot;importance&quot; and adds it all up), and an <strong>output</strong> (the result passed through an activation function).</p>\n<p>The resemblance is... loose. A biological neuron is unimaginably more complicated. But the <strong>inspiration</strong> was important - Warren McCulloch and Walter Pitts showed in 1943 that such a simplified model of a neuron can perform basic logical operations (AND, OR, NOT). And that meant a network of such neurons could theoretically compute <strong>anything</strong>.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Does an LLM &quot;think&quot; like a brain?</strong> No. An artificial neuron is a mathematical abstraction, not a biological model. A biological neuron uses electrical impulses, neurotransmitters, has thousands of connections and a dynamics that can't be reduced to <code>w₁x₁ + w₂x₂</code>. But the inspiration was the starting point - and an important one.</p>\n</div>\n<p>OK, that's enough biology. Let's move on to what came out of it ;-)</p>\n<hr />\n<h2><a href=\"#perceptron---the-simplest-decision-in-the-world\" aria-hidden=\"true\" class=\"anchor\" id=\"perceptron---the-simplest-decision-in-the-world\"></a>Perceptron - the simplest decision in the world</h2>\n<p>In 1958 Frank Rosenblatt created the <strong>perceptron</strong> - the first algorithm that could <strong>learn</strong> from data. It was a milestone.</p>\n<p>The perceptron works trivially simply. Imagine you're deciding whether to go for a walk:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"915.8044\" height=\"594.1909\" viewBox=\"0 0 915.8044 594.1909\"><rect x=\"0\" y=\"0\" width=\"915.8044\" height=\"594.1909\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 144.866,59.000 L 144.866,102.786 Q 144.866,112.786 154.866,112.786 L 339.844,112.786 Q 349.844,112.786 349.844,122.786 L 349.844,166.572\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(349.84 166.57) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"100.82\" y=\"114.67\" width=\"88.10\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"144.87\" y=\"132.37\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"144.87\" dy=\"0.00\">&quot;w = +5&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 310.146,59.000 L 310.146,71.480 Q 310.146,81.480 320.146,81.480 L 387.847,81.480 Q 397.847,81.480 397.847,91.480 L 397.847,159.191 Q 397.847,166.572 390.467,166.572 L 381.446,166.572\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(381.45 166.57) rotate(180.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"371.96\" y=\"50.71\" width=\"88.10\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"416.01\" y=\"68.41\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"416.01\" dy=\"0.00\">&quot;w = -8&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 479.924,59.000 L 498.624,59.000 Q 508.624,59.000 508.624,69.000 L 508.624,128.072 Q 508.624,138.072 498.624,138.072 L 443.222,138.072 Q 433.222,138.072 433.222,148.072 L 433.222,166.572\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(433.22 166.57) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"418.52\" y=\"108.08\" width=\"88.10\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"462.57\" y=\"125.78\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"462.57\" dy=\"0.00\">&quot;w = +3&quot;</tspan></text></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 695.103,59.000 L 695.103,152.786 Q 695.103,162.786 685.103,162.786 L 457.676,162.786 Q 455.972,162.786 455.972,164.489 L 455.972,166.572\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(455.97 166.57) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 402.141,217.572 L 402.141,228.295 Q 402.141,235.072 402.744,241.822 L 402.877,243.322 Q 403.480,250.072 403.480,256.848 L 403.480,267.572\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(403.48 267.57) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 404.480,463.298 L 414.105,463.298 Q 421.980,463.298 418.298,470.259 L 391.333,521.230 Q 387.651,528.191 395.526,528.191 L 405.151,528.191\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(405.15 528.19) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-5\" data-label-kind=\"center\" x=\"407.54\" y=\"480.21\" width=\"58.44\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-5\" data-label-kind=\"center\"><text x=\"436.76\" y=\"497.91\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"436.76\" dy=\"0.00\">&quot;Yes&quot;</tspan></text></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 402.480,463.298 L 392.855,463.298 Q 384.980,463.298 383.510,471.035 L 374.121,520.454 Q 372.651,528.191 364.776,528.191 L 355.151,528.191\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(355.15 528.19) rotate(180.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-6\" data-label-kind=\"center\" x=\"328.86\" y=\"478.35\" width=\"48.55\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-6\" data-label-kind=\"center\"><text x=\"353.13\" y=\"496.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"353.13\" dy=\"0.00\">&quot;No&quot;</tspan></text></g><rect x=\"640.81\" y=\"8.00\" width=\"258.99\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"770.31\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"770.31\" dy=\"0.00\">⚙️ Threshold (bias) = 0</tspan></text><rect x=\"195.87\" y=\"8.00\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"273.45\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"273.45\" dy=\"0.00\">🌧️ Raining?</tspan></text><polygon points=\"403.48,267.57 501.84,365.93 403.48,464.30 305.12,365.93\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"403.48\" y=\"358.93\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"403.48\" dy=\"0.00\">Sum &gt;= threshold?</tspan><tspan x=\"403.48\" dy=\"21.00\">(threshold = 0)</tspan></text><rect x=\"174.03\" y=\"527.19\" width=\"181.13\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#cc6666\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"264.59\" y=\"556.19\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"264.59\" dy=\"0.00\">❌ Staying home</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"76.93\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"76.93\" dy=\"0.00\">☀️ Sunny?</tspan></text><rect x=\"347.31\" y=\"166.57\" width=\"109.66\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"402.14\" y=\"195.57\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"402.14\" dy=\"0.00\">➕ SUM</tspan></text><rect x=\"401.04\" y=\"8.00\" width=\"189.78\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"495.92\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"495.92\" dy=\"0.00\">🌡️ Temp &gt; 20°C?</tspan></text><rect x=\"405.15\" y=\"527.19\" width=\"258.99\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#66cc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"534.65\" y=\"556.19\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"534.65\" dy=\"0.00\">✅ I&apos;m going for a walk!</tspan></text></svg></div>\n<p>The mechanics are simple:</p>\n<ol>\n<li>Each input has its own <strong>weight</strong> (importance) - sun has weight +5, rain -8, temperature +3</li>\n<li>The perceptron <strong>multiplies</strong> each input by its weight and <strong>adds it all up</strong> (that's the &quot;weighted sum&quot;)</li>\n<li>If the sum is greater than or equal to the <strong>threshold</strong> (in our case threshold = 0) - it fires &quot;yes&quot;. Otherwise - &quot;no&quot;.</li>\n</ol>\n<p>Example:</p>\n<table>\n<thead>\n<tr>\n<th>Situation</th>\n<th>Sun (+5)</th>\n<th>Rain (-8)</th>\n<th>Temp &gt;20° (+3)</th>\n<th>Sum</th>\n<th>Decision</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Sunny, warm, no rain</td>\n<td>1</td>\n<td>0</td>\n<td>1</td>\n<td>5 + 0 + 3 = <strong>8</strong></td>\n<td>✅ Going out</td>\n</tr>\n<tr>\n<td>Raining, cold</td>\n<td>0</td>\n<td>1</td>\n<td>0</td>\n<td>0 - 8 + 0 = <strong>-8</strong></td>\n<td>❌ Staying home</td>\n</tr>\n<tr>\n<td>Cloudy and raining, but warm</td>\n<td>0</td>\n<td>1</td>\n<td>1</td>\n<td>0 - 8 + 3 = <strong>-5</strong></td>\n<td>❌ Staying home</td>\n</tr>\n</tbody>\n</table>\n<p>And - most importantly - the perceptron can <strong>learn</strong> these weights. You show it 100 examples of &quot;went out / didn't go out&quot; and it gradually adjusts the weights so that its decisions match yours.</p>\n<p>Brilliant in its simplicity, right?</p>\n<h3><a href=\"#but-the-perceptron-has-one-big-problem\" aria-hidden=\"true\" class=\"anchor\" id=\"but-the-perceptron-has-one-big-problem\"></a>But the perceptron has one big problem...</h3>\n<p>A perceptron can draw <strong>a single straight line</strong> dividing data into two groups. Which is great if the data can be split that way:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">⚫ ⚫ ⚫    │    ⚪ ⚪ ⚪\n⚫ ⚫ ⚫    │    ⚪ ⚪ ⚪\n           ↑\n      one line separates them ✅\n</code></pre>\n<p>But what if the data looks like this?</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">⚪  ⚫\n\n⚫  ⚪\n</code></pre>\n<p>That's the famous <strong>XOR problem</strong> (exclusive OR). The output is &quot;true&quot; only when exactly <strong>one</strong> input is true - not both and not neither. And you can't draw a single straight line that would separate them.</p>\n<p>This problem <strong>halted the development of neural networks for almost 20 years</strong>. Seriously. Researchers said: &quot;well OK, the perceptron is cool, but if it can't handle something as simple as XOR, what's the point?&quot; This period is called the <strong>&quot;AI Winter&quot;</strong>.</p>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Why was XOR so important?</strong> Because it showed that a single perceptron is limited to <strong>linearly separable</strong> problems. And the real world is rarely linear. Language definitely isn't.</p>\n</div>\n<p>And then someone said: <strong>what if we combine several perceptrons together?</strong></p>\n<hr />\n<h2><a href=\"#mlp---a-team-that-can-do-more-than-an-individual\" aria-hidden=\"true\" class=\"anchor\" id=\"mlp---a-team-that-can-do-more-than-an-individual\"></a>MLP - a team that can do more than an individual</h2>\n<p>A <strong>Multilayer Perceptron (MLP)</strong> is a network made up of many layers of neurons. Instead of one decision layer, we have:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1341.5353\" height=\"459.6258\" viewBox=\"0 0 1341.5353 459.6258\"><rect x=\"0\" y=\"0\" width=\"1341.5353\" height=\"459.6258\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"261.03\" y=\"8.00\" width=\"330.34\" height=\"435.63\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"426.20\" y=\"35.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"426.20\" dy=\"0.00\">Hidden layer 1</tspan></text><rect x=\"671.37\" y=\"58.42\" width=\"304.38\" height=\"337.92\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"823.57\" y=\"85.92\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"823.57\" dy=\"0.00\">Hidden layer 2</tspan></text><rect x=\"1055.76\" y=\"111.37\" width=\"269.78\" height=\"227.84\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"1190.65\" y=\"138.87\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1190.65\" dy=\"0.00\">Output layer</tspan></text><rect x=\"8.00\" y=\"66.36\" width=\"188.77\" height=\"300.43\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"102.38\" y=\"93.86\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"102.38\" dy=\"0.00\">Input layer</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 141.035,156.864 L 147.646,156.864 Q 153.055,156.864 156.250,161.229 L 285.819,338.261 Q 289.014,342.626 294.423,342.626 L 301.035,342.626\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 342.63) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 141.035,120.990 L 147.646,120.990 Q 153.055,120.990 158.392,120.108 L 283.677,99.383 Q 289.014,98.500 294.423,98.500 L 301.035,98.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 98.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 141.035,154.773 L 147.646,154.773 Q 153.055,154.773 158.459,155.014 L 283.610,160.613 Q 289.014,160.855 294.423,160.855 L 301.035,160.855\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 160.85) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 141.035,156.864 L 141.035,161.587 Q 141.035,165.450 144.898,165.450 L 149.191,165.450 Q 153.055,165.450 153.055,161.587 L 153.055,160.728 Q 153.055,156.864 156.274,159.001 L 284.507,244.103 Q 289.014,247.094 294.423,247.094 L 301.035,247.094\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 247.09) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 141.035,246.330 L 147.646,246.330 Q 153.055,246.330 157.469,249.457 L 285.861,340.393 Q 289.014,342.626 289.014,346.490 L 289.014,347.348 Q 289.014,351.212 292.878,351.212 L 297.171,351.212 Q 301.035,351.212 301.035,347.348 L 301.035,342.626\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 342.63) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 141.035,197.752 L 147.646,197.752 Q 153.055,197.752 157.418,194.553 L 284.651,101.277 Q 289.014,98.078 294.423,98.078 L 301.035,98.078\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 98.08) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 141.035,212.011 L 147.646,212.011 Q 153.055,212.011 158.427,211.373 L 283.642,196.510 Q 289.014,195.872 294.423,195.872 L 301.035,195.872\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 195.87) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 141.035,245.581 L 147.646,245.581 Q 153.055,245.581 158.410,246.344 L 283.659,264.198 Q 289.014,264.961 294.423,264.961 L 301.035,264.961\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 264.96) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-8\" class=\"edgePath\" data-edge-id=\"edge-8\" d=\"M 141.035,335.213 L 147.646,335.213 Q 153.055,335.213 158.424,335.876 L 283.645,351.324 Q 289.014,351.987 294.423,351.987 L 301.035,351.987\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 351.99) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-9\" class=\"edgePath\" data-edge-id=\"edge-9\" d=\"M 141.035,286.796 L 147.646,286.796 Q 153.055,286.796 156.222,282.410 L 286.752,101.633 Q 289.014,98.500 289.014,102.364 L 289.014,103.222 Q 289.014,107.086 292.878,107.086 L 297.171,107.086 Q 301.035,107.086 301.035,103.222 L 301.035,98.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 98.50) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-10\" class=\"edgePath\" data-edge-id=\"edge-10\" d=\"M 141.035,286.796 L 141.035,291.518 Q 141.035,295.382 144.898,295.382 L 149.191,295.382 Q 153.055,295.382 153.055,291.518 L 153.055,290.660 Q 153.055,286.796 156.271,284.654 L 284.512,199.208 Q 289.014,196.209 294.423,196.209 L 301.035,196.209\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 196.21) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-11\" class=\"edgePath\" data-edge-id=\"edge-11\" d=\"M 141.035,311.296 L 147.646,311.296 Q 153.055,311.296 158.412,310.545 L 283.657,292.989 Q 289.014,292.238 294.423,292.238 L 301.035,292.238\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(301.03 292.24) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-12\" class=\"edgePath\" data-edge-id=\"edge-12\" d=\"M 551.374,378.728 L 557.985,378.728 Q 563.395,378.728 568.752,377.978 L 693.997,360.436 Q 699.354,359.686 704.763,359.686 L 711.374,359.686\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 359.69) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-13\" class=\"edgePath\" data-edge-id=\"edge-13\" d=\"M 551.374,342.626 L 557.985,342.626 Q 563.395,342.626 566.502,338.198 L 696.246,153.343 Q 699.354,148.916 704.763,148.916 L 711.374,148.916\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 148.92) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-14\" class=\"edgePath\" data-edge-id=\"edge-14\" d=\"M 551.374,342.626 L 551.374,347.348 Q 551.374,351.212 555.238,351.212 L 559.531,351.212 Q 563.395,351.212 563.395,347.348 L 563.395,346.490 Q 563.395,342.626 566.551,340.397 L 694.935,249.744 Q 699.354,246.624 704.763,246.624 L 711.374,246.624\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 246.62) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-15\" class=\"edgePath\" data-edge-id=\"edge-15\" d=\"M 378.338,98.500 L 384.949,98.500 Q 390.359,98.500 394.921,101.406 L 694.791,292.427 Q 699.354,295.333 704.763,295.333 L 711.374,295.333\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 295.33) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-16\" class=\"edgePath\" data-edge-id=\"edge-16\" d=\"M 378.338,94.749 L 384.949,94.749 Q 390.359,94.749 395.757,95.094 L 693.955,114.134 Q 699.354,114.479 704.763,114.479 L 711.374,114.479\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 114.48) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-17\" class=\"edgePath\" data-edge-id=\"edge-17\" d=\"M 378.338,98.500 L 378.338,103.222 Q 378.338,107.086 382.202,107.086 L 386.495,107.086 Q 390.359,107.086 390.359,103.222 L 390.359,102.364 Q 390.359,98.500 394.003,99.782 L 694.251,205.412 Q 699.354,207.207 704.763,207.207 L 711.374,207.207\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 207.21) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-18\" class=\"edgePath\" data-edge-id=\"edge-18\" d=\"M 378.338,196.209 L 384.949,196.209 Q 390.359,196.209 395.509,197.861 L 695.674,294.153 Q 699.354,295.333 699.354,299.197 L 699.354,300.055 Q 699.354,303.919 703.217,303.919 L 707.510,303.919 Q 711.374,303.919 711.374,300.055 L 711.374,295.333\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 295.33) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-19\" class=\"edgePath\" data-edge-id=\"edge-19\" d=\"M 378.338,166.086 L 384.949,166.086 Q 390.359,166.086 395.755,165.715 L 693.957,145.241 Q 699.354,144.870 704.763,144.870 L 711.374,144.870\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 144.87) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-20\" class=\"edgePath\" data-edge-id=\"edge-20\" d=\"M 378.338,192.457 L 384.949,192.457 Q 390.359,192.457 395.752,192.877 L 693.961,216.082 Q 699.354,216.501 704.763,216.501 L 711.374,216.501\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 216.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-21\" class=\"edgePath\" data-edge-id=\"edge-21\" d=\"M 378.338,290.283 L 384.949,290.283 Q 390.359,290.283 395.749,290.735 L 693.963,315.757 Q 699.354,316.209 704.763,316.209 L 711.374,316.209\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 316.21) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-22\" class=\"edgePath\" data-edge-id=\"edge-22\" d=\"M 378.338,255.759 L 384.949,255.759 Q 390.359,255.759 395.471,253.991 L 695.702,150.178 Q 699.354,148.916 699.354,152.780 L 699.354,153.638 Q 699.354,157.502 703.217,157.502 L 707.510,157.502 Q 711.374,157.502 711.374,153.638 L 711.374,148.916\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 148.92) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-23\" class=\"edgePath\" data-edge-id=\"edge-23\" d=\"M 378.338,270.192 L 384.949,270.192 Q 390.359,270.192 395.746,269.711 L 693.966,243.061 Q 699.354,242.579 704.763,242.579 L 711.374,242.579\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(711.37 242.58) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-24\" class=\"edgePath\" data-edge-id=\"edge-24\" d=\"M 935.758,312.875 L 942.370,312.875 Q 947.779,312.875 953.177,312.522 L 1078.340,304.331 Q 1083.738,303.977 1089.147,303.977 L 1095.758,303.977\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 303.98) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-25\" class=\"edgePath\" data-edge-id=\"edge-25\" d=\"M 935.758,295.333 L 942.370,295.333 Q 947.779,295.333 952.236,292.269 L 1079.280,204.932 Q 1083.738,201.867 1089.147,201.867 L 1095.758,201.867\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 201.87) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-26\" class=\"edgePath\" data-edge-id=\"edge-26\" d=\"M 788.678,148.916 L 795.289,148.916 Q 800.698,148.916 805.841,150.592 L 1078.595,239.492 Q 1083.738,241.168 1089.147,241.168 L 1095.758,241.168\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 241.17) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-27\" class=\"edgePath\" data-edge-id=\"edge-27\" d=\"M 788.678,145.740 L 795.289,145.740 Q 800.698,145.740 806.086,146.217 L 1078.349,170.321 Q 1083.738,170.798 1089.147,170.798 L 1095.758,170.798\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 170.80) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-28\" class=\"edgePath\" data-edge-id=\"edge-28\" d=\"M 788.678,242.606 L 795.289,242.606 Q 800.698,242.606 806.089,243.057 L 1078.347,265.841 Q 1083.738,266.292 1089.147,266.292 L 1095.758,266.292\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 266.29) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-29\" class=\"edgePath\" data-edge-id=\"edge-29\" d=\"M 788.678,217.624 L 953.657,217.624 Q 962.547,217.624 962.547,208.734 L 962.547,206.758 Q 962.547,197.868 971.437,197.868 L 1095.758,197.868\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1095.76 197.87) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"711.37\" y=\"294.33\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"823.57\" y=\"323.33\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"823.57\" dy=\"0.00\">g₁</tspan><tspan x=\"823.57\" dy=\"21.00\">&lt;i&gt;combinations&lt;/i&gt;</tspan></text><rect x=\"711.37\" y=\"98.92\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"750.03\" y=\"127.92\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"750.03\" dy=\"0.00\">g₂</tspan></text><rect x=\"711.37\" y=\"196.62\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"750.03\" y=\"225.62\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"750.03\" dy=\"0.00\">g₃</tspan></text><rect x=\"301.03\" y=\"341.63\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"426.20\" y=\"370.63\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"426.20\" dy=\"0.00\">h₁</tspan><tspan x=\"426.20\" dy=\"21.00\">&lt;i&gt;simple features&lt;/i&gt;</tspan></text><rect x=\"301.03\" y=\"48.50\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"339.69\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"339.69\" dy=\"0.00\">h₂</tspan></text><rect x=\"301.03\" y=\"146.21\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"339.69\" y=\"175.21\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"339.69\" dy=\"0.00\">h₃</tspan></text><rect x=\"301.03\" y=\"243.92\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"339.69\" y=\"272.92\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"339.69\" dy=\"0.00\">h₄</tspan></text><rect x=\"63.73\" y=\"106.86\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"102.38\" y=\"135.86\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"102.38\" dy=\"0.00\">x₁</tspan></text><rect x=\"63.73\" y=\"196.33\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"102.38\" y=\"225.33\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"102.38\" dy=\"0.00\">x₂</tspan></text><rect x=\"63.73\" y=\"285.80\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"102.38\" y=\"314.80\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"102.38\" dy=\"0.00\">x₃</tspan></text><rect x=\"1095.76\" y=\"237.21\" width=\"189.78\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1190.65\" y=\"266.21\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"1190.65\" dy=\"0.00\">y₁</tspan><tspan x=\"1190.65\" dy=\"21.00\">&lt;i&gt;decision&lt;/i&gt;</tspan></text><rect x=\"1095.76\" y=\"151.87\" width=\"77.30\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1134.41\" y=\"180.87\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"1134.41\" dy=\"0.00\">y₂</tspan></text></svg></div>\n<p>Every neuron in one layer is connected to <strong>every</strong> neuron in the next layer (that's why it's called &quot;fully connected&quot; or &quot;dense&quot;).</p>\n<p>The metaphor that fits best for me:</p>\n<p>Imagine a <strong>company</strong>. Analysts (layer 1) look at raw data and pick out simple patterns. Managers (layer 2) combine those patterns into something more meaningful. The director (the output layer) makes the final decision. None of these people understands the full picture alone - but together they form a <strong>cascade of abstraction</strong>.</p>\n<p>And that's exactly what solves the XOR problem! The first layer draws <strong>two lines</strong>. The second layer combines them into <strong>one region</strong>. Suddenly a non-linear problem becomes solvable.</p>\n<h3><a href=\"#but-careful---theres-a-catch\" aria-hidden=\"true\" class=\"anchor\" id=\"but-careful---theres-a-catch\"></a>But careful - there's a catch!</h3>\n<p>Adding hidden layers <strong>by itself</strong> does nothing. Why?</p>\n<p>Because if each layer just does <code>sum = weights × inputs + bias</code>, then two layers of that operation are still... <strong>one big linear operation</strong>. Let me show with numbers:</p>\n<p><strong>Layer 1:</strong> <code>y = 2·x + 1</code>\n<strong>Layer 2:</strong> <code>z = 3·y + 2</code></p>\n<p>Substitute the first into the second:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">z = 3·(2·x + 1) + 2\nz = 6·x + 3 + 2\nz = 6·x + 5    ← one operation, just with different numbers\n</code></pre>\n<p>The two layers collapsed into one. Instead of two transformations, you get one - just with different coefficients. It's like using one coffee filter twice as thick instead of two. Same effect.</p>\n<p>So we need <strong>something non-linear</strong> between the layers. And that's where...</p>\n<h3><a href=\"#the-activation-function---the-unsung-hero-of-deep-learning\" aria-hidden=\"true\" class=\"anchor\" id=\"the-activation-function---the-unsung-hero-of-deep-learning\"></a>The activation function - the unsung hero of deep learning</h3>\n<p>An activation function is a kind of &quot;non-standard processing plant&quot; that we pass the sum through. The most popular today is <strong>ReLU</strong> (Rectified Linear Unit):</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>def</a-k> <a-f>relu</a-f>(<a-v>x</a-v>):\n    <a-k>if</a-k> <a-v>x</a-v> <a-o>&gt;</a-o> <a-n>0</a-n>:\n        <a-k>return</a-k> <a-v>x</a-v>\n    <a-k>else</a-k>:\n        <a-k>return</a-k> <a-n>0</a-n></code></pre>\n<p>That's it. <strong>If the value is positive - keep it. If negative - zero it out.</strong></p>\n<p>Sounds trivial? It is trivial. But this one simple operation <strong>breaks linearity</strong>.</p>\n<p>Back to our numbers example. Without ReLU, two layers collapsed into one (<code>z = 6·x + 5</code>). But now let's insert ReLU between them:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Layer 1:  y = ReLU(2·x + 1)\nLayer 2:  z = ReLU(3·y + 2)\n</code></pre>\n<p>Let's check for three values of <code>x</code>:</p>\n<table>\n<thead>\n<tr>\n<th>x</th>\n<th>2·x + 1</th>\n<th>y (after ReLU)</th>\n<th>3·y + 2</th>\n<th>after ReLU</th>\n<th>Without ReLU (6·x + 5)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>-2</strong></td>\n<td>-3</td>\n<td><strong>0</strong> ⬅ zeroed out!</td>\n<td>2</td>\n<td>2</td>\n<td>-7</td>\n</tr>\n<tr>\n<td><strong>0</strong></td>\n<td>1</td>\n<td>1</td>\n<td>5</td>\n<td>5</td>\n<td>5</td>\n</tr>\n<tr>\n<td><strong>1</strong></td>\n<td>3</td>\n<td>3</td>\n<td>11</td>\n<td>11</td>\n<td>11</td>\n</tr>\n</tbody>\n</table>\n<p>Without ReLU the result changes linearly (-7, 5, 11 - constant increase). With ReLU, suddenly for <code>x = -2</code> we get <strong>2 instead of -7</strong>. This relationship is no longer a straight line. <strong>Zeroing out negative values is something that can't be expressed as <code>a·x + b</code></strong> - and that's exactly why layers stop collapsing into one.</p>\n<p>Analogy: imagine <strong>window blinds</strong>. Linearity is a transparent pane of glass - it lets everything through, slightly dimmed. ReLU is blinds that completely block light below a certain angle. You can't simulate &quot;complete blocking&quot; by &quot;dimming the glass more&quot;. It's a <strong>qualitatively different operation</strong>.</p>\n<p>Thanks to ReLU, each layer does something <strong>different</strong> from the previous one. And suddenly a network with many layers becomes powerful - it can model non-linear, complicated relationships in data.</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>ReLU in a nutshell:</strong> Without a (non-linear) activation function between layers, a network with 100 layers is just as expressive as a network with 1 layer. ReLU (and its cousins: sigmoid, tanh, GELU) is <strong>the ingredient that makes depth make sense.</strong></p>\n</div>\n<p>Other popular activation functions:</p>\n<table>\n<thead>\n<tr>\n<th>Function</th>\n<th>Formula (simplified)</th>\n<th>Range</th>\n<th>Where it's used</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>ReLU</strong></td>\n<td>max(0, x)</td>\n<td>[0, +∞)</td>\n<td>Hidden layers (standard)</td>\n</tr>\n<tr>\n<td><strong>Sigmoid</strong></td>\n<td>1 / (1 + e⁻ˣ)</td>\n<td>(0, 1)</td>\n<td>LSTM gates, binary output</td>\n</tr>\n<tr>\n<td><strong>Tanh</strong></td>\n<td>(eˣ - e⁻ˣ) / (eˣ + e⁻ˣ)</td>\n<td>(-1, 1)</td>\n<td>LSTM gates, hidden states</td>\n</tr>\n<tr>\n<td><strong>Softmax</strong></td>\n<td>eˣⁱ / Σeˣʲ</td>\n<td>(0, 1), sum = 1</td>\n<td>Output layer (classification)</td>\n</tr>\n</tbody>\n</table>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>An experiment for you:</strong> Open Python and run this:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>import</a-k> <a-v>numpy</a-v> <a-k>as</a-k> <a-v>np</a-v>\n\n<a-k>def</a-k> <a-f>relu</a-f>(<a-v>x</a-v>):\n    <a-k>return</a-k> <a-v>np</a-v>.<a-pr>maximum</a-pr>(<a-n>0</a-n>, <a-v>x</a-v>)\n\n<a-v>x</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-o>-</a-o><a-n>3</a-n>, <a-o>-</a-o><a-n>1</a-n>, <a-n>0</a-n>, <a-n>2</a-n>, <a-n>5</a-n>])\n<a-f>print</a-f>(<a-s>f&quot;Input: </a-s><a-p>{</a-p><a-v>x</a-v><a-p>}</a-p><a-s>&quot;</a-s>)\n<a-f>print</a-f>(<a-s>f&quot;After ReLU: </a-s><a-p>{</a-p><a-f>relu</a-f><a-eb>(</a-eb><a-v>x</a-v><a-eb>)</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)</code></pre>\n<p>You'll see how ReLU &quot;cuts off&quot; everything below zero. This simple operation lets the network &quot;choose&quot; which features are active and which to ignore.</p>\n</div>\n<h3><a href=\"#mini-quiz-linear-or-not\" aria-hidden=\"true\" class=\"anchor\" id=\"mini-quiz-linear-or-not\"></a>Mini-quiz: linear or not?<sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\" data-footnote-ref>1</a></sup></h3>\n<ol>\n<li>Plain linear regression (y = ax + b) - linear or non-linear?</li>\n<li>A perceptron with a step function (0 or 1) - linear or non-linear?</li>\n<li>An MLP without an activation function between layers - linear or non-linear?</li>\n</ol>\n<hr />\n<h2><a href=\"#problem-an-mlp-doesnt-understand-order\" aria-hidden=\"true\" class=\"anchor\" id=\"problem-an-mlp-doesnt-understand-order\"></a>Problem: an MLP doesn't understand order</h2>\n<p>OK, we have an MLP. It can model non-linear relationships. Great. But there's one <strong>fundamental</strong> problem that blocks us from using an MLP for language.</p>\n<p>An MLP sees <strong>all features at once</strong>. It has no concept of order.</p>\n<p>Take a classic English example. Two sentences with <strong>exactly the same words</strong>, but in a different order:</p>\n<table>\n<thead>\n<tr>\n<th>Sentence</th>\n<th>dog</th>\n<th>bites</th>\n<th>man</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>&quot;Dog bites man&quot;</td>\n<td>1</td>\n<td>1</td>\n<td>1</td>\n</tr>\n<tr>\n<td>&quot;Man bites dog&quot;</td>\n<td>1</td>\n<td>1</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Identical vector.</strong> And the meaning? The first is a boring news item. The second is a newspaper sensation :D</p>\n<p>For an MLP both sentences are <strong>exactly the same</strong> - because the MLP gets the same vector and has no concept of order.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>What about Polish?</strong> Polish is tricky here - due to inflection (7 cases!) we rarely have two sentences with <strong>exactly the same</strong> word forms. &quot;Pies gryzie człowieka&quot; vs &quot;Człowiek gryzie psa&quot; are different forms (pies→psa, człowieka→człowiek). But English, with minimal inflection, shows this problem perfectly. And that's exactly why bag-of-words examples often use English ;-)</p>\n</div>\n<p>This is the <strong>permutation</strong> problem - an MLP can't distinguish <code>[A, B, C]</code> from <code>[C, B, A]</code>. And in language, order is <strong>everything</strong>. &quot;I do not like&quot; vs &quot;I like not&quot; - same words, completely different meaning.</p>\n<p>You might think: &quot;OK, then let's add word position as a feature.&quot; But that doesn't solve the problem - the MLP still doesn't understand that the word at position 1 has a <strong>relationship</strong> with the word at position 5. Each position is just another number on the input.</p>\n<p>So we need something that processes data <strong>step by step</strong>, <strong>in order</strong>, and builds understanding <strong>sequentially</strong>. Just like we read a book - sentence by sentence, word by word.</p>\n<p>And here enters the RNN.</p>\n<hr />\n<h2><a href=\"#rnn---reads-text-one-by-one\" aria-hidden=\"true\" class=\"anchor\" id=\"rnn---reads-text-one-by-one\"></a>RNN - &quot;reads text one by one&quot;</h2>\n<p>A <strong>Recurrent Neural Network (RNN)</strong> is a network that has something an MLP doesn't: <strong>memory</strong>. Well... sort of ;-)</p>\n<p>Imagine you're reading a book. You don't read the whole page at once (like an MLP would). You read <strong>word by word</strong>, <strong>sentence by sentence</strong>. And with each new word you <strong>update your understanding</strong> of what's going on.</p>\n<p>That's exactly what an RNN does. It has a <strong>hidden state</strong> - that's its &quot;understanding of the text so far&quot;. With each new word:</p>\n<ol>\n<li>It takes the new word (x_t)</li>\n<li>It takes its current understanding (h_{t-1})</li>\n<li>It combines them and creates a <strong>new</strong> understanding (h_t)</li>\n</ol>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1609.8755\" height=\"476.04822\" viewBox=\"0 0 1609.8755 476.04822\"><rect x=\"0\" y=\"0\" width=\"1609.8755\" height=\"476.04822\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"1585.88\" height=\"452.05\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"800.94\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"800.94\" dy=\"0.00\">RNN reads: &apos;The cat sits on</tspan><tspan x=\"800.94\" dy=\"21.00\">the mat&apos;</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 168.563,104.549 L 177.995,104.549 Q 185.713,104.549 193.419,104.953 L 253.268,108.095 Q 260.975,108.500 268.693,108.500 L 278.125,108.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(278.12 108.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 387.248,108.819 L 579.280,108.819\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(579.28 108.82) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"402.19\" y=\"58.45\" width=\"186.98\" height=\"52.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"495.68\" y=\"77.65\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"495.68\" dy=\"0.00\">&quot;understands:</tspan><tspan x=\"495.68\" dy=\"21.00\">&apos;a cat is coming&apos;&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 168.563,209.605 L 177.995,209.605 Q 185.713,209.605 193.283,208.105 L 554.560,136.542 Q 562.130,135.043 569.847,135.043 L 579.280,135.043\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(579.28 135.04) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 688.403,109.387 L 942.728,109.387\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(942.73 109.39) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"705.77\" y=\"57.76\" width=\"256.19\" height=\"52.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"833.87\" y=\"76.96\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"833.87\" dy=\"0.00\">&quot;understands:</tspan><tspan x=\"833.87\" dy=\"21.00\">&apos;the cat does something&apos;&quot;</tspan></text></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 177.214,280.048 L 186.647,280.048 Q 194.364,280.048 201.939,278.573 L 918.002,139.133 Q 925.578,137.658 933.295,137.658 L 942.728,137.658\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(942.73 137.66) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 1051.851,144.637 L 1069.000,144.637 L 931.343,156.437 L 948.493,156.437\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(948.49 156.44) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 229.125,382.223 L 238.558,382.223 Q 246.275,382.223 253.787,380.454 L 923.831,222.656 Q 931.343,220.887 939.060,220.887 L 948.493,220.887\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(948.49 220.89) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 1057.616,165.226 L 1067.048,165.226 Q 1074.766,165.226 1082.403,164.116 L 1296.052,133.072 Q 1303.690,131.962 1311.407,131.962 L 1320.839,131.962\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1320.84 131.96) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-7\" data-label-kind=\"center\" x=\"1097.28\" y=\"163.87\" width=\"266.08\" height=\"52.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-7\" data-label-kind=\"center\"><text x=\"1230.32\" y=\"183.07\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1230.32\" dy=\"0.00\">&quot;understands:</tspan><tspan x=\"1230.32\" dy=\"21.00\">&apos;the cat sits on the mat&apos;&quot;</tspan></text></g><rect x=\"1320.84\" y=\"84.66\" width=\"233.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#66cc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1437.36\" y=\"113.66\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"1437.36\" dy=\"0.00\">✅ Full understanding</tspan></text><rect x=\"278.12\" y=\"72.50\" width=\"109.12\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"332.69\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"332.69\" dy=\"0.00\">🔄 RNN</tspan><tspan x=\"332.69\" dy=\"21.00\">h₁</tspan></text><rect x=\"579.28\" y=\"73.14\" width=\"109.12\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"633.84\" y=\"102.14\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"633.84\" dy=\"0.00\">🔄 RNN</tspan><tspan x=\"633.84\" dy=\"21.00\">h₂</tspan></text><rect x=\"942.73\" y=\"73.64\" width=\"109.12\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"997.29\" y=\"102.64\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"997.29\" dy=\"0.00\">🔄 RNN</tspan><tspan x=\"997.29\" dy=\"21.00\">h₃</tspan></text><rect x=\"948.49\" y=\"155.44\" width=\"109.12\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1003.05\" y=\"184.44\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"1003.05\" dy=\"0.00\">🔄 RNN</tspan><tspan x=\"1003.05\" dy=\"21.00\">h₄</tspan></text><rect x=\"48.00\" y=\"79.05\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"108.28\" y=\"108.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"108.28\" dy=\"0.00\">📖 &apos;The&apos;</tspan></text><rect x=\"48.00\" y=\"179.05\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"108.28\" y=\"208.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"108.28\" dy=\"0.00\">📖 &apos;cat&apos;</tspan></text><rect x=\"48.00\" y=\"279.05\" width=\"129.21\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"112.61\" y=\"308.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"112.61\" dy=\"0.00\">📖 &apos;sits&apos;</tspan></text><rect x=\"48.00\" y=\"379.05\" width=\"181.13\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"138.56\" y=\"408.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"138.56\" dy=\"0.00\">📖 &apos;on the mat&apos;</tspan></text></svg></div>\n<p>This diagram is exactly the <strong>unrolling</strong> in time. In reality it's <strong>the same</strong> RNN neuron - but we &quot;unwrap&quot; it in time to show how it processes consecutive words. Notice: the arrow goes from left to right - information flows <strong>sequentially</strong>.</p>\n<p>This is brilliant in its simplicity. The RNN &quot;reads&quot; text just like we do - one by one, building understanding step by step.</p>\n<h3><a href=\"#rnn-in-code---minimal\" aria-hidden=\"true\" class=\"anchor\" id=\"rnn-in-code---minimal\"></a>RNN in code - minimal</h3>\n<p>To really feel this, let's write the simplest possible RNN. No PyTorch, no TensorFlow - just NumPy:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>import</a-k> <a-v>numpy</a-v> <a-k>as</a-k> <a-v>np</a-v>\n\n<a-k>def</a-k> <a-f>simple_rnn</a-f>(<a-v>word_vectors</a-v>, <a-v>hidden_size</a-v><a-o>=</a-o><a-n>4</a-n>):\n    <a-v>words</a-v>, <a-v>dim</a-v> <a-o>=</a-o> <a-v>word_vectors</a-v>.<a-pr>shape</a-pr>\n    <a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>seed</a-pr>(<a-n>42</a-n>)\n    \n    <a-cr>W_h</a-cr> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>randn</a-pr>(<a-v>hidden_size</a-v>, <a-v>hidden_size</a-v>) <a-o>*</a-o> <a-n>0.01</a-n>\n    <a-cr>W_x</a-cr> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>randn</a-pr>(<a-v>hidden_size</a-v>, <a-v>dim</a-v>) <a-o>*</a-o> <a-n>0.01</a-n>\n    <a-v>bias</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>zeros</a-pr>(<a-v>hidden_size</a-v>)\n    \n    <a-v>h</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>zeros</a-pr>(<a-v>hidden_size</a-v>)\n    \n    <a-k>for</a-k> <a-v>t</a-v>, <a-v>word</a-v> <a-o>in</a-o> <a-f>enumerate</a-f>(<a-v>word_vectors</a-v>):\n        <a-v>h</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>tanh</a-pr>(<a-cr>W_h</a-cr> @ <a-v>h</a-v> <a-o>+</a-o> <a-cr>W_x</a-cr> @ <a-v>word</a-v> <a-o>+</a-o> <a-v>bias</a-v>)\n        <a-f>print</a-f>(<a-s>f&quot;  Step </a-s><a-p>{</a-p><a-v>t</a-v><a-o>+</a-o><a-n>1</a-n><a-p>}</a-p><a-s>: hidden state = </a-s><a-p>{</a-p><a-v>np</a-v><a-eb>.</a-eb><a-pr>round</a-pr><a-eb>(</a-eb><a-v>h</a-v><a-eb>, </a-eb><a-n>2</a-n><a-eb>)</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)\n    \n    <a-k>return</a-k> <a-v>h</a-v>\n\n<a-v>the</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-n>1.0</a-n>, <a-n>0.0</a-n>])\n<a-v>cat</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-n>0.0</a-n>, <a-n>1.0</a-n>])\n<a-v>sits</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-n>0.3</a-n>, <a-n>0.3</a-n>])\n<a-v>on_mat</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-n>0.8</a-n>, <a-n>0.2</a-n>])\n\n<a-v>sentence</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>array</a-pr>([<a-v>the</a-v>, <a-v>cat</a-v>, <a-v>sits</a-v>, <a-v>on_mat</a-v>])\n<a-f>print</a-f>(<a-s>&quot;Processing: &#39;The cat sits on the mat&#39;&quot;</a-s>)\n<a-v>final</a-v> <a-o>=</a-o> <a-f>simple_rnn</a-f>(<a-v>sentence</a-v>)\n<a-f>print</a-f>(<a-s>f&quot;\\nFinal hidden state: </a-s><a-p>{</a-p><a-v>np</a-v><a-eb>.</a-eb><a-pr>round</a-pr><a-eb>(</a-eb><a-v>final</a-v><a-eb>, </a-eb><a-n>2</a-n><a-eb>)</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)</code></pre>\n<p>Run it! You'll see how with each word the <code>hidden state</code> changes. The last hidden state is the &quot;understanding&quot; of the whole sentence by our simple RNN.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Key intuition:</strong> Notice the line <code>h = np.tanh(W_h @ h + W_x @ word + bias)</code>. That's the heart of the RNN.</p>\n<p><strong>Two parts of this line:</strong></p>\n<ul>\n<li><code>W_h @ h + W_x @ word + bias</code> - this is the same &quot;weighted sum&quot; as in the perceptron and MLP. Except now it sums <strong>two sources</strong>: the previous hidden state (<code>h</code>) and the new word (<code>word</code>).</li>\n<li><code>tanh(...)</code> - that's the <strong>activation function</strong>, exactly the same family as ReLU from the previous section. Instead of &quot;cutting off below zero&quot;, tanh squeezes everything into the range (-1, 1). But the goal is the same: <strong>break linearity</strong>.</li>\n</ul>\n<p>The new hidden state depends on <strong>two things</strong>: the previous hidden state (<code>h</code>) and the new word (<code>word</code>). That's exactly what we do when reading text - we combine what we already know with what we just read.</p>\n</div>\n<h3><a href=\"#but-the-rnn-has-one-big-problem\" aria-hidden=\"true\" class=\"anchor\" id=\"but-the-rnn-has-one-big-problem\"></a>But the RNN has one big problem...</h3>\n<p>And here we get to the topic that changed everything.</p>\n<hr />\n<h2><a href=\"#the-goldfish-problem---why-the-rnn-forgets\" aria-hidden=\"true\" class=\"anchor\" id=\"the-goldfish-problem---why-the-rnn-forgets\"></a>The goldfish problem - why the RNN forgets</h2>\n<p>The RNN has memory, yes. But it's a <strong>goldfish</strong> memory.</p>\n<p>Imagine this sentence:</p>\n<blockquote>\n<p>&quot;This is <strong>Jan</strong> and he's 30 years old. He likes hiking in the mountains, programming in Python, and playing the guitar. His favorite color is green. He once wanted to become an astronaut, but then he discovered that (...) [here 50 words about various things] (...) and that's why <strong>___</strong> went to music school.&quot;</p>\n</blockquote>\n<p>What should &quot;___&quot; be? <strong>Jan.</strong> But to know that, the RNN has to remember the name from the beginning of the sentence. And here's the problem: after 50+ words, the signal from the first word is so <strong>diluted</strong> that the RNN practically doesn't remember it.</p>\n<p>This is the famous <strong>vanishing gradient</strong> problem.</p>\n<p>Metaphor: <strong>Chinese whispers</strong>. You play Chinese whispers - the first person whispers a message to the second, that one to the third, and so on. After 10 people the message is a bit distorted. After 50 people - completely unreadable. After 100 people - someone says &quot;buy milk&quot;, and the last person hears &quot;grab bread&quot;.</p>\n<p>In an RNN the gradient (the learning signal) flows through the network exactly the same way - <strong>step by step</strong>. At each step it gets multiplied by some weights. If those weights are smaller than 1, then after many multiplications the gradient <strong>vanishes to zero</strong>. The network stops learning from distant words.</p>\n<p>And sometimes it's the other way - the weights are bigger than 1 and the gradient <strong>grows exponentially</strong> (exploding gradient). The network &quot;goes crazy&quot; and values shoot into space.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1192.3552\" height=\"96\" viewBox=\"0 0 1192.3552 96\"><rect x=\"0\" y=\"0\" width=\"1192.3552\" height=\"96\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 189.125,44.000 L 274.806,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(274.81 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"197.80\" y=\"13.70\" width=\"68.33\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"231.97\" y=\"31.40\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"231.97\" dy=\"0.00\">&quot;×0.7&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 386.717,44.000 L 472.397,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(472.40 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"395.39\" y=\"13.70\" width=\"68.33\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"429.56\" y=\"31.40\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"429.56\" dy=\"0.00\">&quot;×0.7&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 584.308,44.000 L 669.988,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(669.99 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"592.98\" y=\"13.70\" width=\"68.33\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"627.15\" y=\"31.40\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"627.15\" dy=\"0.00\">&quot;×0.7&quot;</tspan></text></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 781.899,44.000 L 858.565,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(858.56 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"791.01\" y=\"13.70\" width=\"58.44\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"820.23\" y=\"31.40\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"820.23\" dy=\"0.00\">&quot;...&quot;</tspan></text></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 979.127,44.000 L 1055.793,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1055.79 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-4\" data-label-kind=\"center\" x=\"988.24\" y=\"13.70\" width=\"58.44\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-4\" data-label-kind=\"center\"><text x=\"1017.46\" y=\"31.40\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1017.46\" dy=\"0.00\">&quot;...&quot;</tspan></text></g><rect x=\"8.00\" y=\"8.00\" width=\"181.13\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#66cc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"98.56\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"98.56\" dy=\"0.00\">Step 1</tspan><tspan x=\"98.56\" dy=\"21.00\">gradient = 1.0</tspan></text><rect x=\"274.81\" y=\"8.00\" width=\"111.91\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99cc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"330.76\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"330.76\" dy=\"0.00\">Step 2</tspan><tspan x=\"330.76\" dy=\"21.00\">0.7</tspan></text><rect x=\"472.40\" y=\"8.00\" width=\"111.91\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#cccc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"528.35\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"528.35\" dy=\"0.00\">Step 3</tspan><tspan x=\"528.35\" dy=\"21.00\">0.49</tspan></text><rect x=\"669.99\" y=\"8.00\" width=\"111.91\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#cc9966\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"725.94\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"725.94\" dy=\"0.00\">Step 4</tspan><tspan x=\"725.94\" dy=\"21.00\">0.34</tspan></text><rect x=\"858.56\" y=\"8.00\" width=\"120.56\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#cc6666\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"918.85\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"918.85\" dy=\"0.00\">Step 20</tspan><tspan x=\"918.85\" dy=\"21.00\">0.001</tspan></text><rect x=\"1055.79\" y=\"8.00\" width=\"120.56\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#993333\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1116.07\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"1116.07\" dy=\"0.00\">Step 50</tspan><tspan x=\"1116.07\" dy=\"21.00\">≈ 0</tspan></text></svg></div>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Why is this so important?</strong> Because language is full of <strong>long dependencies</strong>. &quot;The <strong>cat</strong>, which already ate all the fish in the fridge and then slept on the couch for three hours, was <strong>happy</strong>.&quot; - to connect &quot;cat&quot; with &quot;was happy&quot;, the model has to jump over a dozen words. An RNN can't do that.</p>\n</div>\n<p>And then in 1997 Sepp Hochreiter and Jürgen Schmidhuber said: <strong>what if we gave the network an explicit memory mechanism?</strong></p>\n<hr />\n<h2><a href=\"#lstm---the-network-with-a-notebook\" aria-hidden=\"true\" class=\"anchor\" id=\"lstm---the-network-with-a-notebook\"></a>LSTM - the network with a notebook</h2>\n<p>A <strong>Long Short-Term Memory (LSTM)</strong> is an RNN on steroids. Instead of one simple hidden state, the LSTM has a <strong>memory cell</strong> (cell state) and <strong>three gates</strong> that decide what to do with that memory.</p>\n<p>The metaphor that works best: <strong>an LSTM is a student with a notebook and three rules</strong>.</p>\n<h3><a href=\"#the-forget-gate---throw-out-old-notes\" aria-hidden=\"true\" class=\"anchor\" id=\"the-forget-gate---throw-out-old-notes\"></a>The forget gate - &quot;throw out old notes&quot;</h3>\n<p>At the beginning of each step the LSTM asks: <strong>&quot;what from my current memory is already outdated and I can throw out?&quot;</strong></p>\n<p>When you read a new chapter of a book, you don't need to remember what the characters had for breakfast three chapters ago. You forget irrelevant details to make room for new ones.</p>\n<p>In an LSTM: the forget gate passes each element of memory through a <strong>sigmoid</strong> (values 0-1). Close to 0 = &quot;forget&quot;. Close to 1 = &quot;keep&quot;.</p>\n<h3><a href=\"#the-input-gate---save-this-its-important\" aria-hidden=\"true\" class=\"anchor\" id=\"the-input-gate---save-this-its-important\"></a>The input gate - &quot;save this, it's important&quot;</h3>\n<p>Then the LSTM asks: <strong>&quot;what from the new word is worth saving?&quot;</strong></p>\n<p>When you read &quot;My name is <strong>Jan</strong>&quot; - you have a reflex: &quot;OK, this is important, I have to remember it&quot;. You don't memorize every word literally, but you <strong>pick out</strong> what's relevant.</p>\n<p>In an LSTM: the input gate decides which new information to let through to the cell state.</p>\n<h3><a href=\"#the-output-gate---show-me-what-i-need-right-now\" aria-hidden=\"true\" class=\"anchor\" id=\"the-output-gate---show-me-what-i-need-right-now\"></a>The output gate - &quot;show me what I need right now&quot;</h3>\n<p>Finally the LSTM asks: <strong>&quot;what from my memory is relevant to what I'm doing right now?&quot;</strong></p>\n<p>When someone asks you &quot;What's the name of that character we just read about?&quot; - you reach into the notebook and pull out the specific information. You don't show the whole notebook - only what's needed <strong>now</strong>.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"900.41156\" height=\"1148.5\" viewBox=\"0 0 900.41156 1148.5\"><rect x=\"0\" y=\"0\" width=\"900.41156\" height=\"1148.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"105.00\" width=\"876.41\" height=\"1027.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"446.21\" y=\"132.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"446.21\" dy=\"0.00\">LSTM - memory cell</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 451.103,238.500 L 451.103,248.125 Q 451.103,256.000 458.978,256.000 L 558.399,256.000 Q 568.399,256.000 568.399,266.000 L 568.399,410.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(568.40 410.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 677.310,360.500 L 677.310,370.125 Q 677.310,378.000 669.702,380.033 L 628.792,390.967 Q 621.184,393.000 621.184,400.875 L 621.184,410.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(621.18 410.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 536.399,461.500 L 536.399,471.125 Q 536.399,479.000 531.431,485.110 L 495.023,529.890 Q 490.055,536.000 490.055,543.875 L 490.055,553.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(490.05 553.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 379.825,503.500 L 379.825,513.125 Q 379.825,521.000 385.245,526.713 L 388.635,530.287 Q 394.055,536.000 394.055,543.875 L 394.055,553.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(394.05 553.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 214.296,360.500 L 214.296,370.125 Q 214.296,378.000 221.763,380.500 L 251.630,390.500 Q 259.098,393.000 259.098,400.875 L 259.098,410.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(259.10 410.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 442.066,604.500 L 442.066,654.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(442.07 654.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 442.083,747.500 L 442.083,797.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(442.08 797.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 458.094,848.500 L 458.094,898.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(458.09 898.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-8\" class=\"edgePath\" data-edge-id=\"edge-8\" d=\"M 453.827,360.500 L 453.827,379.300 Q 453.827,389.300 443.827,389.300 L 190.500,389.300 Q 180.500,389.300 180.500,399.300 L 180.500,866.500 Q 180.500,876.500 190.500,876.500 L 432.004,876.500 Q 441.904,876.500 441.904,886.400 L 441.904,898.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(441.90 898.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-9\" class=\"edgePath\" data-edge-id=\"edge-9\" d=\"M 442.099,949.500 L 442.099,999.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(442.10 999.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-10\" class=\"edgePath\" data-edge-id=\"edge-10\" d=\"M 215.976,80.000 L 215.976,102.750 Q 215.976,112.750 225.976,112.750 L 625.313,112.750 Q 635.313,112.750 635.313,122.750 L 635.313,288.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(635.31 288.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-11\" class=\"edgePath\" data-edge-id=\"edge-11\" d=\"M 144.776,80.000 L 144.776,93.116 Q 144.776,97.500 149.160,97.500 L 150.134,97.500 Q 154.518,97.500 154.518,101.884 L 154.518,288.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(154.52 288.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-12\" class=\"edgePath\" data-edge-id=\"edge-12\" d=\"M 188.427,80.000 L 188.427,256.500 Q 188.427,266.500 198.427,266.500 L 372.617,266.500 Q 382.517,266.500 382.517,276.400 L 382.517,288.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(382.52 288.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-13\" class=\"edgePath\" data-edge-id=\"edge-13\" d=\"M 732.478,80.000 L 732.478,89.625 Q 732.478,97.500 732.331,105.374 L 729.389,263.126 Q 729.242,271.000 729.242,278.875 L 729.242,288.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(729.24 288.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-14\" class=\"edgePath\" data-edge-id=\"edge-14\" d=\"M 642.301,80.000 L 642.301,85.280 Q 642.301,89.600 646.621,89.600 L 869.253,89.600 Q 869.973,89.600 869.973,88.880 L 869.973,88.720 Q 869.973,88.000 869.253,88.000 L 601.507,88.000 Q 594.982,88.000 594.982,81.475 L 594.982,80.025 Q 594.982,73.500 588.457,73.500 L 254.695,73.500 Q 244.695,73.500 244.695,83.500 L 244.695,288.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(244.69 288.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-15\" class=\"edgePath\" data-edge-id=\"edge-15\" d=\"M 602.982,79.000 L 593.357,79.000 Q 585.482,79.000 584.963,86.858 L 572.091,281.642 Q 571.572,289.500 563.697,289.500 L 554.072,289.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(554.07 289.50) rotate(180.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"329.86\" y=\"553.50\" width=\"224.38\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.05\" y=\"582.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"442.05\" dy=\"0.00\">➕ + new information</tspan></text><rect x=\"293.99\" y=\"145.50\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"423.49\" y=\"174.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"423.49\" dy=\"0.00\">📥 Cell state (input)</tspan><tspan x=\"423.49\" dy=\"21.00\">&lt;i&gt;the conveyor belt of</tspan><tspan x=\"423.49\" dy=\"21.00\">information&lt;/i&gt;</tspan></text><rect x=\"321.23\" y=\"654.50\" width=\"241.69\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.08\" y=\"683.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"442.08\" dy=\"0.00\">📤 Cell state (output)</tspan><tspan x=\"442.08\" dy=\"21.00\">&lt;i&gt;updated conveyor</tspan><tspan x=\"442.08\" dy=\"21.00\">belt&lt;/i&gt;</tspan></text><rect x=\"604.07\" y=\"288.50\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff6666\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"729.24\" y=\"317.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"729.24\" dy=\"0.00\">🗑️ Forget gate</tspan><tspan x=\"729.24\" dy=\"21.00\">&lt;i&gt;what to forget?&lt;/i&gt;</tspan></text><rect x=\"303.95\" y=\"999.50\" width=\"276.29\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#cc99ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.10\" y=\"1028.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"442.10\" dy=\"0.00\">🧠 Hidden state</tspan><tspan x=\"442.10\" dy=\"21.00\">&lt;i&gt;what it &apos;thinks&apos; right</tspan><tspan x=\"442.10\" dy=\"21.00\">now&lt;/i&gt;</tspan></text><rect x=\"602.98\" y=\"8.00\" width=\"258.99\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"732.48\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"732.48\" dy=\"0.00\">🧠 Previous hidden state</tspan><tspan x=\"732.48\" dy=\"21.00\">(h_{t-1})</tspan></text><rect x=\"38.00\" y=\"288.50\" width=\"233.04\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#66cc66\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"154.52\" y=\"317.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"154.52\" dy=\"0.00\">📥 Input gate</tspan><tspan x=\"154.52\" dy=\"21.00\">&lt;i&gt;what to save?&lt;/i&gt;</tspan></text><rect x=\"469.18\" y=\"410.50\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"568.40\" y=\"439.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"568.40\" dy=\"0.00\">✖️ × forget gate</tspan></text><rect x=\"342.88\" y=\"898.50\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.10\" y=\"927.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"442.10\" dy=\"0.00\">✖️ × output gate</tspan></text><rect x=\"212.10\" y=\"410.50\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"315.64\" y=\"439.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"315.64\" dy=\"0.00\">📝 New information</tspan><tspan x=\"315.64\" dy=\"21.00\">&lt;i&gt;input gate ×</tspan><tspan x=\"315.64\" dy=\"21.00\">candidate&lt;/i&gt;</tspan></text><rect x=\"321.04\" y=\"288.50\" width=\"233.04\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#6666ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"437.55\" y=\"317.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"437.55\" dy=\"0.00\">📤 Output gate</tspan><tspan x=\"437.55\" dy=\"21.00\">&lt;i&gt;what to show?&lt;/i&gt;</tspan></text><rect x=\"394.79\" y=\"797.50\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.09\" y=\"826.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"442.09\" dy=\"0.00\">tanh</tspan></text><rect x=\"45.56\" y=\"29.00\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"144.78\" y=\"58.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"144.78\" dy=\"0.00\">📖 New word (x_t)</tspan></text></svg></div>\n<p>The key thing: the <strong>cell state</strong> is that &quot;conveyor belt&quot;. Information on it can flow <strong>almost unchanged</strong> through many steps - the gates only decide what to let through, what to add, and what to remove. This solves the vanishing gradient problem, because the information doesn't have to be &quot;multiplied&quot; at every step - it can just flow.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>RNN vs LSTM in one sentence:</strong> An RNN tries to remember <strong>everything</strong>, but forgets quickly. An LSTM is <strong>selective</strong> - it decides what to keep, what to update, and what to show. That's the difference between &quot;trying to memorize an entire lecture word for word&quot; and &quot;taking notes of the most important points&quot;.</p>\n</div>\n<details>\n<summary>For the curious: the math of LSTM gates</summary>\n<p>If you want to see the formulas, here they are (you don't have to memorize them, but it's worth seeing that it's not black magic):</p>\n<p><strong>Forget gate:</strong>\n$$f_t = \\sigma(W_f \\cdot [h_{t-1}, x_t] + b_f)$$</p>\n<p><strong>Input gate:</strong>\n$$i_t = \\sigma(W_i \\cdot [h_{t-1}, x_t] + b_i)$$</p>\n<p><strong>Cell state candidate:</strong>\n$$\\tilde{C}<em>t = \\tanh(W_c \\cdot [h</em>{t-1}, x_t] + b_c)$$</p>\n<p><strong>Cell state update:</strong>\n$$C_t = f_t \\odot C_{t-1} + i_t \\odot \\tilde{C}_t$$</p>\n<p><strong>Output gate:</strong>\n$$o_t = \\sigma(W_o \\cdot [h_{t-1}, x_t] + b_o)$$</p>\n<p><strong>Hidden state:</strong>\n$$h_t = o_t \\odot \\tanh(C_t)$$</p>\n<p>Where $\\sigma$ is the sigmoid (squashes values into 0-1), $\\odot$ is element-wise multiplication, and $[h_{t-1}, x_t]$ is the concatenation of the previous hidden state with the new input.</p>\n</details>\n<h3><a href=\"#an-experiment-for-you\" aria-hidden=\"true\" class=\"anchor\" id=\"an-experiment-for-you\"></a>An experiment for you</h3>\n<p>Try it yourself. Fire up ChatGPT (or Claude, Gemini - whatever you have) and send this prompt:</p>\n<blockquote>\n<p>&quot;Pola had a rare ability to remember numbers. Her favorite number was 42. She also liked longboarding, watercolor painting, and playing chess. Her cat was named Whiskers. (...) <em>[paste 3-4 paragraphs of any text here - a pancake recipe, a weather report, whatever]</em> (...) Still, it was ___ who decided to enter the math competition.&quot;</p>\n</blockquote>\n<p>See whether the model fills in the blank correctly (<strong>Pola</strong>). An LSTM would handle this. A plain RNN - probably not. And why? Because the LSTM has a mechanism that says &quot;remember the name <strong>Pola</strong> - this might be important later&quot;. The RNN would simply... forget ;-)</p>\n<hr />\n<h2><a href=\"#why-lstm-still-wasnt-enough\" aria-hidden=\"true\" class=\"anchor\" id=\"why-lstm-still-wasnt-enough\"></a>Why LSTM still wasn't enough</h2>\n<p>OK, so LSTM solved the memory problem. At least partially. But new problems appeared, and they turned out to be <strong>fundamental</strong>.</p>\n<h3><a href=\"#problem-1-even-lstm-has-its-limits\" aria-hidden=\"true\" class=\"anchor\" id=\"problem-1-even-lstm-has-its-limits\"></a>Problem 1: Even LSTM has its limits</h3>\n<p>LSTM solved vanishing gradient <strong>to a large extent</strong>, but not <strong>completely</strong>. When the distance between related words grows to hundreds or thousands of words, even LSTM starts losing the thread of the narrative. Bengio et al. (1994) showed that recurrent networks - even with gates - still struggle to maintain useful gradients over very long distances.</p>\n<p>So: instead of forgetting after 10 words (RNN), LSTM forgets after... 100? 200? Better, but still not ideal.</p>\n<h3><a href=\"#problem-2-sequentiality--bottleneck\" aria-hidden=\"true\" class=\"anchor\" id=\"problem-2-sequentiality--bottleneck\"></a>Problem 2: Sequentiality = bottleneck</h3>\n<p>And this is the <strong>most important</strong> problem.</p>\n<p>RNN and LSTM process data <strong>step by step</strong>. Step 2 has to wait for step 1. Step 3 for step 2. And so on.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"899.1033\" height=\"75\" viewBox=\"0 0 899.1033 75\"><rect x=\"0\" y=\"0\" width=\"899.1033\" height=\"75\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 119.911,33.500 L 160.638,33.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(160.64 33.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 272.549,33.500 L 313.277,33.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(313.28 33.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 425.188,33.500 L 465.915,33.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(465.92 33.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 577.826,33.500 L 618.554,33.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(618.55 33.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 704.509,33.500 L 745.237,33.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(745.24 33.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"8.00\" y=\"8.00\" width=\"111.91\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"63.96\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"63.96\" dy=\"0.00\">Step 1</tspan></text><rect x=\"160.64\" y=\"8.00\" width=\"111.91\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"216.59\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"216.59\" dy=\"0.00\">Step 2</tspan></text><rect x=\"313.28\" y=\"8.00\" width=\"111.91\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"369.23\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"369.23\" dy=\"0.00\">Step 3</tspan></text><rect x=\"465.92\" y=\"8.00\" width=\"111.91\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"521.87\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"521.87\" dy=\"0.00\">Step 4</tspan></text><rect x=\"618.55\" y=\"8.00\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"661.53\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"661.53\" dy=\"0.00\">...</tspan></text><rect x=\"745.24\" y=\"8.00\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"814.17\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"814.17\" dy=\"0.00\">Step 1000</tspan></text></svg></div>\n<p>Now think about GPUs. A GPU is a machine that <strong>loves</strong> doing many things at once (parallel processing). Thousands of cores working simultaneously.</p>\n<p>But RNN/LSTM tells the GPU: &quot;no, no, wait. First let's finish step 1, <strong>only then</strong> start step 2&quot;. The GPU cries.</p>\n<p>It's like a book with 10,000 chapters, where <strong>each chapter has to be read after the previous one</strong>. You can't read chapter 500 until you've finished 499. You can't parallelize this. For short texts it's not a problem, but when training a model on <strong>billions</strong> of words? That's a nightmare.</p>\n<p>LSTM additionally has <strong>4x more parameters</strong> than a simple RNN (three gates + cell state = four sets of weights per neuron). So it trains slower and uses more memory.</p>\n<h3><a href=\"#problem-3-black-box\" aria-hidden=\"true\" class=\"anchor\" id=\"problem-3-black-box\"></a>Problem 3: &quot;Black box&quot;</h3>\n<p>LSTM (like most deep learning models) is hard to interpret. The model can generate correct results, but <strong>it's hard to understand why</strong> it made this decision and not another. In applications like medicine or finance, where interpretability is key, that's a serious problem.</p>\n<h3><a href=\"#evolution-summary---what-solved-what\" aria-hidden=\"true\" class=\"anchor\" id=\"evolution-summary---what-solved-what\"></a>Evolution summary - what solved what</h3>\n<table>\n<thead>\n<tr>\n<th>Architecture</th>\n<th>Year</th>\n<th>Solves...</th>\n<th>But can't...</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Perceptron</strong></td>\n<td>1958</td>\n<td>Linear classification</td>\n<td>XOR, non-linearity</td>\n</tr>\n<tr>\n<td><strong>MLP</strong></td>\n<td>1986</td>\n<td>Non-linear relationships</td>\n<td>Understand word order</td>\n</tr>\n<tr>\n<td><strong>RNN</strong></td>\n<td>1986</td>\n<td>Process sequences step by step</td>\n<td>Remember long dependencies</td>\n</tr>\n<tr>\n<td><strong>LSTM</strong></td>\n<td>1997</td>\n<td>Remember longer thanks to gates</td>\n<td>Process in parallel, very long texts</td>\n</tr>\n</tbody>\n</table>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1284.3135\" height=\"117.12468\" viewBox=\"0 0 1284.3135 117.12468\"><rect x=\"0\" y=\"0\" width=\"1284.3135\" height=\"117.12468\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 1034.787,54.556 L 1179.992,54.556\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1179.99 54.56) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"1043.56\" y=\"24.26\" width=\"127.65\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"1107.39\" y=\"41.96\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1107.39\" dy=\"0.00\">&quot;add layers&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 163.170,54.562 L 163.170,66.772 Q 163.170,76.762 173.160,76.762 L 332.992,76.762 Q 342.982,76.762 342.982,66.772 L 342.982,54.562\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(342.98 54.56) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"194.19\" y=\"78.76\" width=\"117.77\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"253.08\" y=\"96.46\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"253.08\" dy=\"0.00\">&quot;add gates&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 567.367,54.494 L 644.262,54.494\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(644.26 54.49) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"576.59\" y=\"56.49\" width=\"58.44\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"605.81\" y=\"74.19\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"605.81\" dy=\"0.00\">&quot;???&quot;</tspan></text></g><rect x=\"342.98\" y=\"8.00\" width=\"224.38\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#cc99ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"455.17\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"455.17\" dy=\"0.00\">LSTM</tspan><tspan x=\"455.17\" dy=\"21.00\">✅ longer memory</tspan><tspan x=\"455.17\" dy=\"21.00\">❌ sequential = slow</tspan></text><rect x=\"1179.99\" y=\"29.11\" width=\"88.32\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1224.15\" y=\"58.11\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1224.15\" dy=\"0.00\">MLP</tspan></text><rect x=\"845.01\" y=\"8.00\" width=\"189.78\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"939.90\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"939.90\" dy=\"0.00\">Perceptron</tspan><tspan x=\"939.90\" dy=\"21.00\">✅ classifies</tspan><tspan x=\"939.90\" dy=\"21.00\">❌ only linearly</tspan></text><rect x=\"644.26\" y=\"28.99\" width=\"151.70\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff6666\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"720.11\" y=\"57.99\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"720.11\" dy=\"0.00\">&lt;b&gt;???&lt;/b&gt;</tspan></text><rect x=\"8.00\" y=\"8.12\" width=\"155.17\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ccff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"85.58\" y=\"37.12\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"85.58\" dy=\"0.00\">RNN</tspan><tspan x=\"85.58\" dy=\"21.00\">✅ sequences</tspan><tspan x=\"85.58\" dy=\"21.00\">❌ forgets</tspan></text></svg></div>\n<p>Each generation solved the previous one's problem, but created a <strong>new</strong> one. It's like a game of whack-a-mole - you hit one mole, another pops up.</p>\n<p>And then in 2017 someone asked a crazy question...</p>\n<hr />\n<h2><a href=\"#what-if-we-stop-reading-one-by-one\" aria-hidden=\"true\" class=\"anchor\" id=\"what-if-we-stop-reading-one-by-one\"></a>&quot;What if we stop reading one by one?&quot;</h2>\n<p>The metaphor that changes everything.</p>\n<p>Imagine you're reading a novel. Now you have three ways to do it:</p>\n<ul>\n<li><strong>RNN</strong> - you remember the last few sentences. The rest blurs.</li>\n<li><strong>LSTM</strong> - you hold onto the main plot, forget the small details. Better, but you still read linearly.</li>\n<li><strong>???</strong> - instead of reading word by word, <strong>you look at the whole page at once</strong>. Your attention jumps to the key characters, important plot moments, unexpected twists. <strong>You don't read in order - you grasp the whole thing simultaneously!</strong></li>\n</ul>\n<p>In 2017 a group of researchers at Google published a paper with the modest title: <strong>&quot;Attention Is All You Need&quot;</strong>. Their crazy idea? <strong>What if we stop reading one by one altogether?</strong> What if every word could &quot;see&quot; <strong>all the other words at once</strong>?</p>\n<p>And <strong>a revolution happened</strong>. Because if every word looks at every other <strong>simultaneously</strong> (not waiting for its turn), then:</p>\n<ul>\n<li>There's no sequential bottleneck - everything happens <strong>in parallel</strong></li>\n<li>The GPU is in heaven - thousands of cores working at once</li>\n<li>Long dependencies? No problem - word no. 1 and word no. 1000 &quot;see&quot; each other <strong>directly</strong>, without 999 intermediate steps</li>\n</ul>\n<p>This architecture is called the <strong>Transformer</strong>. And it's what ChatGPT, Claude, Gemini, and all the LLMs you know are built on.</p>\n<hr />\n<h2><a href=\"#summary---the-whole-evolution-in-one-place\" aria-hidden=\"true\" class=\"anchor\" id=\"summary---the-whole-evolution-in-one-place\"></a>Summary - the whole evolution in one place</h2>\n<table>\n<thead>\n<tr>\n<th>Architecture</th>\n<th>Metaphor</th>\n<th>What it can do</th>\n<th>What it can't?</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Perceptron</strong></td>\n<td>A ruler</td>\n<td>Draws one line, classifies into 2 groups</td>\n<td>XOR, non-linearity, anything complex</td>\n</tr>\n<tr>\n<td><strong>MLP</strong></td>\n<td>A team of analysts</td>\n<td>Models non-linear relationships, &quot;depth&quot;</td>\n<td>Doesn't understand order, sees everything at once</td>\n</tr>\n<tr>\n<td><strong>RNN</strong></td>\n<td>A word-by-word reader</td>\n<td>Processes sequences, has a hidden state</td>\n<td>Short memory (vanishing gradient)</td>\n</tr>\n<tr>\n<td><strong>LSTM</strong></td>\n<td>A student with a notebook and gates</td>\n<td>Selective memory, three control gates</td>\n<td>Sequential = slow, no parallelization</td>\n</tr>\n<tr>\n<td><strong>Transformer</strong></td>\n<td>The whole page at once</td>\n<td>Parallelism, attention to everything</td>\n<td>...to be discovered in the next posts...</td>\n</tr>\n</tbody>\n</table>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"368.94678\" height=\"605.5\" viewBox=\"0 0 368.94678 605.5\"><rect x=\"0\" y=\"0\" width=\"368.94678\" height=\"605.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"344.95\" height=\"581.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"180.47\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"180.47\" dy=\"0.00\">From a neuron to an LLM -</tspan><tspan x=\"180.47\" dy=\"21.00\">the path we took</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 180.472,144.500 L 180.472,168.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 168.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 180.472,240.500 L 180.473,264.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 264.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 180.473,336.500 L 180.473,360.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 360.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 180.473,432.500 L 180.473,456.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 456.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"76.93\" y=\"360.50\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#cc99ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"389.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">LSTM 1997</tspan><tspan x=\"180.47\" dy=\"21.00\">memory with gates</tspan></text><rect x=\"55.30\" y=\"168.50\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"197.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">MLP 1986</tspan><tspan x=\"180.47\" dy=\"21.00\">non-linearity + layers</tspan></text><rect x=\"59.63\" y=\"72.50\" width=\"241.69\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">Perceptron 1958</tspan><tspan x=\"180.47\" dy=\"21.00\">linear classification</tspan></text><rect x=\"46.65\" y=\"264.50\" width=\"267.64\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ccff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"293.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">RNN 1986</tspan><tspan x=\"180.47\" dy=\"21.00\">sequences + hidden state</tspan></text><rect x=\"38.00\" y=\"456.50\" width=\"284.95\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff6666\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"485.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"180.47\" dy=\"0.00\">Transformer 2017</tspan><tspan x=\"180.47\" dy=\"21.00\">attention to everything at</tspan><tspan x=\"180.47\" dy=\"21.00\">once</tspan></text></svg></div>\n<h3><a href=\"#final-quiz-match-the-architecture\" aria-hidden=\"true\" class=\"anchor\" id=\"final-quiz-match-the-architecture\"></a>Final quiz: match the architecture<sup class=\"footnote-ref\"><a href=\"#fn-2\" id=\"fnref-2\" data-footnote-ref>2</a></sup></h3>\n<ol>\n<li>You want to predict the price of a house based on square footage, number of rooms, and neighborhood - which architecture is enough?</li>\n<li>You need to process a 50-word sentence and determine its sentiment (positive/negative) - what do you choose?</li>\n<li>You're training a model on 10,000-word texts and every word has to &quot;see&quot; every other - RNN, LSTM, or something else?</li>\n<li>You want to classify points on a plane into two groups, but they're arranged in an X shape (XOR) - is a single perceptron enough?</li>\n</ol>\n<hr />\n<p>This post is quite long, but I felt this evolution from the perceptron to LSTM deserved a full, told story.</p>\n<p>If anything is unclear - <strong>let me know in the comments</strong>, I'll try to explain.</p>\n<p>Which architecture surprised you the most? Did you know that the &quot;AI Winter&quot; was caused by something as &quot;simple&quot; as XOR?</p>\n<blockquote>\n<p><strong>What's in the next post?</strong> We're getting into the <strong>Transformer</strong> - the architecture that changed everything. Attention, self-attention, positional encoding, multi-head attention - all the things that made ChatGPT exist in the first place. Stay tuned!</p>\n</blockquote>\n<p>See you next time!</p>\n<hr />\n<p><strong>Sources and interesting links:</strong></p>\n<p>If you want to go deeper, here are the materials I used:</p>\n<ul>\n<li><a href=\"https://d2l.ai/chapter_multilayer-perceptrons/mlp.html\">Multilayer Perceptrons - d2l.ai</a> - an excellent, visual introduction to MLP: layers, activation functions, the transition from linear regression to multi-layer networks</li>\n<li><a href=\"https://en.wikipedia.org/wiki/Multilayer_perceptron\">Multilayer perceptron - Wikipedia</a> - definitions, network diagrams, a timeline of the history from 1943 to the present</li>\n<li><a href=\"https://dev.to/zeromathai/multilayer-perceptron-mlp-a-practical-way-to-understand-neural-networks-3hic\">Multilayer Perceptron (MLP): A Practical Way to Understand Neural Networks - dev.to</a> - a fresh, very intuitive article with metaphors and a comparison of MLP vs CNN vs Transformer</li>\n<li><a href=\"https://ai.plainenglish.io/deep-learning-specialization-perceptron-explained-building-blocks-working-limitations-c1e3b0815f08\">Perceptron Explained - PlainEnglish</a> - the perceptron as the &quot;building block&quot; of networks, components, geometric intuition, limitations</li>\n<li><a href=\"https://www.geeksforgeeks.org/deep-learning/multi-layer-perceptron-learning-in-tensorflow/\">Multi-Layer Perceptron Learning in TensorFlow - GeeksforGeeks</a> - clear diagrams, forward propagation, backpropagation with implementation</li>\n<li><a href=\"https://www.geeksforgeeks.org/deep-learning/deep-learning-introduction-to-long-short-term-memory/\">Introduction to Long Short Term Memory - GeeksforGeeks</a> - an accessible introduction to LSTM: memory cell, gates, the long-term dependencies problem</li>\n<li><a href=\"https://papers.ssrn.com/sol3/JELJOUR_Results.cfm?form_name=journalBrowse&amp;journal_id=3747444\">Drawbacks of LSTM Algorithm: A Case Study - SSRN</a> - the drawbacks of LSTM: computational complexity, overfitting, lack of parallelization, sensitivity to hyperparameters</li>\n<li><a href=\"https://dev.to/sreeni5018/understanding-transformer-model-types-the-evolution-from-rnn-to-modern-ai-1j4i\">Understanding Transformer Model Types: The Evolution from RNN to Modern AI - dev.to</a> - a narrative account of the transition from RNNs to Transformers, encoder/decoder types</li>\n<li><a href=\"https://www.youtube.com/watch?v=gNusDo8D8gk\">LLM: Large Language Models Evolution - YouTube</a> - a video telling the development line from sequential models to attention-based architectures</li>\n</ul>\n<section class=\"footnotes\" data-footnotes>\n<ol>\n<li id=\"fn-1\">\n<p>Mini-quiz answers: 1) Linear - y = ax + b is a linear function. 2) Non-linear - the step function &quot;breaks&quot; linearity. 3) Linear! Without a non-linear activation, an MLP with 100 layers = one big linear transformation. That's exactly why activation functions are necessary. <a href=\"#fnref-1\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"1\" aria-label=\"Back to reference 1\">↩</a></p>\n</li>\n<li id=\"fn-2\">\n<p>My answers: 1) A simple <strong>MLP</strong> is enough - tabular data, no sequence. 2) <strong>LSTM</strong> - a sequence of moderate length, LSTM will handle it. 3) <strong>Transformer</strong> - 10,000 words is too much even for LSTM. A Transformer with self-attention lets every word &quot;see&quot; every other without waiting. 4) <strong>No</strong> - a single perceptron can't solve XOR. You need at least an MLP (2 layers). <a href=\"#fnref-2\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"2\" aria-label=\"Back to reference 2\">↩</a></p>\n</li>\n</ol>\n</section>\n",
      "summary": "\"From a single neuron in 1958, through MLP and RNN with the forgetting problem, to LSTM with memory gates. The evolution of architectures that led to Transformers.\"",
      "date_published": "2026-06-17T00:00:00-00:00",
      "image": "",
      "authors": [
        {
          "name": "Blazej Gruszka",
          "url": "https://www.linkedin.com/in/blazejgruszka/",
          "avatar": "https://github.com/bgruszka.png"
        }
      ],
      "tags": [
        "llm",
        "ai",
        "neural-networks",
        "rnn",
        "lstm",
        "perceptron",
        "mlp",
        "language-models",
        "deep-learning"
      ],
      "language": "en"
    },
    {
      "id": "https://gruszka.dev/en/how-computer-reads-text.html",
      "url": "https://gruszka.dev/en/how-computer-reads-text.html",
      "title": "How a computer reads text - from counting words to vectors",
      "content_html": "<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Want to run this code yourself?</strong> All the examples from this post are in a ready-made Jupyter notebook: <a href=\"./how-computer-reads-text.ipynb\">how-computer-reads-text.ipynb</a></p>\n</div>\n<p>In the two previous posts we built a solid foundation. In the <a href=\"linguistic-features-and-llm.html\">first</a> we took language apart - phonetics, morphology, syntax, semantics, pragmatics. In the <a href=\"semiotics-and-llm.html\">second</a> we asked: &quot;OK, but does an LLM even understand what it generates?&quot; and concluded that an LLM is a machine of signs, not a mind.</p>\n<p>But one fundamental question remained unanswered: <strong>how does a computer even &quot;take&quot; text in?</strong></p>\n<p>Because a computer doesn't see letters. It doesn't see words. A computer sees <strong>numbers</strong>. So how is it that you type &quot;The cat sits on the mat&quot; and ChatGPT somehow processes it? What's the path from text to number, from number to &quot;understanding&quot;?</p>\n<p>That path is a fascinating story of evolution - from the simplest word counting, through ever smarter mathematical tricks, to vectors that can capture semantic similarities. Every step on that path was an answer to the limitations of the previous one.</p>\n<p>This is the <strong>third post in the &quot;Understanding LLM&quot; series</strong>. Today we switch the perspective from linguistic and philosophical to <strong>technical</strong>. But don't worry - there will still be plenty of examples, plenty of &quot;aha!&quot; moments, and zero formulas you can't understand ;-)</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1319.9656\" height=\"96\" viewBox=\"0 0 1319.9656 96\"><rect x=\"0\" y=\"0\" width=\"1319.9656\" height=\"96\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 232.384,44.000 L 282.384,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(282.38 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 498.117,44.000 L 548.117,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(548.12 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 763.849,44.000 L 813.849,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(813.85 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 1003.626,44.000 L 1053.626,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1053.63 44.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"282.38\" y=\"8.00\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"390.25\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"390.25\" dy=\"0.00\">🔢 BoW / TF-IDF</tspan><tspan x=\"390.25\" dy=\"21.00\">&lt;i&gt;count words&lt;/i&gt;</tspan></text><rect x=\"548.12\" y=\"8.00\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"655.98\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"655.98\" dy=\"0.00\">🔗 N-grams / Markov</tspan><tspan x=\"655.98\" dy=\"21.00\">&lt;i&gt;add context&lt;/i&gt;</tspan></text><rect x=\"813.85\" y=\"8.00\" width=\"189.78\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ccff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"908.74\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"908.74\" dy=\"0.00\">📊 Bayes</tspan><tspan x=\"908.74\" dy=\"21.00\">&lt;i&gt;classify&lt;/i&gt;</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"120.19\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"120.19\" dy=\"0.00\">✂️ Tokenization</tspan><tspan x=\"120.19\" dy=\"21.00\">&lt;i&gt;cut the text&lt;/i&gt;</tspan></text><rect x=\"1053.63\" y=\"8.00\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ccff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1178.80\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1178.80\" dy=\"0.00\">📐 Word2Vec</tspan><tspan x=\"1178.80\" dy=\"21.00\">&lt;i&gt;meaning vectors&lt;/i&gt;</tspan></text></svg></div>\n<p>The narrative of this post: <strong>&quot;First you cut the text into pieces, then you count, then you understand.&quot;</strong> Simple? We'll see ;-) Let's start with the cutting.</p>\n<hr />\n<h2><a href=\"#tokenization---how-text-gets-split-into-pieces\" aria-hidden=\"true\" class=\"anchor\" id=\"tokenization---how-text-gets-split-into-pieces\"></a>Tokenization - how text gets split into pieces</h2>\n<h3><a href=\"#the-problem-a-computer-doesnt-see-words\" aria-hidden=\"true\" class=\"anchor\" id=\"the-problem-a-computer-doesnt-see-words\"></a>The problem: a computer doesn't see words</h3>\n<p>Imagine you're a computer. Someone shows you text:</p>\n<blockquote>\n<p>&quot;Alice has a cat.&quot;</p>\n</blockquote>\n<p>What do you see? Letters? Words? No. You see a sequence of bytes: <code>41 6c 69 63 65 20 68 61 73 20 61 20 63 61 74 2e</code>. Zero idea where one word starts and another ends. Zero idea that &quot;cat&quot; is an animal and not three random characters.</p>\n<p>For a computer to do anything with text, it first has to <strong>cut it into pieces</strong>. And that process is called <strong>tokenization</strong>.</p>\n<p>Tokenization is <strong>step zero</strong>. Without it there's no TF-IDF, no n-grams, no embeddings, no LLM. Everything starts with cutting.</p>\n<h3><a href=\"#the-naive-approach-split-on-spaces\" aria-hidden=\"true\" class=\"anchor\" id=\"the-naive-approach-split-on-spaces\"></a>The naive approach: split on spaces</h3>\n<p>The simplest idea: split the text on spaces.</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">&quot;Alice has a cat.&quot; -&gt; [&quot;Alice&quot;, &quot;has&quot;, &quot;a&quot;, &quot;cat.&quot;]\n</code></pre>\n<p>Did you notice? &quot;cat.&quot; has a period glued to it. That's not the word &quot;cat&quot; - it's the word &quot;cat&quot; with punctuation. And what about texts like these:</p>\n<ul>\n<li>&quot;un-believ-able&quot; - one word or three?</li>\n<li>&quot;Hi!&quot; - word + punctuation?</li>\n<li>&quot;New York&quot; - one word or two?</li>\n<li>&quot;:) &quot; - a word? a symbol? an emotion?</li>\n</ul>\n<p>In short: <strong>splitting on spaces doesn't work</strong>. The world is too complicated for such simple rules.</p>\n<h3><a href=\"#token--word--morpheme\" aria-hidden=\"true\" class=\"anchor\" id=\"token--word--morpheme\"></a>Token != word != morpheme</h3>\n<p>In the <a href=\"linguistic-features-and-llm.html\">first post</a> we met morphemes - the smallest meaningful units. &quot;Unhappiness&quot; is three morphemes: &quot;un-happy-ness&quot;. And now note: <strong>a token is not the same as a morpheme.</strong></p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"534.2058\" height=\"332.00266\" viewBox=\"0 0 534.2058 332.00266\"><rect x=\"0\" y=\"0\" width=\"534.2058\" height=\"332.00266\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"484.25\" height=\"139.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"250.13\" y=\"35.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"250.13\" dy=\"0.00\">A linguist sees:</tspan></text><rect x=\"8.00\" y=\"197.50\" width=\"510.21\" height=\"118.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"263.10\" y=\"225.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"263.10\" dy=\"0.00\">GPT-4o sees (BPE tokens):</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 199.170,84.501 L 249.170,84.501\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(249.17 84.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 199.170,263.501 L 249.170,263.501\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(249.17 263.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"44.00\" y=\"59.00\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"121.58\" y=\"88.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"121.58\" dy=\"0.00\">unhappiness</tspan></text><rect x=\"249.17\" y=\"48.50\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"352.71\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"352.71\" dy=\"0.00\">un + happy + ness</tspan><tspan x=\"352.71\" dy=\"21.00\">&lt;i&gt;morphemes&lt;/i&gt;</tspan></text><rect x=\"44.00\" y=\"238.00\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"121.58\" y=\"267.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"121.58\" dy=\"0.00\">unhappiness</tspan></text><rect x=\"249.17\" y=\"238.00\" width=\"233.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"365.69\" y=\"267.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"365.69\" dy=\"0.00\">un + h + app + iness</tspan></text></svg></div>\n<p>A token is simply <strong>a piece of text</strong> determined by the tokenizer. It can be a whole word, a part of a word, or a single character. It depends on the algorithm.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Three levels of cutting text:</strong></p>\n<ul>\n<li><strong>Word</strong> - the unit you intuitively &quot;feel&quot; (separated by spaces)</li>\n<li><strong>Morpheme</strong> - the smallest MEANINGFUL unit in a language (un-, happy-, -ness)</li>\n<li><strong>Token</strong> - a piece of text determined by a computer ALGORITHM (un, h, app, iness)</li>\n</ul>\n</div>\n<h3><a href=\"#bpe---byte-pair-encoding\" aria-hidden=\"true\" class=\"anchor\" id=\"bpe---byte-pair-encoding\"></a>BPE - Byte Pair Encoding</h3>\n<p>And here comes <strong>BPE (Byte Pair Encoding)</strong> - the most popular tokenization algorithm, used by GPT-2, GPT-3, GPT-4, Llama, and many other models.</p>\n<p>The idea of BPE can be reduced to one sentence: <strong>find the most frequent pair of characters and merge it into one token. And repeat.</strong></p>\n<p>Sounds simple? Because it is simple ;-) Let's see it on an example.</p>\n<h4><a href=\"#bpe-step-by-step\" aria-hidden=\"true\" class=\"anchor\" id=\"bpe-step-by-step\"></a>BPE step by step</h4>\n<p>We have a small corpus with five English words and their frequencies:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">&quot;low&quot;  ×10     &quot;lower&quot;  ×5      &quot;newest&quot;  ×12\n&quot;widest&quot;  ×4    &quot;new&quot;  ×5\n</code></pre>\n<p><strong>Step 0:</strong> We split everything into single characters:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">l o w       ×10     l o w e r       ×5      n e w e s t       ×12\nw i d e s t  ×4     n e w           ×5\n</code></pre>\n<p>Our starting dictionary is: <code>[&quot;d&quot;, &quot;e&quot;, &quot;i&quot;, &quot;l&quot;, &quot;n&quot;, &quot;o&quot;, &quot;r&quot;, &quot;s&quot;, &quot;t&quot;, &quot;w&quot;]</code> - simply all unique characters.</p>\n<p><strong>Step 1:</strong> We find the most frequent pair of adjacent characters:</p>\n<ul>\n<li>(e, s) appears in &quot;newest&quot; (12) and &quot;widest&quot; (4) = <strong>16 times</strong> &lt;- winner!</li>\n<li>(n, e) appears in &quot;newest&quot; (12) and &quot;new&quot; (5) = 17 times</li>\n<li>(l, o) appears in &quot;low&quot; (10) and &quot;lower&quot; (5) = 15 times</li>\n</ul>\n<p>Wait, let's recount. (n, e): &quot;newest&quot; (12) + &quot;new&quot; (5) = 17. Actually (n,e) = <strong>17 times</strong> &lt;- winner!</p>\n<p>Let's merge (n, e) -&gt; <strong>&quot;ne&quot;</strong>. Our dictionary grows by one token:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Dictionary: [&quot;d&quot;, &quot;e&quot;, &quot;i&quot;, &quot;l&quot;, &quot;n&quot;, &quot;o&quot;, &quot;r&quot;, &quot;s&quot;, &quot;t&quot;, &quot;w&quot;, &quot;ne&quot;]\n\nl o w       ×10     l o w e r       ×5      ne w e s t        ×12\nw i d e s t  ×4     ne w            ×5\n</code></pre>\n<p><strong>Step 2:</strong> We look for the most frequent pair again:</p>\n<ul>\n<li>(ne, w) appears in &quot;newest&quot; (12) and &quot;new&quot; (5) = <strong>17 times</strong> &lt;- winner!</li>\n<li>(e, s) appears in &quot;newest&quot; (12) and &quot;widest&quot; (4) = 16 times</li>\n<li>(l, o) appears in &quot;low&quot; (10) and &quot;lower&quot; (5) = 15 times</li>\n</ul>\n<p>Merge (ne, w) -&gt; <strong>&quot;new&quot;</strong>:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Dictionary: [..., &quot;ne&quot;, &quot;new&quot;]\n\nl o w       ×10     l o w e r       ×5      new e s t         ×12\nw i d e s t  ×4     new             ×5\n</code></pre>\n<p><strong>Step 3:</strong> The most frequent pair is now (e, s) = 16 times. Merge -&gt; <strong>&quot;es&quot;</strong>:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Dictionary: [..., &quot;ne&quot;, &quot;new&quot;, &quot;es&quot;]\n\nl o w       ×10     l o w e r       ×5      new es t          ×12\nw i d es t   ×4     new             ×5\n</code></pre>\n<p><strong>Step 4:</strong> The most frequent pair is (l, o) = 15 times. Merge -&gt; <strong>&quot;lo&quot;</strong>:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Dictionary: [..., &quot;ne&quot;, &quot;new&quot;, &quot;es&quot;, &quot;lo&quot;]\n\nlo w        ×10     lo w e r        ×5      new es t          ×12\nw i d es t   ×4     new             ×5\n</code></pre>\n<p><strong>Step 5:</strong> The most frequent pair is (lo, w) = 15 times. Merge -&gt; <strong>&quot;low&quot;</strong>:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Dictionary: [..., &quot;ne&quot;, &quot;new&quot;, &quot;es&quot;, &quot;lo&quot;, &quot;low&quot;]\n\nlow         ×10     lo w e r        ×5      new es t          ×12\nw i d es t   ×4     new             ×5\n</code></pre>\n<p>And so on, until we reach the target vocabulary size. In real models:</p>\n<ul>\n<li><strong>GPT-2</strong> has a vocabulary of <strong>50 257</strong> tokens (256 bytes + 50 000 merges + 1 special)</li>\n<li><strong>GPT-4/o</strong> has a vocabulary of ~<strong>100 000</strong> tokens</li>\n<li><strong>Llama 3</strong> also uses around ~<strong>100 000</strong> tokens</li>\n</ul>\n<h3><a href=\"#when-is-the-tokenizer-used\" aria-hidden=\"true\" class=\"anchor\" id=\"when-is-the-tokenizer-used\"></a>When is the tokenizer used?</h3>\n<p>That's an important question, and the answer is: <strong>always. At both stages.</strong></p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"2403.962\" height=\"270.13962\" viewBox=\"0 0 2403.962 270.13962\"><rect x=\"0\" y=\"0\" width=\"2403.962\" height=\"270.13962\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"1007.76\" y=\"108.81\" width=\"1380.20\" height=\"145.33\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"1697.86\" y=\"136.31\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1697.86\" dy=\"0.00\">PROMPTING (inference)</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"919.76\" height=\"145.14\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"467.88\" y=\"35.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"467.88\" dy=\"0.00\">TRAINING</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 255.081,97.631 L 279.081,97.631\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(279.08 97.63) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 442.902,87.087 L 460.402,87.087 L 449.402,84.001 L 466.902,84.001\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(466.90 84.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 622.072,74.011 L 646.072,74.011\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(646.07 74.01) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 1220.233,198.631 L 1244.233,198.631\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1244.23 198.63) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 1408.055,188.087 L 1425.555,188.087 L 1414.555,185.001 L 1432.055,185.001\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1432.05 185.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 1587.224,175.011 L 1611.225,175.011\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1611.22 175.01) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 1818.305,174.925 L 1842.305,174.925\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1842.31 174.92) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 2032.082,174.836 L 2056.082,174.836\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(2056.08 174.84) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-8\" class=\"edgePath\" data-edge-id=\"edge-8\" d=\"M 2193.948,174.815 L 2217.948,174.815\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(2217.95 174.81) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-9\" class=\"edgePath\" data-edge-id=\"edge-9\" d=\"M 441.902,123.122 L 441.902,125.872 Q 441.902,128.122 444.152,128.122 L 1235.233,128.122 Q 1245.233,128.122 1245.233,138.122 L 1245.233,173.122\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1245.23 173.12) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-9\" data-label-kind=\"center\" x=\"824.68\" y=\"130.12\" width=\"117.77\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-9\" data-label-kind=\"center\"><text x=\"883.57\" y=\"147.82\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"883.57\" dy=\"0.00\">&quot;the same!&quot;</tspan></text></g><rect x=\"1047.76\" y=\"173.14\" width=\"172.47\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1134.00\" y=\"202.14\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1134.00\" dy=\"0.00\">💬 Your prompt</tspan></text><rect x=\"2056.08\" y=\"149.32\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"2125.02\" y=\"178.32\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"2125.02\" dy=\"0.00\">📤 Decoder</tspan></text><rect x=\"2217.95\" y=\"149.31\" width=\"130.01\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"2282.96\" y=\"178.31\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"2282.96\" dy=\"0.00\">💬 Answer</tspan></text><rect x=\"1432.05\" y=\"149.52\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1509.64\" y=\"178.52\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1509.64\" dy=\"0.00\">🔢 Token IDs</tspan></text><rect x=\"1611.22\" y=\"149.50\" width=\"207.08\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1714.76\" y=\"178.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1714.76\" dy=\"0.00\">🤖 Model generates</tspan></text><rect x=\"1842.31\" y=\"149.35\" width=\"189.78\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1937.19\" y=\"178.35\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1937.19\" dy=\"0.00\">🔢 New token IDs</tspan></text><rect x=\"1244.23\" y=\"173.12\" width=\"163.82\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1326.14\" y=\"202.12\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1326.14\" dy=\"0.00\">✂️ Tokenizer</tspan></text><rect x=\"48.00\" y=\"72.14\" width=\"207.08\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"151.54\" y=\"101.14\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"151.54\" dy=\"0.00\">📚 Training corpus</tspan></text><rect x=\"466.90\" y=\"48.52\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"544.49\" y=\"77.52\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"544.49\" dy=\"0.00\">🔢 Token IDs</tspan></text><rect x=\"646.07\" y=\"48.50\" width=\"241.69\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"766.92\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"766.92\" dy=\"0.00\">🧠 You train the model</tspan></text><rect x=\"279.08\" y=\"72.12\" width=\"163.82\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"360.99\" y=\"101.12\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"360.99\" dy=\"0.00\">✂️ Tokenizer</tspan></text></svg></div>\n<ol>\n<li>\n<p><strong>Training:</strong> first you train the tokenizer on a huge corpus (it learns which pairs to merge). Then you tokenize the ENTIRE training corpus into IDs. The model learns on those IDs.</p>\n</li>\n<li>\n<p><strong>Prompting:</strong> when you write to ChatGPT, your text goes through the <strong>SAME</strong> tokenizer -&gt; IDs -&gt; the model generates new IDs -&gt; a decoder turns them back into text.</p>\n</li>\n</ol>\n<p>The key point: <strong>the tokenizer is trained separately, before the model.</strong> Then it's &quot;frozen&quot; - it never changes again. GPT-2 has its tokenizer (a 50K vocabulary), GPT-4 has its own (a 100K vocabulary). And that's the reason Polish gets cut up worse in GPT-2 - because GPT-2's <strong>tokenizer</strong> was trained mainly on English, so few Polish character sequences got merged. The model itself might &quot;understand&quot; Polish better, but the tokenizer already cut the text into tiny pieces.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>An experiment for you:</strong> Go to <a href=\"https://tiktokenizer.vercel.app/\">tiktokenizer.vercel.app</a>, type some Polish text and see how the GPT-2 model cuts it into tokens. You'll see that Polish characters (a, e, l, s, c with diacritics) often take up 2-3 tokens! Because GPT-2 was trained mainly on English, Polish is &quot;exotic&quot; to it.</p>\n</div>\n<h3><a href=\"#different-models---different-cuts\" aria-hidden=\"true\" class=\"anchor\" id=\"different-models---different-cuts\"></a>Different models - different cuts</h3>\n<p>The key thing: <strong>every model has its own tokenizer</strong>. The same text can be cut completely differently:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>import</a-k> <a-v>tiktoken</a-v>\n\n<a-v>text</a-v> <a-o>=</a-o> <a-s>&quot;Incredibly happy&quot;</a-s>\n\n<a-v>gpt2</a-v> <a-o>=</a-o> <a-v>tiktoken</a-v>.<a-pr>get_encoding</a-pr>(<a-s>&quot;gpt2&quot;</a-s>)\n<a-v>gpt4</a-v> <a-o>=</a-o> <a-v>tiktoken</a-v>.<a-pr>get_encoding</a-pr>(<a-s>&quot;cl100k_base&quot;</a-s>)\n\n<a-f>print</a-f>(<a-s>&quot;GPT-2:&quot;</a-s>, <a-v>gpt2</a-v>.<a-pr>encode</a-pr>(<a-v>text</a-v>))\n<a-f>print</a-f>(<a-s>&quot;GPT-4:&quot;</a-s>, <a-v>gpt4</a-v>.<a-pr>encode</a-pr>(<a-v>text</a-v>))\n\n<a-f>print</a-f>(<a-s>&quot;GPT-2:&quot;</a-s>, [<a-v>gpt2</a-v>.<a-pr>decode</a-pr>([<a-v>t</a-v>]) <a-k>for</a-k> <a-v>t</a-v> <a-o>in</a-o> <a-v>gpt2</a-v>.<a-pr>encode</a-pr>(<a-v>text</a-v>)])\n<a-f>print</a-f>(<a-s>&quot;GPT-4:&quot;</a-s>, [<a-v>gpt4</a-v>.<a-pr>decode</a-pr>([<a-v>t</a-v>]) <a-k>for</a-k> <a-v>t</a-v> <a-o>in</a-o> <a-v>gpt4</a-v>.<a-pr>encode</a-pr>(<a-v>text</a-v>)])</code></pre>\n<p>GPT-2 will probably cut the text into many small fragments (because it doesn't &quot;know&quot; it well), and GPT-4 will do it much more efficiently (because it has seen more of this text).</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1071.626\" height=\"360.5\" viewBox=\"0 0 1071.626 360.5\"><rect x=\"0\" y=\"0\" width=\"1071.626\" height=\"360.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"32.00\" width=\"330.29\" height=\"312.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"173.15\" y=\"59.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"173.15\" dy=\"0.00\">GPT-2 (English BPE):</tspan></text><rect x=\"388.29\" y=\"32.00\" width=\"312.99\" height=\"312.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"544.79\" y=\"59.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"544.79\" dy=\"0.00\">GPT-4o (multilingual BPE):</tspan></text><rect x=\"751.29\" y=\"8.00\" width=\"304.34\" height=\"315.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"903.46\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"903.46\" dy=\"0.00\">Polish RoBERTa (Polish</tspan><tspan x=\"903.46\" dy=\"21.00\">SentencePiece):</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 173.162,144.500 L 173.162,194.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(173.16 194.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 544.790,144.500 L 544.790,194.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(544.79 194.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 903.443,144.500 L 903.443,194.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(903.44 194.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"69.64\" y=\"72.50\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"173.18\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"173.18\" dy=\"0.00\">Nieprawdopodobnie</tspan><tspan x=\"173.18\" dy=\"21.00\">szczęśliwy</tspan></text><rect x=\"35.00\" y=\"194.50\" width=\"276.29\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"173.15\" y=\"223.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"173.15\" dy=\"0.00\">N + ie + p + raw + d + op</tspan><tspan x=\"173.15\" dy=\"21.00\">+ od + ob + nie + s + z +</tspan><tspan x=\"173.15\" dy=\"21.00\">cz + ... + li + wy</tspan><tspan x=\"173.15\" dy=\"21.00\">&lt;i&gt;18 tokens!&lt;/i&gt;</tspan></text><rect x=\"441.25\" y=\"72.50\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"544.79\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"544.79\" dy=\"0.00\">Nieprawdopodobnie</tspan><tspan x=\"544.79\" dy=\"21.00\">szczęśliwy</tspan></text><rect x=\"415.29\" y=\"194.50\" width=\"258.99\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"544.79\" y=\"223.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"544.79\" dy=\"0.00\">Nie + p + rawd + op +</tspan><tspan x=\"544.79\" dy=\"21.00\">odob + nie + szcz + ę +</tspan><tspan x=\"544.79\" dy=\"21.00\">śli + wy</tspan><tspan x=\"544.79\" dy=\"21.00\">&lt;i&gt;10 tokens&lt;/i&gt;</tspan></text><rect x=\"799.89\" y=\"72.50\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"903.43\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"903.43\" dy=\"0.00\">Nieprawdopodobnie</tspan><tspan x=\"903.43\" dy=\"21.00\">szczęśliwy</tspan></text><rect x=\"778.29\" y=\"194.50\" width=\"250.34\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"903.46\" y=\"223.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"903.46\" dy=\"0.00\">Nie + prawdopodobnie +</tspan><tspan x=\"903.46\" dy=\"21.00\">szczęśliwy</tspan><tspan x=\"903.46\" dy=\"21.00\">&lt;i&gt;3 tokens!&lt;/i&gt;</tspan></text></svg></div>\n<p>The example above uses Polish (&quot;Nieprawdopodobnie szczęśliwy&quot; = &quot;Incredibly happy&quot;) because it perfectly illustrates how badly a tokenizer trained on one language handles another.</p>\n<h3><a href=\"#what-about-polish-tokenizers\" aria-hidden=\"true\" class=\"anchor\" id=\"what-about-polish-tokenizers\"></a>What about Polish tokenizers?</h3>\n<p>There are models trained specifically on Polish text - and their tokenizers cut Polish <strong>much</strong> better:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>transformers</a-v> <a-k>import</a-k> <a-cr>AutoTokenizer</a-cr>\n\n<a-v>text</a-v> <a-o>=</a-o> <a-s>&quot;Nieprawdopodobnie szczęśliwy&quot;</a-s>\n\n<a-v>herbert</a-v> <a-o>=</a-o> <a-cr>AutoTokenizer</a-cr>.<a-pr>from_pretrained</a-pr>(<a-s>&quot;allegro/herbert-base-cased&quot;</a-s>)\n<a-f>print</a-f>(<a-s>&quot;HerBERT (Allegro, Polish WordPiece):&quot;</a-s>, <a-v>herbert</a-v>.<a-pr>tokenize</a-pr>(<a-v>text</a-v>))\n\n<a-v>roberta</a-v> <a-o>=</a-o> <a-cr>AutoTokenizer</a-cr>.<a-pr>from_pretrained</a-pr>(<a-s>&quot;sdadas/polish-roberta-base-v2&quot;</a-s>)\n<a-f>print</a-f>(<a-s>&quot;Polish RoBERTa (Polish SentencePiece):&quot;</a-s>, <a-v>roberta</a-v>.<a-pr>tokenize</a-pr>(<a-v>text</a-v>))</code></pre>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">HerBERT (Allegro, Polish WordPiece):  ['Nie', 'prawdopodobnie&lt;/w&gt;', 'szczęśliwy&lt;/w&gt;']  -&gt; 3 tokens\nPolish RoBERTa (Polish SentencePiece): ['▁Nie', 'prawdopodobnie', '▁szczęśliwy']        -&gt; 3 tokens\n</code></pre>\n<p>Three tokens! &quot;prawdopodobnie&quot; and &quot;szczęśliwy&quot; are single tokens for a Polish tokenizer. Because that tokenizer &quot;saw&quot; these words so many times on a Polish corpus that it merged them into whole units.</p>\n<p>Two Polish tokenizers worth knowing:</p>\n<table>\n<thead>\n<tr>\n<th>Tokenizer</th>\n<th>Creator</th>\n<th>Algorithm</th>\n<th>Implemented in</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>HerBERT</strong></td>\n<td>Allegro</td>\n<td>WordPiece</td>\n<td>Polish BERT on the KGR10 corpus</td>\n</tr>\n<tr>\n<td><strong>Polish RoBERTa</strong></td>\n<td>sdadas</td>\n<td>SentencePiece (Unigram)</td>\n<td>Polish RoBERTa on a large corpus</td>\n</tr>\n</tbody>\n</table>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Why do Polish models cut better?</strong> Because their tokenizers were trained <strong>on Polish text</strong>. &quot;Prawdopodobnie&quot; appeared in the Polish corpus thousands of times, so BPE/SentencePiece merged it into one token. GPT-2 saw mostly English, so &quot;prawdopodobnie&quot; never got merged - and it cuts it into pieces. This is also why GPT-4o (trained on a much more multilingual corpus) cuts Polish better than GPT-2 - but still worse than typically Polish models.</p>\n</div>\n<h3><a href=\"#build-your-own-tokenizer\" aria-hidden=\"true\" class=\"anchor\" id=\"build-your-own-tokenizer\"></a>Build your own tokenizer!</h3>\n<p>Now that we understand how BPE works, let's try to train <strong>our own tokenizer</strong>. We'll use the <code>tokenizers</code> library from HuggingFace (not to be confused with <code>tiktoken</code>):</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>tokenizers</a-v> <a-k>import</a-k> <a-cr>Tokenizer</a-cr>\n<a-k>from</a-k> <a-v>tokenizers</a-v>.<a-v>models</a-v> <a-k>import</a-k> <a-co>BPE</a-co>\n<a-k>from</a-k> <a-v>tokenizers</a-v>.<a-v>trainers</a-v> <a-k>import</a-k> <a-cr>BpeTrainer</a-cr>\n<a-k>from</a-k> <a-v>tokenizers</a-v>.<a-v>pre_tokenizers</a-v> <a-k>import</a-k> <a-cr>Whitespace</a-cr>\n\n<a-v>tokenizer</a-v> <a-o>=</a-o> <a-f>Tokenizer</a-f>(<a-f>BPE</a-f>(<a-v>unk_token</a-v><a-o>=</a-o><a-s>&quot;[UNK]&quot;</a-s>))\n<a-v>tokenizer</a-v>.<a-pr>pre_tokenizer</a-pr> <a-o>=</a-o> <a-f>Whitespace</a-f>()\n\n<a-v>trainer</a-v> <a-o>=</a-o> <a-f>BpeTrainer</a-f>(<a-v>vocab_size</a-v><a-o>=</a-o><a-n>300</a-n>, <a-v>special_tokens</a-v><a-o>=</a-o>[<a-s>&quot;[UNK]&quot;</a-s>])\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;Alice has a cat and a dog&quot;</a-s>,\n    <a-s>&quot;The cat sits on the mat&quot;</a-s>,\n    <a-s>&quot;The dog runs in the park&quot;</a-s>,\n    <a-s>&quot;Alice has a cat and a cat and once more a cat&quot;</a-s>,\n    <a-s>&quot;The cat likes milk and the cat likes to sleep&quot;</a-s>,\n    <a-s>&quot;The dog likes to run in the park and chase the cat&quot;</a-s>,\n    <a-s>&quot;A happy cat is a cat that has lots of milk&quot;</a-s>,\n    <a-s>&quot;An incredibly happy dog runs in the park&quot;</a-s>,\n    <a-s>&quot;Happy Alice has a cat and a dog and a happy home&quot;</a-s>,\n    <a-s>&quot;A home is a place where a happy family lives&quot;</a-s>,\n]\n\n<a-v>tokenizer</a-v>.<a-pr>train_from_iterator</a-pr>(<a-v>corpus</a-v>, <a-v>trainer</a-v>)\n<a-f>print</a-f>(<a-s>f&quot;Vocabulary size: </a-s><a-p>{</a-p><a-v>tokenizer</a-v><a-eb>.</a-eb><a-pr>get_vocab_size</a-pr><a-eb>()</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)\n\n<a-v>test</a-v> <a-o>=</a-o> <a-s>&quot;Incredibly happy&quot;</a-s>\n<a-v>encoding</a-v> <a-o>=</a-o> <a-v>tokenizer</a-v>.<a-pr>encode</a-pr>(<a-v>test</a-v>)\n<a-f>print</a-f>(<a-s>f&#39;&quot;</a-s><a-p>{</a-p><a-v>test</a-v><a-p>}</a-p><a-s>&quot; -&gt; </a-s><a-p>{</a-p><a-v>encoding</a-v><a-eb>.</a-eb><a-pr>tokens</a-pr><a-p>}</a-p><a-s>&#39;</a-s>)</code></pre>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Vocabulary size: 130\n&quot;Incredibly happy&quot; -&gt; ['Incredibly', 'happy']\n</code></pre>\n<p><strong>Two tokens!</strong> Because our small corpus is in English - and &quot;Incredibly&quot; and &quot;happy&quot; appeared often enough for BPE to merge them into single tokens.</p>\n<p>But wait - what do those parameters in the code actually mean?</p>\n<table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>What it does</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong><code>vocab_size</code></strong></td>\n<td>The maximum number of tokens in the vocabulary. BPE will merge pairs until the vocabulary reaches this size. The bigger, the longer the tokens (whole words). The smaller, the smaller the pieces (single letters).</td>\n<td>GPT-2: 50 257, ours: 300</td>\n</tr>\n<tr>\n<td><strong><code>special_tokens</code></strong></td>\n<td>Tokens with a special meaning for the model. They're always in the vocabulary, regardless of training.</td>\n<td><code>[UNK]</code>, <code>&lt;PAD&gt;</code>, <code>&lt;S&gt;</code> (start), <code>&lt;/S&gt;</code> (end)</td>\n</tr>\n<tr>\n<td><strong><code>unk_token</code></strong></td>\n<td>The &quot;unknown&quot; token - replaces every character the tokenizer can't recognize. E.g. if an emoji appears in the text and the tokenizer doesn't have it in the vocabulary, it inserts <code>[UNK]</code>.</td>\n<td><code>[UNK]</code> = &quot;I don't know what this is&quot;</td>\n</tr>\n</tbody>\n</table>\n<p>A simple analogy: <code>vocab_size</code> is the thickness of your dictionary - how many entries fit in it. <code>unk_token</code> is the entry meaning &quot;no such word&quot;. And <code>special_tokens</code> are &quot;reserved pages&quot; - they're always in the dictionary, regardless of what you teach the tokenizer.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Experiment:</strong> Copy this code, change <code>vocab_size</code> to e.g. 50 and see what happens. You'll see that with a smaller vocabulary the tokenizer cuts words into smaller pieces - because it has less &quot;room&quot; for merges. That's exactly what we talked about: vocabulary size is a hyperparameter, and how finely the text gets cut depends on it.</p>\n</div>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Why does this matter?</strong> Because an LLM has a token limit in its context window. GPT-3 has 4K tokens, GPT-4 Turbo has 128K. But a &quot;token&quot; is not a &quot;word&quot;! In English ~1 token ~= 0.75 words. In a language poorly served by the tokenizer, it can be ~1 token ~= 0.4 words. So such text &quot;eats up&quot; more tokens and hits the limit faster.</p>\n</div>\n<h3><a href=\"#other-tokenization-algorithms\" aria-hidden=\"true\" class=\"anchor\" id=\"other-tokenization-algorithms\"></a>Other tokenization algorithms</h3>\n<p>BPE isn't the only player in town. Here's a quick comparison:</p>\n<table>\n<thead>\n<tr>\n<th>Algorithm</th>\n<th>Who uses it</th>\n<th>How it works</th>\n<th>Key difference</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>BPE</strong></td>\n<td>GPT, Llama, many others</td>\n<td>Merges the most frequent pair</td>\n<td>Simple, bottom-up</td>\n</tr>\n<tr>\n<td><strong>WordPiece</strong></td>\n<td>BERT, DistilBERT, Electra</td>\n<td>Merges the pair with the highest &quot;score&quot;</td>\n<td>Score = freq(pair) / (freq(a) x freq(b))</td>\n</tr>\n<tr>\n<td><strong>Unigram</strong></td>\n<td>T5, Pegasus, ALBERT</td>\n<td>Starts from a large vocabulary, removes the least useful</td>\n<td>Probabilistic, can yield different tokenizations</td>\n</tr>\n<tr>\n<td><strong>SentencePiece</strong></td>\n<td>Multilingual models</td>\n<td>BPE or Unigram on raw text (even without spaces!)</td>\n<td>Works with languages without spaces (Chinese, Japanese)</td>\n</tr>\n</tbody>\n</table>\n<p>The difference between BPE and WordPiece is subtle: BPE simply merges the <strong>most frequent</strong> pair. WordPiece merges the pair that is <strong>most surprising</strong> - i.e. one that appears together more often than would follow from the frequency of the individual elements. It's a bit like a relationship that is &quot;more than the sum of its parts&quot; ;-)</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>A callback to post 1:</strong> Remember when we said Polish morphology is a nightmare for an LLM? 7 cases, inflection, lots of endings... Well, now you see why. The tokenizer doesn't &quot;know&quot; that &quot;domu&quot;, &quot;domowi&quot;, &quot;domem&quot; are inflections of the same word. To it they're just different character sequences. &quot;Understanding&quot; the relationship between forms - that's something the model has to learn on its own, during training.</p>\n</div>\n<h3><a href=\"#quiz-how-will-bpe-cut-this\" aria-hidden=\"true\" class=\"anchor\" id=\"quiz-how-will-bpe-cut-this\"></a>Quiz: how will BPE cut this?<sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\" data-footnote-ref>1</a></sup></h3>\n<p>We have our merges from the example above: n+e-&gt;ne, ne+w-&gt;new, e+s-&gt;es, l+o-&gt;lo, lo+w-&gt;low. How will BPE split these new words?</p>\n<ol>\n<li>&quot;lowest&quot; (assuming it wasn't in the corpus)</li>\n<li>&quot;newer&quot; (assuming it wasn't in the corpus)</li>\n<li>&quot;widower&quot; (a real English word!)</li>\n</ol>\n<hr />\n<h2><a href=\"#corpora-bag-of-words-and-tf-idf\" aria-hidden=\"true\" class=\"anchor\" id=\"corpora-bag-of-words-and-tf-idf\"></a>Corpora, Bag-of-Words, and TF-IDF</h2>\n<h3><a href=\"#what-is-a-corpus\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-a-corpus\"></a>What is a corpus?</h3>\n<p>OK, we have tokens. But how does the tokenizer know which character pairs to merge? From a <strong>corpus</strong>! BPE learns the most frequent combinations from text. And to do anything with tokens - count them, find patterns, train a model - we also need a corpus.</p>\n<p>A <strong>corpus</strong> is simply a collection of texts. It can be:</p>\n<ul>\n<li>the set of all Wikipedia articles</li>\n<li>a set of product reviews from Amazon</li>\n<li>the emails in your inbox</li>\n<li>a set of all posts on Reddit (knock on wood)</li>\n</ul>\n<p>Each individual text in a corpus we call a <strong>document</strong>. Simple?</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"857.71515\" height=\"260\" viewBox=\"0 0 857.71515 260\"><rect x=\"0\" y=\"0\" width=\"857.71515\" height=\"260\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 300.228,100.000 L 290.603,100.000 Q 282.728,100.000 278.523,106.658 L 254.090,145.342 Q 249.884,152.000 242.009,152.000 L 232.384,152.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(232.38 152.00) rotate(180.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 407.816,101.000 L 407.816,151.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(407.82 151.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 515.961,100.000 L 525.586,100.000 Q 533.461,100.000 537.566,106.720 L 561.119,145.280 Q 565.224,152.000 573.099,152.000 L 582.724,152.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(582.72 152.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"300.23\" y=\"8.00\" width=\"215.73\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"408.09\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"408.09\" dy=\"0.00\">📚 CORPUS</tspan><tspan x=\"408.09\" dy=\"21.00\">&lt;i&gt;a collection of</tspan><tspan x=\"408.09\" dy=\"21.00\">documents&lt;/i&gt;</tspan></text><rect x=\"8.00\" y=\"151.00\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"120.19\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"120.19\" dy=\"0.00\">📄 Document 1</tspan><tspan x=\"120.19\" dy=\"21.00\">This movie is great</tspan></text><rect x=\"282.38\" y=\"151.00\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"407.55\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"407.55\" dy=\"0.00\">📄 Document 2</tspan><tspan x=\"407.55\" dy=\"21.00\">This movie is terrible</tspan></text><rect x=\"582.72\" y=\"151.00\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"712.22\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"712.22\" dy=\"0.00\">📄 Document 3</tspan><tspan x=\"712.22\" dy=\"21.00\">Great book, I recommend</tspan><tspan x=\"712.22\" dy=\"21.00\">it</tspan></text></svg></div>\n<p>And these are exactly the datasets on which real models are trained - both tokenizers and the models themselves:</p>\n<table>\n<thead>\n<tr>\n<th>Corpus</th>\n<th>What it contains</th>\n<th>Size</th>\n<th>Fun fact</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Wikitext</strong></td>\n<td>Articles from (English) Wikipedia</td>\n<td>~500 MB</td>\n<td>A standard benchmark for evaluating language models</td>\n</tr>\n<tr>\n<td><strong>Wiki-40B</strong></td>\n<td>Wikipedia in 59 languages (including Polish!)</td>\n<td>~40 GB</td>\n<td>The first step of many multilingual models</td>\n</tr>\n<tr>\n<td><strong>EuroParl</strong></td>\n<td>Transcriptions from the EU parliament (21 languages)</td>\n<td>~2 GB</td>\n<td>High-quality official texts, great for translation</td>\n</tr>\n<tr>\n<td><strong>Common Crawl</strong></td>\n<td>Dumps of web content</td>\n<td><strong>petabytes</strong> (PB!)</td>\n<td>The largest publicly available web corpus. Most LLMs use it</td>\n</tr>\n<tr>\n<td><strong>OpenWebText</strong></td>\n<td>A copy of Reddit links with &gt;3 upvotes</td>\n<td>~38 GB</td>\n<td>GPT-2 was trained on it. Filtered &quot;quality&quot; from Reddit</td>\n</tr>\n<tr>\n<td><strong>The Pile</strong></td>\n<td>A mix of 22 sources (arXiv, GitHub, Wikipedia, books...)</td>\n<td>~825 GB</td>\n<td>Created by EleutherAI as a &quot;do-everything&quot; dataset</td>\n</tr>\n<tr>\n<td><strong>RedPajama</strong></td>\n<td>An open replica of LLaMA's training data</td>\n<td>~1.2 TB</td>\n<td>That's why LLaMA is so good - trained on a huge, diverse set</td>\n</tr>\n<tr>\n<td><strong>OSCAR</strong></td>\n<td>Web dumps, filtered by language</td>\n<td>~6.5 TB</td>\n<td>Has separate subsets for each language, including Polish OSCAR</td>\n</tr>\n</tbody>\n</table>\n<p>And Polish corpora? Here are the most important ones:</p>\n<ul>\n<li><strong>NKJP</strong> (Narodowy Korpus Jezyka Polskiego / National Corpus of Polish) - millions of Polish texts, a balanced set from various fields</li>\n<li><strong>Polish-ROBERTa corpus</strong> - ~20 GB of Polish text from the web, Polish RoBERTa was trained on it</li>\n<li><strong>OSCAR (the Polish part)</strong> - Polish pages from Common Crawl, several hundred GB</li>\n<li><strong>Polish Wikipedia</strong> - ~2 GB of articles, often the starting point for Polish models</li>\n</ul>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1194.7957\" height=\"741.5\" viewBox=\"0 0 1194.7957 741.5\"><rect x=\"0\" y=\"0\" width=\"1194.7957\" height=\"741.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"1170.80\" height=\"717.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"593.40\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"593.40\" dy=\"0.00\">Where LLM training data</tspan><tspan x=\"593.40\" dy=\"21.00\">comes from</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 289.688,363.000 L 299.313,363.000 Q 307.188,363.000 314.933,364.424 L 340.398,369.107 Q 348.143,370.531 356.018,370.531 L 365.643,370.531\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(365.64 370.53) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 220.473,460.500 L 230.098,460.500 Q 237.973,460.500 245.276,457.552 L 340.841,418.978 Q 348.143,416.031 356.018,416.031 L 365.643,416.031\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(365.64 416.03) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 263.732,143.500 L 330.643,143.500 Q 340.643,143.500 340.643,153.500 L 340.643,315.031 Q 340.643,325.031 350.643,325.031 L 365.643,325.031\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(365.64 325.03) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 281.036,603.500 L 355.643,603.500 Q 365.643,603.500 365.643,593.500 L 365.643,416.031\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(365.64 416.03) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 315.643,265.500 L 315.643,325.265 Q 315.643,335.265 325.643,335.265 L 361.038,335.265 Q 365.643,335.265 365.643,330.660 L 365.643,325.031\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(365.64 325.03) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 572.724,370.661 L 622.724,370.661\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(622.72 370.66) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 847.108,338.791 L 857.712,338.791 Q 864.608,338.791 871.358,340.203 L 872.858,340.516 Q 879.608,341.927 886.504,341.927 L 897.108,341.927\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(897.11 341.93) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 847.108,402.498 L 897.108,402.498\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(897.11 402.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"48.00\" y=\"194.50\" width=\"267.64\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"181.82\" y=\"223.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"181.82\" dy=\"0.00\">📄 ArXiv</tspan><tspan x=\"181.82\" dy=\"21.00\">&lt;i&gt;scientific papers&lt;/i&gt;</tspan></text><rect x=\"48.00\" y=\"602.50\" width=\"233.04\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"164.52\" y=\"631.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"164.52\" dy=\"0.00\">📖 Books</tspan><tspan x=\"164.52\" dy=\"21.00\">&lt;i&gt;Project Gutenberg</tspan><tspan x=\"164.52\" dy=\"21.00\">etc.&lt;/i&gt;</tspan></text><rect x=\"48.00\" y=\"316.50\" width=\"241.69\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"168.84\" y=\"345.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"168.84\" dy=\"0.00\">🌐 Common Crawl</tspan><tspan x=\"168.84\" dy=\"21.00\">&lt;i&gt;petabytes from the</tspan><tspan x=\"168.84\" dy=\"21.00\">web&lt;/i&gt;</tspan></text><rect x=\"622.72\" y=\"324.29\" width=\"224.38\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"734.92\" y=\"353.29\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"734.92\" dy=\"0.00\">📊 Clean corpus</tspan><tspan x=\"734.92\" dy=\"21.00\">&lt;i&gt;hundreds of GB -</tspan><tspan x=\"734.92\" dy=\"21.00\">TB&lt;/i&gt;</tspan></text><rect x=\"48.00\" y=\"72.50\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"155.87\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"155.87\" dy=\"0.00\">💻 GitHub</tspan><tspan x=\"155.87\" dy=\"21.00\">&lt;i&gt;source code&lt;/i&gt;</tspan></text><rect x=\"897.11\" y=\"395.92\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"996.32\" y=\"424.92\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"996.32\" dy=\"0.00\">🧠 Model training</tspan></text><rect x=\"365.64\" y=\"324.03\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"469.18\" y=\"353.03\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"469.18\" dy=\"0.00\">🧹 Filtering</tspan><tspan x=\"469.18\" dy=\"21.00\">&lt;i&gt;removing spam,</tspan><tspan x=\"469.18\" dy=\"21.00\">duplicates&lt;/i&gt;</tspan></text><rect x=\"897.11\" y=\"294.92\" width=\"241.69\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1017.95\" y=\"323.92\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1017.95\" dy=\"0.00\">✂️ Tokenizer training</tspan></text><rect x=\"48.00\" y=\"459.50\" width=\"172.47\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"134.24\" y=\"488.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"134.24\" dy=\"0.00\">📚 Wikipedia</tspan><tspan x=\"134.24\" dy=\"21.00\">&lt;i&gt;49 GB, 59</tspan><tspan x=\"134.24\" dy=\"21.00\">languages&lt;/i&gt;</tspan></text></svg></div>\n<p>Key observation: <strong>the same corpus is used to train both the tokenizer and the model.</strong> First you train the tokenizer on the corpus (it learns which character pairs to merge), then you tokenize the whole corpus with that tokenizer, and on those tokens you train the model.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Why does this matter?</strong> If your corpus has little Polish text (e.g. GPT-2 trained mainly on English), the tokenizer won't merge Polish words, and the model won't learn Polish well. That's why Polish models (HerBERT, Polish RoBERTa) use corpora with a lot of Polish text - e.g. NKJP + Polish OSCAR + Polish Wikipedia.</p>\n</div>\n<h3><a href=\"#bag-of-words---a-bag-full-of-words\" aria-hidden=\"true\" class=\"anchor\" id=\"bag-of-words---a-bag-full-of-words\"></a>Bag-of-Words - a bag full of words</h3>\n<p>We have a corpus. Now we want to turn each document into <strong>numbers</strong> so the computer can do something with it.</p>\n<p>The simplest way: <strong>Bag-of-Words (BoW)</strong> - a bag of words. We count how many times each word appears in the document.</p>\n<p>Example. We have three short movie reviews:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Document 1: &quot;This movie is great&quot;\nDocument 2: &quot;This movie is terrible&quot;\nDocument 3: &quot;Great movie I recommend&quot;\n</code></pre>\n<p>We build a vocabulary of all unique words:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">{this, movie, is, great, terrible, i, recommend}\n</code></pre>\n<p>And now we turn each document into a vector of counts:</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>this</th>\n<th>movie</th>\n<th>is</th>\n<th>great</th>\n<th>terrible</th>\n<th>i</th>\n<th>recommend</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Doc 1</strong></td>\n<td>1</td>\n<td>1</td>\n<td>1</td>\n<td>1</td>\n<td>0</td>\n<td>0</td>\n<td>0</td>\n</tr>\n<tr>\n<td><strong>Doc 2</strong></td>\n<td>1</td>\n<td>1</td>\n<td>1</td>\n<td>0</td>\n<td>1</td>\n<td>0</td>\n<td>0</td>\n</tr>\n<tr>\n<td><strong>Doc 3</strong></td>\n<td>0</td>\n<td>1</td>\n<td>0</td>\n<td>1</td>\n<td>0</td>\n<td>1</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>\n<p>Each document is now just a sequence of numbers. The computer is happy.</p>\n<p>But we're not entirely ;-). Because notice the problem:</p>\n<blockquote>\n<p>Document 1: &quot;This movie is great&quot; -&gt; [1, 1, 1, 1, 0, 0, 0]\nDocument 2: &quot;This movie is terrible&quot; -&gt; [1, 1, 1, 0, 1, 0, 0]</p>\n</blockquote>\n<p>These vectors are almost identical! They differ in one position. Yet one says &quot;great&quot; and the other &quot;terrible&quot; - completely different meanings.</p>\n<p>And there's a second problem: &quot;Dog bites man&quot; and &quot;Man bites dog&quot; will give <strong>exactly the same</strong> BoW vector. BoW completely <strong>ignores word order</strong>.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>In inflected languages things look different.</strong> In a language with cases, &quot;The dog bites the man&quot; and &quot;The man bites the dog&quot; can look different because the word forms change. But in English, &quot;dog&quot; is always &quot;dog&quot; regardless of its role in the sentence - which is exactly why BoW can't distinguish &quot;dog bites man&quot; from &quot;man bites dog&quot;. This is that morphology from the <a href=\"linguistic-features-and-llm.html\">first post</a> that sometimes helps us and sometimes gets in the way ;-)</p>\n</div>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Bag-of-Words in a nutshell:</strong></p>\n<ul>\n<li>Plus: trivially simple, works fast</li>\n<li>Minus: ignores order, ignores meaning, ignores context</li>\n<li>Metaphor: you throw all the words into a bag, shake it, and see what falls out. The bag doesn't know what was first and what was last.</li>\n</ul>\n</div>\n<h3><a href=\"#bag-of-words-in-code\" aria-hidden=\"true\" class=\"anchor\" id=\"bag-of-words-in-code\"></a>Bag-of-Words in code</h3>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>feature_extraction</a-v>.<a-v>text</a-v> <a-k>import</a-k> <a-cr>CountVectorizer</a-cr>\n<a-k>import</a-k> <a-v>pandas</a-v> <a-k>as</a-k> <a-v>pd</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;This movie is great&quot;</a-s>,\n    <a-s>&quot;This movie is terrible&quot;</a-s>,\n    <a-s>&quot;Great movie I recommend&quot;</a-s>,\n]\n\n<a-v>vectorizer</a-v> <a-o>=</a-o> <a-f>CountVectorizer</a-f>()\n<a-co>X</a-co> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>fit_transform</a-pr>(<a-v>corpus</a-v>)\n\n<a-v>df</a-v> <a-o>=</a-o> <a-v>pd</a-v>.<a-pr>DataFrame</a-pr>(\n    <a-co>X</a-co>.<a-pr>toarray</a-pr>(),\n    <a-v>columns</a-v><a-o>=</a-o><a-v>vectorizer</a-v>.<a-pr>get_feature_names_out</a-pr>(),\n    <a-v>index</a-v><a-o>=</a-o>[<a-s>&quot;Doc 1&quot;</a-s>, <a-s>&quot;Doc 2&quot;</a-s>, <a-s>&quot;Doc 3&quot;</a-s>]\n)\n<a-f>print</a-f>(<a-v>df</a-v>)</code></pre>\n<p>Result:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">        great  i  is  movie  recommend  terrible  this\nDoc 1      1  0   1      1          0         0     1\nDoc 2      0  0   1      1          0         1     1\nDoc 3      1  1   0      1          1         0     0\n</code></pre>\n<p>Exactly the same table as above - only now generated by code. Notice: &quot;movie&quot; is everywhere (value 1 in every row), and &quot;terrible&quot; only in Document 2. That's the whole magic of BoW - simple counting.</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>Can BoW generate new texts?</strong> No. BoW is only a way of <strong>representing</strong> text (text -&gt; numbers). It's used to analyze, compare, and classify documents, but it doesn't generate anything new. It also can't predict what word should come after &quot;The cat sits on the...&quot;. To generate text, we need something that understands word <strong>order</strong> and can predict the next one. And that's exactly what we're getting to with n-grams and Markov chains ;-)</p>\n</div>\n<h3><a href=\"#tf-idf---what-if-not-all-words-are-equal\" aria-hidden=\"true\" class=\"anchor\" id=\"tf-idf---what-if-not-all-words-are-equal\"></a>TF-IDF - what if not all words are equal?</h3>\n<p>BoW treats every word the same. But <strong>not every word is equally important!</strong></p>\n<p>The word &quot;is&quot; appears in almost every English sentence. The word &quot;semiotics&quot; - rather rarely. Which is more informative? Obviously &quot;semiotics&quot; - because if you see it in a document, it tells you much more about its content than &quot;is&quot;.</p>\n<p>TF-IDF (Term Frequency - Inverse Document Frequency) is a way to capture that.</p>\n<p>Recall our corpus - three short movie reviews:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Document 1: &quot;This movie is great&quot;          (4 words)\nDocument 2: &quot;This movie is terrible&quot;       (4 words)\nDocument 3: &quot;Great movie I recommend&quot;      (3 words)\n</code></pre>\n<p>Let's compute TF-IDF for the word <strong>&quot;great&quot;</strong> in Document 1:</p>\n<p><strong>TF (Term Frequency)</strong> - how often the word appears in one document:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">TF(&quot;great&quot;, Document 1) = 1 / 4 = 0.25\n</code></pre>\n<p>(1 occurrence in a 4-word document)</p>\n<p><strong>IDF (Inverse Document Frequency)</strong> - how &quot;rare&quot; the word is across the whole corpus:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">IDF(&quot;great&quot;) = log(3 / 2) = 0.176\n</code></pre>\n<p>(3 documents in the corpus, 2 of them contain &quot;great&quot;)</p>\n<p><strong>TF-IDF</strong> = TF x IDF:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">TF-IDF(&quot;great&quot;, Document 1) = 0.25 x 0.176 = 0.044\n</code></pre>\n<p>And the word &quot;is&quot;, which is EVERYWHERE?</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">IDF(&quot;is&quot;) = log(3 / 2) = 0.176  (also in 2 of 3 documents)\nIDF(&quot;movie&quot;) = log(3 / 3) = 0      (in ALL documents!)\n</code></pre>\n<p>&quot;Movie&quot; gets <strong>zero</strong> in IDF! Because if a word is in every document, it carries no information that would help tell one document apart from another.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>The intuition behind TF-IDF in one sentence:</strong> A word is important for a given document if it appears there often (high TF) but rarely in other documents (high IDF). In other words: &quot;Are you unique?&quot;</p>\n</div>\n<h3><a href=\"#tf-idf-in-code\" aria-hidden=\"true\" class=\"anchor\" id=\"tf-idf-in-code\"></a>TF-IDF in code</h3>\n<p>Try it yourself. Here's a complete example in Python:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>feature_extraction</a-v>.<a-v>text</a-v> <a-k>import</a-k> <a-cr>TfidfVectorizer</a-cr>\n<a-k>import</a-k> <a-v>pandas</a-v> <a-k>as</a-k> <a-v>pd</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;This movie is great&quot;</a-s>,\n    <a-s>&quot;This movie is terrible&quot;</a-s>,\n    <a-s>&quot;Great movie I recommend&quot;</a-s>,\n]\n\n<a-v>vectorizer</a-v> <a-o>=</a-o> <a-f>TfidfVectorizer</a-f>()\n<a-v>tfidf_matrix</a-v> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>fit_transform</a-pr>(<a-v>corpus</a-v>)\n\n<a-v>df</a-v> <a-o>=</a-o> <a-v>pd</a-v>.<a-pr>DataFrame</a-pr>(\n    <a-v>tfidf_matrix</a-v>.<a-pr>toarray</a-pr>(),\n    <a-v>columns</a-v><a-o>=</a-o><a-v>vectorizer</a-v>.<a-pr>get_feature_names_out</a-pr>(),\n    <a-v>index</a-v><a-o>=</a-o>[<a-s>&quot;Doc 1&quot;</a-s>, <a-s>&quot;Doc 2&quot;</a-s>, <a-s>&quot;Doc 3&quot;</a-s>]\n)\n<a-f>print</a-f>(<a-v>df</a-v>.<a-pr>round</a-pr>(<a-n>2</a-n>))</code></pre>\n<p>The result will look roughly like this:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">        great    i    is  movie  recommend  terrible  this\nDoc 1     0.41  0.0  0.49   0.37        0.0       0.0  0.49\nDoc 2     0.00  0.0  0.46   0.35        0.0       0.58  0.46\nDoc 3     0.41  0.54  0.0   0.41        0.54       0.0  0.00\n</code></pre>\n<p>Notice: &quot;movie&quot; has low values everywhere (because it's everywhere). &quot;terrible&quot; has a high value only in Document 2 (because it only appears there). TF-IDF works!</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>An experiment for you:</strong> Think about your study (or work) notes. Which words would have high TF-IDF? Probably technical terms - &quot;recursion&quot;, &quot;entropy&quot;, &quot;backpropagation&quot;. And which would have low ones? &quot;And&quot;, &quot;is&quot;, &quot;on&quot;, &quot;that&quot; - because they're everywhere.</p>\n</div>\n<h3><a href=\"#tf-idf-as-a-search-engine\" aria-hidden=\"true\" class=\"anchor\" id=\"tf-idf-as-a-search-engine\"></a>TF-IDF as a search engine</h3>\n<p>TF-IDF has one super practical application: <strong>text search</strong>. This is basically how the first search engines worked.</p>\n<p>The idea is simple: you turn the user's query into a TF-IDF vector, and look for the document whose vector is <strong>most similar</strong> to it (so-called cosine similarity).</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>feature_extraction</a-v>.<a-v>text</a-v> <a-k>import</a-k> <a-cr>TfidfVectorizer</a-cr>\n<a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>metrics</a-v>.<a-v>pairwise</a-v> <a-k>import</a-k> <a-v>cosine_similarity</a-v>\n<a-k>import</a-k> <a-v>numpy</a-v> <a-k>as</a-k> <a-v>np</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;This movie is great&quot;</a-s>,\n    <a-s>&quot;This movie is terrible&quot;</a-s>,\n    <a-s>&quot;Great movie I recommend&quot;</a-s>,\n]\n\n<a-v>vectorizer</a-v> <a-o>=</a-o> <a-f>TfidfVectorizer</a-f>()\n<a-v>tfidf_matrix</a-v> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>fit_transform</a-pr>(<a-v>corpus</a-v>)\n\n<a-v>query</a-v> <a-o>=</a-o> <a-s>&quot;great movie&quot;</a-s>\n<a-v>query_vec</a-v> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>transform</a-pr>([<a-v>query</a-v>])\n\n<a-v>similarities</a-v> <a-o>=</a-o> <a-f>cosine_similarity</a-f>(<a-v>query_vec</a-v>, <a-v>tfidf_matrix</a-v>)[<a-n>0</a-n>]\n<a-v>ranked</a-v> <a-o>=</a-o> <a-f>sorted</a-f>(<a-f>zip</a-f>(<a-v>corpus</a-v>, <a-v>similarities</a-v>), <a-v>key</a-v><a-o>=</a-o><a-k>lambda</a-k> <a-v>x</a-v>: <a-o>-</a-o><a-v>x</a-v>[<a-n>1</a-n>])\n<a-k>for</a-k> <a-v>i</a-v>, (<a-v>doc</a-v>, <a-v>sim</a-v>) <a-o>in</a-o> <a-f>enumerate</a-f>(<a-v>ranked</a-v>, <a-n>1</a-n>):\n    <a-f>print</a-f>(<a-s>f&#39;</a-s><a-p>{</a-p><a-v>i</a-v><a-p>}</a-p><a-s>. &quot;</a-s><a-p>{</a-p><a-v>doc</a-v><a-p>}</a-p><a-s>&quot; -&gt; </a-s><a-p>{</a-p><a-v>sim</a-v><a-eb>:.3f</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)</code></pre>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Query: &quot;great movie&quot;\n\n1. &quot;Great movie I recommend&quot;        -&gt; 0.694  &lt;- best result!\n2. &quot;This movie is great&quot;            -&gt; 0.667\n3. &quot;This movie is terrible&quot;         -&gt; 0.229\n</code></pre>\n<p>Document 3 wins - because &quot;great&quot; and &quot;movie&quot; are high-TF-IDF keywords for it. Document 2 has &quot;movie&quot; but not &quot;great&quot; - so its similarity is low.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Cosine similarity</strong> measures the angle between two vectors. If the vectors point in the same direction (similar proportions of words) - the similarity is close to 1. If in opposite directions - close to 0. Don't worry about the math - the intuition is simple: &quot;how similar are these two vectors to each other?&quot;</p>\n</div>\n<hr />\n<h2><a href=\"#n-grams---or-adding-context\" aria-hidden=\"true\" class=\"anchor\" id=\"n-grams---or-adding-context\"></a>N-grams - or, adding context</h2>\n<h3><a href=\"#the-problem-words-dont-live-in-a-vacuum\" aria-hidden=\"true\" class=\"anchor\" id=\"the-problem-words-dont-live-in-a-vacuum\"></a>The problem: words don't live in a vacuum</h3>\n<p>TF-IDF is better than pure BoW, because at least it weights words by importance. But it still treats every word <strong>separately</strong>. It doesn't know that &quot;do&quot; + &quot;not&quot; + &quot;like&quot; = something completely different than &quot;like&quot; alone.</p>\n<p>Or an English example that shows the problem perfectly:</p>\n<ul>\n<li>&quot;big red <strong>carpet</strong> and machine&quot; - we're talking about a carpet</li>\n<li>&quot;big red <strong>machine</strong> and carpet&quot; - we're talking about a machine</li>\n</ul>\n<p>The same words! But the order changes everything. BoW and TF-IDF don't see it.</p>\n<h3><a href=\"#what-are-n-grams\" aria-hidden=\"true\" class=\"anchor\" id=\"what-are-n-grams\"></a>What are n-grams?</h3>\n<p>An <strong>n-gram</strong> is simply a sequence of N consecutive elements (usually words or characters).</p>\n<p>Example with the sentence &quot;Alice has a cat&quot;:</p>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>N</th>\n<th>Result</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Unigrams</td>\n<td>1</td>\n<td>Alice, has, a, cat</td>\n</tr>\n<tr>\n<td>Bigrams</td>\n<td>2</td>\n<td>Alice has, has a, a cat</td>\n</tr>\n<tr>\n<td>Trigrams</td>\n<td>3</td>\n<td>Alice has a, has a cat</td>\n</tr>\n</tbody>\n</table>\n<p>And now the magic: instead of counting single words, we count <strong>pairs of words</strong> (bigrams). And suddenly:</p>\n<ul>\n<li>&quot;do not&quot; becomes a single entity (negation + verb = negative sense)</li>\n<li>&quot;big red&quot; and &quot;red carpet&quot; are different things</li>\n<li>&quot;New York&quot; is one unit, not two words</li>\n</ul>\n<p>You can also combine n-grams with TF-IDF! In sklearn it's enough to change one parameter:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>feature_extraction</a-v>.<a-v>text</a-v> <a-k>import</a-k> <a-cr>TfidfVectorizer</a-cr>\n<a-k>import</a-k> <a-v>pandas</a-v> <a-k>as</a-k> <a-v>pd</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;This movie is great&quot;</a-s>,\n    <a-s>&quot;This movie is terrible&quot;</a-s>,\n    <a-s>&quot;Great movie I recommend&quot;</a-s>,\n]\n\n<a-v>vectorizer</a-v> <a-o>=</a-o> <a-f>TfidfVectorizer</a-f>(<a-v>ngram_range</a-v><a-o>=</a-o>(<a-n>1</a-n>, <a-n>2</a-n>))\n<a-v>tfidf_matrix</a-v> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>fit_transform</a-pr>(<a-v>corpus</a-v>)\n\n<a-v>df</a-v> <a-o>=</a-o> <a-v>pd</a-v>.<a-pr>DataFrame</a-pr>(\n    <a-v>tfidf_matrix</a-v>.<a-pr>toarray</a-pr>(),\n    <a-v>columns</a-v><a-o>=</a-o><a-v>vectorizer</a-v>.<a-pr>get_feature_names_out</a-pr>(),\n    <a-v>index</a-v><a-o>=</a-o>[<a-s>&quot;Doc 1&quot;</a-s>, <a-s>&quot;Doc 2&quot;</a-s>, <a-s>&quot;Doc 3&quot;</a-s>]\n)\n<a-f>print</a-f>(<a-v>df</a-v>.<a-pr>round</a-pr>(<a-n>2</a-n>))</code></pre>\n<p>Look what happened - the feature vocabulary grew! Besides single words (&quot;movie&quot;, &quot;is&quot;, &quot;great&quot;) we now have <strong>pairs</strong>: &quot;movie is&quot;, &quot;is great&quot;, &quot;is terrible&quot;, &quot;great movie&quot;, &quot;this movie&quot;, &quot;movie recommend&quot;. Each pair is a separate column with its own TF-IDF.</p>\n<p>Thanks to this, the model sees that &quot;is great&quot; (Doc 1) and &quot;is terrible&quot; (Doc 2) are <strong>different things</strong> - because they're different bigrams with different TF-IDF values.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>N-grams are a trade-off.</strong> The bigger the N, the more context you capture, but the more data you need. With trigrams you have 3x more combinations than with unigrams. With 4-grams - even more. And you quickly get to the point where most n-grams appear in the corpus only once, which isn't useful.</p>\n</div>\n<h3><a href=\"#markov-chains---when-n-grams-start-predicting\" aria-hidden=\"true\" class=\"anchor\" id=\"markov-chains---when-n-grams-start-predicting\"></a>Markov chains - when n-grams start &quot;predicting&quot;</h3>\n<p>N-grams by themselves are just counts - like BoW, they don't generate text. But if we add <strong>transition probabilities</strong> to them, we suddenly get something that <strong>generates new text</strong>.</p>\n<p>The idea is simple: for each word we look at what words most often follow it. And we pick the next word probabilistically.</p>\n<p>Let's take a small corpus:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">&quot;alice has a cat alice has a dog the cat likes milk alice likes the cat&quot;\n</code></pre>\n<p>We count bigrams and transition probabilities:</p>\n<table>\n<thead>\n<tr>\n<th>Word</th>\n<th>Next word</th>\n<th>Probability</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>alice</strong></td>\n<td>has</td>\n<td>2/3 = <strong>67%</strong></td>\n</tr>\n<tr>\n<td><strong>alice</strong></td>\n<td>likes</td>\n<td>1/3 = 33%</td>\n</tr>\n<tr>\n<td><strong>has</strong></td>\n<td>a</td>\n<td>2/2 = 100%</td>\n</tr>\n<tr>\n<td><strong>a</strong></td>\n<td>cat</td>\n<td>2/3 = 67%</td>\n</tr>\n<tr>\n<td><strong>a</strong></td>\n<td>dog</td>\n<td>1/3 = 33%</td>\n</tr>\n<tr>\n<td><strong>the</strong></td>\n<td>cat</td>\n<td>1/1 = 100%</td>\n</tr>\n<tr>\n<td><strong>cat</strong></td>\n<td>likes</td>\n<td>1/1 = 100%</td>\n</tr>\n<tr>\n<td><strong>likes</strong></td>\n<td>milk</td>\n<td>1/2 = 50%</td>\n</tr>\n<tr>\n<td><strong>likes</strong></td>\n<td>the</td>\n<td>1/2 = 50%</td>\n</tr>\n</tbody>\n</table>\n<p>That is exactly a <strong>Markov chain</strong> - a model in which the probability of the next state depends <strong>only on the current state</strong> (or the last few).</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"666.00635\" height=\"234.66414\" viewBox=\"0 0 666.00635 234.66414\"><rect x=\"0\" y=\"0\" width=\"666.00635\" height=\"234.66414\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 111.259,103.674 L 122.407,103.674 Q 123.572,103.674 123.572,102.509 L 123.572,102.250 Q 123.572,101.085 124.737,101.085 L 192.793,101.085\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(192.79 101.08) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"108.50\" y=\"71.07\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"138.14\" y=\"88.77\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"138.14\" dy=\"0.00\">&quot;67%&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 111.259,144.174 L 118.031,144.174 Q 123.572,144.174 129.092,144.646 L 174.960,148.568 Q 180.480,149.040 186.021,149.040 L 192.793,149.040\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(192.79 149.04) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"118.82\" y=\"113.96\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"148.46\" y=\"131.66\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"148.46\" dy=\"0.00\">&quot;33%&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 278.748,76.769 L 278.748,88.979 Q 278.748,98.969 288.738,98.969 L 377.536,98.969 Q 387.526,98.969 387.526,88.979 L 387.526,76.769\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(387.53 76.77) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"298.22\" y=\"68.57\" width=\"69.46\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"332.95\" y=\"86.27\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"332.95\" dy=\"0.00\">&quot;100%&quot;</tspan></text></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 456.178,100.590 L 462.950,100.590 Q 468.491,100.590 468.491,106.131 L 468.491,114.335 Q 468.491,124.335 478.491,124.335 L 554.373,124.335 Q 563.667,124.335 563.667,115.040 L 563.667,103.680\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(563.67 103.68) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"492.40\" y=\"126.33\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"522.05\" y=\"144.03\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"522.05\" dy=\"0.00\">&quot;67%&quot;</tspan></text></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 456.178,66.217 L 456.178,49.908 Q 456.178,39.908 466.178,39.908 L 543.213,39.908 Q 551.355,39.908 551.355,48.050 L 551.355,52.459 Q 551.355,58.000 556.895,58.000 L 563.667,58.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(563.67 58.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-4\" data-label-kind=\"center\" x=\"462.85\" y=\"9.51\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-4\" data-label-kind=\"center\"><text x=\"492.49\" y=\"27.21\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"492.49\" dy=\"0.00\">&quot;33%&quot;</tspan></text></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 296.052,170.513 L 302.824,170.513 Q 308.365,170.513 308.365,176.054 L 308.365,180.592 Q 308.365,188.839 316.612,188.839 L 377.526,188.839 Q 387.526,188.839 387.526,178.839 L 387.526,162.765\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(387.53 162.76) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-5\" data-label-kind=\"center\" x=\"316.02\" y=\"190.84\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-5\" data-label-kind=\"center\"><text x=\"345.66\" y=\"208.54\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"345.66\" dy=\"0.00\">&quot;50%&quot;</tspan></text></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 296.052,156.623 L 305.652,156.623 L 293.328,156.623 L 299.226,156.623 Q 304.052,156.623 304.052,161.449 L 304.052,186.264 Q 304.052,196.264 294.052,196.264 L 194.793,196.264 Q 184.793,196.264 184.793,186.264 L 184.793,129.680 Q 184.793,119.680 194.793,119.680 L 293.328,119.680 L 563.667,119.680\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(563.67 119.68) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-6\" data-label-kind=\"center\" x=\"208.63\" y=\"198.26\" width=\"59.28\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-6\" data-label-kind=\"center\"><text x=\"238.27\" y=\"215.96\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"238.27\" dy=\"0.00\">&quot;50%&quot;</tspan></text></g><rect x=\"8.00\" y=\"94.17\" width=\"103.26\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"59.63\" y=\"123.17\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"59.63\" dy=\"0.00\">alice</tspan></text><rect x=\"192.79\" y=\"51.08\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"235.77\" y=\"80.08\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"235.77\" dy=\"0.00\">has</tspan></text><rect x=\"387.53\" y=\"51.09\" width=\"68.65\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"421.85\" y=\"80.09\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"421.85\" dy=\"0.00\">a</tspan></text><rect x=\"563.67\" y=\"94.18\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"606.65\" y=\"123.18\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"606.65\" dy=\"0.00\">cat</tspan></text><rect x=\"563.67\" y=\"8.00\" width=\"86.34\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"606.84\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"606.84\" dy=\"0.00\">dog</tspan></text><rect x=\"192.79\" y=\"137.26\" width=\"103.26\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"244.42\" y=\"166.26\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"244.42\" dy=\"0.00\">likes</tspan></text><rect x=\"387.53\" y=\"137.26\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"434.83\" y=\"166.26\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"434.83\" dy=\"0.00\">milk</tspan></text></svg></div>\n<p>&quot;alice&quot; -&gt; most often &quot;has&quot; (67%) -&gt; &quot;a&quot; -&gt; &quot;cat&quot; (67%) or &quot;dog&quot; (33%). So we generate e.g.: &quot;alice has a cat&quot;. Or &quot;alice has a dog&quot;. Or &quot;alice likes the cat&quot;. All these sentences are &quot;new&quot; - they didn't appear as wholes in the corpus - but the model stitched them together from transition probabilities.</p>\n<h3><a href=\"#how-it-works-under-the-hood---step-by-step\" aria-hidden=\"true\" class=\"anchor\" id=\"how-it-works-under-the-hood---step-by-step\"></a>How it works under the hood - step by step</h3>\n<p>Before we get to the code, let's trace the whole process on our fingers. We have the same corpus:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">&quot;alice has a cat alice has a dog the cat likes milk alice likes the cat&quot;\n</code></pre>\n<p><strong>Step 1: Build the trigram dictionary.</strong> We slide a &quot;window&quot; of 3 words and look at what follows:</p>\n<table>\n<thead>\n<tr>\n<th>Window (trigram)</th>\n<th>Next word</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>alice has <strong>a</strong></td>\n<td>cat</td>\n</tr>\n<tr>\n<td>has a <strong>cat</strong></td>\n<td>alice</td>\n</tr>\n<tr>\n<td>a cat <strong>alice</strong></td>\n<td>has</td>\n</tr>\n<tr>\n<td>cat alice <strong>has</strong></td>\n<td>a</td>\n</tr>\n<tr>\n<td>alice has <strong>a</strong></td>\n<td>dog</td>\n</tr>\n<tr>\n<td>has a <strong>dog</strong></td>\n<td>the</td>\n</tr>\n<tr>\n<td>a dog <strong>the</strong></td>\n<td>cat</td>\n</tr>\n<tr>\n<td>dog the <strong>cat</strong></td>\n<td>likes</td>\n</tr>\n<tr>\n<td>the cat <strong>likes</strong></td>\n<td>milk</td>\n</tr>\n<tr>\n<td>cat likes <strong>milk</strong></td>\n<td>alice</td>\n</tr>\n<tr>\n<td>likes milk <strong>alice</strong></td>\n<td>likes</td>\n</tr>\n<tr>\n<td>milk alice <strong>likes</strong></td>\n<td>the</td>\n</tr>\n</tbody>\n</table>\n<p>Each trigram has exactly one possible next word (because our corpus is tiny).</p>\n<p><strong>Step 2: Generate.</strong> We start from the starter trigram <code>(&quot;alice&quot;, &quot;has&quot;, &quot;a&quot;)</code>:</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>This starter trigram is our &quot;prompt&quot;!</strong> Just like in ChatGPT you type text and the model continues - here we type &quot;alice has a&quot; and the generator picks the next words. The only difference is scale: ChatGPT has a context of thousands of tokens, and we have 3 words.</p>\n</div>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">Start:    alice has a\nStep 1:   alice has a [cat]     &lt;- after (alice,has,a) comes &quot;cat&quot;\nStep 2:   alice has a cat [alice]  &lt;- after (has,a,cat) comes &quot;alice&quot;\nStep 3:   alice has a cat alice [has] &lt;- after (a,cat,alice) comes &quot;has&quot;\nStep 4:   ... cat alice has [a]   &lt;- after (cat,alice,has) comes &quot;a&quot;\nStep 5:   ... alice has a [dog]   &lt;- after (alice,has,a) comes &quot;dog&quot;\nStep 6:   ... has a dog [the]     &lt;- after (has,a,dog) comes &quot;the&quot;\nStep 7:   ... a dog the [cat]     &lt;- after (a,dog,the) comes &quot;cat&quot;\nStep 8:   ... dog the cat [likes] &lt;- after (dog,the,cat) comes &quot;likes&quot;\nStep 9:   ... the cat likes [milk] &lt;- after (the,cat,likes) comes &quot;milk&quot;\nStep 10:  STOP &lt;- trigram (cat,likes,milk) -&gt; &quot;alice&quot;... it loops back\n</code></pre>\n<p>Result: <code>&quot;alice has a cat alice has a dog the cat likes milk&quot;</code> - basically our corpus, &quot;re-glued&quot; from the inside. On a larger corpus the result would be different every time.</p>\n<h3><a href=\"#a-simple-text-generator-from-n-grams\" aria-hidden=\"true\" class=\"anchor\" id=\"a-simple-text-generator-from-n-grams\"></a>A simple text generator from n-grams</h3>\n<p>Here's a complete (and genuinely short!) text generator in Python:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>import</a-k> <a-v>random</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> <a-s>&quot;alice has a cat alice has a dog the cat likes milk alice likes the cat&quot;</a-s>\n<a-v>tokens</a-v> <a-o>=</a-o> <a-v>corpus</a-v>.<a-pr>split</a-pr>()\n\n<a-v>trigrams</a-v> <a-o>=</a-o> {}\n<a-k>for</a-k> <a-v>i</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-f>len</a-f>(<a-v>tokens</a-v>) <a-o>-</a-o> <a-n>3</a-n>):\n    <a-v>key</a-v> <a-o>=</a-o> (<a-v>tokens</a-v>[<a-v>i</a-v>], <a-v>tokens</a-v>[<a-v>i</a-v> <a-o>+</a-o> <a-n>1</a-n>], <a-v>tokens</a-v>[<a-v>i</a-v> <a-o>+</a-o> <a-n>2</a-n>])\n    <a-v>next_word</a-v> <a-o>=</a-o> <a-v>tokens</a-v>[<a-v>i</a-v> <a-o>+</a-o> <a-n>3</a-n>]\n    <a-k>if</a-k> <a-v>key</a-v> <a-o>not in</a-o> <a-v>trigrams</a-v>:\n        <a-v>trigrams</a-v>[<a-v>key</a-v>] <a-o>=</a-o> []\n    <a-v>trigrams</a-v>[<a-v>key</a-v>].<a-pr>append</a-pr>(<a-v>next_word</a-v>)\n\n<a-v>current</a-v> <a-o>=</a-o> (<a-s>&quot;alice&quot;</a-s>, <a-s>&quot;has&quot;</a-s>, <a-s>&quot;a&quot;</a-s>)  <a-c># &lt;- this is our &quot;prompt&quot;!</a-c>\n<a-v>output</a-v> <a-o>=</a-o> <a-f>list</a-f>(<a-v>current</a-v>)\n\n<a-k>for</a-k> <a-v>_</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-n>10</a-n>):\n    <a-k>if</a-k> <a-f>tuple</a-f>(<a-v>output</a-v>[<a-o>-</a-o><a-n>3</a-n>:]) <a-o>not in</a-o> <a-v>trigrams</a-v>:\n        <a-k>break</a-k>\n    <a-v>possibilities</a-v> <a-o>=</a-o> <a-v>trigrams</a-v>[<a-f>tuple</a-f>(<a-v>output</a-v>[<a-o>-</a-o><a-n>3</a-n>:])]\n    <a-v>output</a-v>.<a-pr>append</a-pr>(<a-v>random</a-v>.<a-pr>choice</a-pr>(<a-v>possibilities</a-v>))\n\n<a-f>print</a-f>(<a-s>&quot; &quot;</a-s>.<a-pr>join</a-pr>(<a-v>output</a-v>))</code></pre>\n<p>Possible output: <code>&quot;alice has a cat alice has a dog the cat likes milk alice likes the cat&quot;</code></p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>Why does it come out the same every time?</strong> Because our corpus is so small that most trigrams have <strong>only one</strong> possible next word. <code>random.choice</code> has nothing to choose from! On a larger corpus (e.g. all of English Wikipedia) the same code would generate <strong>different text every time</strong> - because almost every trigram would have several possible continuations with different probabilities. And that's exactly the moment when generation becomes interesting.</p>\n</div>\n<p>Nothing spectacular, right? But that's because our corpus is microscopic. On a real corpus (e.g. all of Wikipedia) a trigram generator can produce sentences that sound sensible, even though they never appeared before.</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>Markov chains are the first &quot;language models&quot;!</strong> Predicting the next word based on context - that is EXACTLY what ChatGPT does. Of course GPT uses a much more advanced method (Transformer + attention over thousands of context tokens), but <strong>the fundamental idea is the same</strong>: the probability of the next token. An LLM is a descendant of Markov chains. On steroids ;-)</p>\n</div>\n<hr />\n<h2><a href=\"#bayesian-techniques---or-classifying-text\" aria-hidden=\"true\" class=\"anchor\" id=\"bayesian-techniques---or-classifying-text\"></a>Bayesian techniques - or, classifying text</h2>\n<h3><a href=\"#what-if-we-dont-want-to-generate-but-classify\" aria-hidden=\"true\" class=\"anchor\" id=\"what-if-we-dont-want-to-generate-but-classify\"></a>What if we don't want to generate, but CLASSIFY?</h3>\n<p>Markov chains are great for generating text. But in practice we often want something else: <strong>assign a text to a category</strong>.</p>\n<ul>\n<li>Is this email <strong>spam</strong> or <strong>not-spam</strong>?</li>\n<li>Is this review <strong>positive</strong> or <strong>negative</strong>?</li>\n<li>Is this article about <strong>sports</strong>, <strong>politics</strong>, or <strong>technology</strong>?</li>\n</ul>\n<p>And here comes <strong>Naive Bayes</strong> - one of the simplest yet most useful text classification algorithms.</p>\n<h3><a href=\"#bayes-theorem---the-intuition\" aria-hidden=\"true\" class=\"anchor\" id=\"bayes-theorem---the-intuition\"></a>Bayes' theorem - the intuition</h3>\n<p>Without formulas, just an example:</p>\n<p>Imagine a colleague comes up to you and says: &quot;I'm coughing.&quot; What's the probability he has a cold?</p>\n<p>It depends! If it's November and everyone in the office is sick - high. If it's July and he coughs once - low.</p>\n<p>Bayes' theorem is a formal way of thinking about such situations: <strong>we update our knowledge based on new evidence.</strong></p>\n<p>And now let's translate that to text. The question is:</p>\n<blockquote>\n<p>&quot;If a document contains the word 'viagra', what's the probability it's spam?&quot;</p>\n</blockquote>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1280.95\" height=\"281\" viewBox=\"0 0 1280.95 281\"><rect x=\"0\" y=\"0\" width=\"1280.95\" height=\"281\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 266.991,131.248 L 316.991,131.248\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(316.99 131.25) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 541.376,102.579 L 552.027,102.579 Q 558.876,102.579 565.626,101.419 L 567.126,101.161 Q 573.876,100.000 580.725,100.000 L 591.376,100.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(591.38 100.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 541.376,166.249 L 551.008,166.249 Q 558.876,166.249 565.626,170.291 L 567.126,171.189 Q 573.876,175.231 581.743,175.231 L 591.376,175.231\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(591.38 175.23) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 867.671,100.000 L 877.296,100.000 Q 885.171,100.000 890.103,106.139 L 900.842,119.508 Q 905.774,125.647 913.649,125.647 L 923.274,125.647\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(923.27 125.65) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 833.063,174.776 L 842.688,174.776 Q 850.563,174.776 856.483,169.582 L 894.251,136.445 Q 900.171,131.251 908.046,131.251 L 917.671,131.251\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(917.67 131.25) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 1065.082,131.251 L 1144.387,131.251\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1144.39 131.25) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-5\" data-label-kind=\"center\" x=\"1074.18\" y=\"100.85\" width=\"61.12\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-5\" data-label-kind=\"center\"><text x=\"1104.73\" y=\"118.55\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1104.73\" dy=\"0.00\">Spam!</tspan></text></g><polygon points=\"991.38,57.55 1065.08,131.25 991.38,204.96 917.67,131.25\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"991.38\" y=\"113.75\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"991.38\" dy=\"0.00\">Which</tspan><tspan x=\"991.38\" dy=\"21.00\">probability</tspan><tspan x=\"991.38\" dy=\"21.00\">is higher?</tspan></text><rect x=\"8.00\" y=\"95.25\" width=\"258.99\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.50\" y=\"124.25\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.50\" dy=\"0.00\">📧 New email:</tspan><tspan x=\"137.50\" dy=\"21.00\">&apos;Buy cheap viagra now!&apos;</tspan></text><rect x=\"591.38\" y=\"151.00\" width=\"241.69\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"712.22\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"712.22\" dy=\"0.00\">📊 P(not-spam) x</tspan><tspan x=\"712.22\" dy=\"21.00\">P(&apos;buy&apos;|not-spam) x</tspan><tspan x=\"712.22\" dy=\"21.00\">P(&apos;cheap&apos;|not-spam) x</tspan><tspan x=\"712.22\" dy=\"21.00\">P(&apos;viagra&apos;|not-spam)</tspan></text><rect x=\"316.99\" y=\"95.25\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"429.18\" y=\"124.25\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"429.18\" dy=\"0.00\">P(spam | &apos;buy cheap</tspan><tspan x=\"429.18\" dy=\"21.00\">viagra now&apos;) = ?</tspan></text><rect x=\"1144.39\" y=\"105.75\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1204.67\" y=\"134.75\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1204.67\" dy=\"0.00\">🗑️ SPAM</tspan></text><rect x=\"591.38\" y=\"8.00\" width=\"276.29\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"729.52\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"729.52\" dy=\"0.00\">📊 P(spam) x P(&apos;buy&apos;|spam)</tspan><tspan x=\"729.52\" dy=\"21.00\">x P(&apos;cheap&apos;|spam) x</tspan><tspan x=\"729.52\" dy=\"21.00\">P(&apos;viagra&apos;|spam)</tspan></text></svg></div>\n<h3><a href=\"#naive-bayes-in-action\" aria-hidden=\"true\" class=\"anchor\" id=\"naive-bayes-in-action\"></a>Naive Bayes in action</h3>\n<p>We have a small set of emails:</p>\n<table>\n<thead>\n<tr>\n<th>Email</th>\n<th>Content</th>\n<th>Label</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>&quot;Buy cheap viagra now&quot;</td>\n<td>Spam</td>\n</tr>\n<tr>\n<td>2</td>\n<td>&quot;Free viagra offer&quot;</td>\n<td>Spam</td>\n</tr>\n<tr>\n<td>3</td>\n<td>&quot;Meeting tomorrow at 10&quot;</td>\n<td>Not-spam</td>\n</tr>\n<tr>\n<td>4</td>\n<td>&quot;Send me the report tomorrow&quot;</td>\n<td>Not-spam</td>\n</tr>\n</tbody>\n</table>\n<p>A new email arrives: <strong>&quot;Viagra meeting tomorrow&quot;</strong>. Spam or not?</p>\n<p>Naive Bayes computes:</p>\n<ol>\n<li>P(Spam) = 2/4 = 0.5, P(Not-spam) = 2/4 = 0.5</li>\n<li>P(&quot;viagra&quot; | Spam) = 2/2 = 1.0 (both spams have &quot;viagra&quot;)</li>\n<li>P(&quot;viagra&quot; | Not-spam) = 0/2 = 0.0 (no not-spam has &quot;viagra&quot;)</li>\n<li>P(&quot;tomorrow&quot; | Spam) = 0/2 = 0.0</li>\n<li>P(&quot;tomorrow&quot; | Not-spam) = 2/2 = 1.0</li>\n</ol>\n<p>P(Spam | &quot;viagra meeting tomorrow&quot;) ∝ 0.5 x 1.0 x 0.0 x ... = <strong>0</strong>!</p>\n<p>P(Not-spam | &quot;viagra meeting tomorrow&quot;) ∝ 0.5 x 0.0 x 1.0 x ... = <strong>0</strong>!</p>\n<p>Oops. The presence of &quot;tomorrow&quot; (a not-spam word) zeroed out spam, and the presence of &quot;viagra&quot; (a spam word) zeroed out not-spam. This particular email is tricky ;-)</p>\n<p>In practice, so-called <strong>Laplace smoothing</strong> is used (we add 1 to each count) to avoid zeroing:</p>\n<ul>\n<li>P(&quot;viagra&quot; | Spam) = (2 + 1) / (7 + 14) = 0.214 (we add 1, divide by all words in spam + unique words)</li>\n<li>P(&quot;viagra&quot; | Not-spam) = (0 + 1) / (7 + 14) = 0.048</li>\n</ul>\n<p>Now: P(Spam | email) ∝ 0.5 x 0.214 x 0.048 x 0.048 ≈ <strong>0.000246</strong>\nP(Not-spam | email) ∝ 0.5 x 0.048 x 0.143 x 0.143 ≈ <strong>0.000490</strong></p>\n<p>Not-spam wins! Because &quot;tomorrow&quot; and &quot;meeting&quot; strongly indicate a normal email.</p>\n<h3><a href=\"#why-naive\" aria-hidden=\"true\" class=\"anchor\" id=\"why-naive\"></a>Why &quot;Naive&quot;?</h3>\n<p>Because we assume words are <strong>independent</strong>. That is: the probability of &quot;viagra&quot; appearing doesn't depend on whether &quot;cheap&quot; also appears. Of course that's not true! &quot;Viagra&quot; and &quot;cheap&quot; appear together more often than by chance. But the model still works surprisingly well...</p>\n<p>It's a bit like assuming the weather in London doesn't depend on the weather in Paris. Of course it does a bit! But if you want to quickly estimate whether you need an umbrella, the independence assumption gives you a reasonably good answer ;-)</p>\n<h3><a href=\"#a-spam-classifier-in-python\" aria-hidden=\"true\" class=\"anchor\" id=\"a-spam-classifier-in-python\"></a>A spam classifier in Python</h3>\n<p>Now that we understand the math, let's do it in a few lines of code. The <code>scikit-learn</code> library has a ready Naive Bayes classifier:</p>\n<ul>\n<li><strong><code>CountVectorizer</code></strong> - turns text into a word-count vector (our BoW from the previous section)</li>\n<li><strong><code>MultinomialNB</code></strong> - that's Naive Bayes, the &quot;multinomial&quot; variant (because it counts word probabilities), with <code>alpha=1.0</code> i.e. Laplace smoothing</li>\n</ul>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>naive_bayes</a-v> <a-k>import</a-k> <a-cr>MultinomialNB</a-cr>\n<a-k>from</a-k> <a-v>sklearn</a-v>.<a-v>feature_extraction</a-v>.<a-v>text</a-v> <a-k>import</a-k> <a-cr>CountVectorizer</a-cr>\n\n<a-v>emails</a-v> <a-o>=</a-o> [\n    <a-s>&quot;Buy cheap viagra now&quot;</a-s>,\n    <a-s>&quot;Free viagra offer&quot;</a-s>,\n    <a-s>&quot;Meeting tomorrow at 10&quot;</a-s>,\n    <a-s>&quot;Send me the report tomorrow&quot;</a-s>,\n    <a-s>&quot;Cheap pills online buy now&quot;</a-s>,\n    <a-s>&quot;Report from yesterday send&quot;</a-s>,\n]\n<a-v>labels</a-v> <a-o>=</a-o> [<a-n>1</a-n>, <a-n>1</a-n>, <a-n>0</a-n>, <a-n>0</a-n>, <a-n>1</a-n>, <a-n>0</a-n>]  <a-c># 1=spam, 0=not-spam</a-c>\n\n<a-v>vectorizer</a-v> <a-o>=</a-o> <a-f>CountVectorizer</a-f>()\n<a-co>X</a-co> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>fit_transform</a-pr>(<a-v>emails</a-v>)\n\n<a-v>classifier</a-v> <a-o>=</a-o> <a-f>MultinomialNB</a-f>(<a-v>alpha</a-v><a-o>=</a-o><a-n>1.0</a-n>)\n<a-v>classifier</a-v>.<a-pr>fit</a-pr>(<a-co>X</a-co>, <a-v>labels</a-v>)\n\n<a-v>new_email</a-v> <a-o>=</a-o> <a-v>vectorizer</a-v>.<a-pr>transform</a-pr>([<a-s>&quot;Viagra meeting tomorrow&quot;</a-s>])\n<a-v>prediction</a-v> <a-o>=</a-o> <a-v>classifier</a-v>.<a-pr>predict</a-pr>(<a-v>new_email</a-v>)\n<a-f>print</a-f>(<a-s>&quot;Spam!&quot;</a-s> <a-k>if</a-k> <a-v>prediction</a-v>[<a-n>0</a-n>] <a-o>==</a-o> <a-n>1</a-n> <a-k>else</a-k> <a-s>&quot;Not spam.&quot;</a-s>)</code></pre>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>An experiment for you:</strong> Create 5 positive sentences about a movie (&quot;This movie was amazing!&quot;, &quot;Great action!&quot;, ...) and 5 negative ones (&quot;Boring as watching paint dry&quot;, &quot;Waste of time&quot;, ...). Write down the words that appear ONLY in positive and ONLY in negative. That's the intuition of Naive Bayes - every word &quot;votes&quot; for one of the categories.</p>\n</div>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Limitation:</strong> Naive Bayes sees words but not context. &quot;The movie is AMAZING... just kidding, awful&quot; - the model will see &quot;amazing&quot; and say &quot;positive&quot;. It doesn't get irony or complex constructions. We need something that understands <strong>relationships between words</strong>. And here we enter the world of vectors...</p>\n</div>\n<hr />\n<h2><a href=\"#word2vec---words-become-geometry\" aria-hidden=\"true\" class=\"anchor\" id=\"word2vec---words-become-geometry\"></a>Word2Vec - words become geometry</h2>\n<h3><a href=\"#the-eureka-moment\" aria-hidden=\"true\" class=\"anchor\" id=\"the-eureka-moment\"></a>The &quot;eureka&quot; moment</h3>\n<p>All the methods we've met so far have one problem in common: <strong>they treat words as discrete, independent entities</strong>. In BoW &quot;cat&quot; is at position 47 in the vector, &quot;dog&quot; at position 138. There's no relationship between them.</p>\n<p>But WE know that &quot;cat&quot; and &quot;dog&quot; are similar - both are pets. &quot;Cat&quot; and &quot;car&quot; - completely different. How do we make a computer &quot;know&quot; that too?</p>\n<p>The answer from 2013, from Tomáš Mikolov's team at Google: <strong>let's turn words into points in a high-dimensional space</strong>. Semantically similar words will be close to each other. Different words - far apart.</p>\n<p>That's <strong>Word2Vec</strong>. And it's a breakthrough.</p>\n<h3><a href=\"#one-hot-encoding-the-starting-point\" aria-hidden=\"true\" class=\"anchor\" id=\"one-hot-encoding-the-starting-point\"></a>One-hot encoding: the starting point</h3>\n<p>Before Word2Vec, the standard was so-called <strong>one-hot encoding</strong> - each word is a vector with a 1 at its position and 0 everywhere else:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">&quot;cat&quot;  -&gt; [0, 0, 0, 1, 0, 0, ...]  (1 at position 3)\n&quot;dog&quot;  -&gt; [0, 0, 1, 0, 0, 0, ...]  (1 at position 2)\n&quot;car&quot;  -&gt; [1, 0, 0, 0, 0, 0, ...]  (1 at position 0)\n</code></pre>\n<p>The problem? <strong>Every word is the same distance from every other word.</strong> The distance between &quot;cat&quot; and &quot;dog&quot; is the same as between &quot;cat&quot; and &quot;car&quot;. Zero information about meaning.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"437.8357\" height=\"309.5\" viewBox=\"0 0 437.8357 309.5\"><rect x=\"0\" y=\"0\" width=\"437.8357\" height=\"309.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"413.84\" height=\"285.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"214.92\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"214.92\" dy=\"0.00\">One-hot: everything is</tspan><tspan x=\"214.92\" dy=\"21.00\">equally far</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 181.866,148.885 L 191.491,148.885 Q 199.366,148.885 207.126,147.541 L 222.710,144.843 Q 230.470,143.500 238.345,143.500 L 247.970,143.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"199.35\" y=\"113.51\" width=\"38.66\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"218.68\" y=\"131.21\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"218.68\" dy=\"0.00\">&quot;=&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 181.866,204.500 L 191.491,204.500 Q 199.366,204.500 207.126,205.843 L 222.710,208.541 Q 230.470,209.885 238.345,209.885 L 247.970,209.885\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"199.35\" y=\"211.47\" width=\"38.66\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"218.68\" y=\"229.17\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"218.68\" dy=\"0.00\">&quot;=&quot;</tspan></text></g><rect x=\"44.00\" y=\"133.50\" width=\"137.87\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"112.93\" y=\"162.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"112.93\" dy=\"0.00\">cat</tspan><tspan x=\"112.93\" dy=\"21.00\">[0,0,1,0]</tspan></text><rect x=\"247.97\" y=\"72.50\" width=\"137.87\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"316.90\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"316.90\" dy=\"0.00\">dog</tspan><tspan x=\"316.90\" dy=\"21.00\">[0,1,0,0]</tspan></text><rect x=\"247.97\" y=\"194.50\" width=\"137.87\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"316.90\" y=\"223.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"316.90\" dy=\"0.00\">car</tspan><tspan x=\"316.90\" dy=\"21.00\">[1,0,0,0]</tspan></text></svg></div>\n<h3><a href=\"#word2vec-show-me-your-neighbors-and-ill-tell-you-who-you-are\" aria-hidden=\"true\" class=\"anchor\" id=\"word2vec-show-me-your-neighbors-and-ill-tell-you-who-you-are\"></a>Word2Vec: &quot;Show me your neighbors and I'll tell you who you are&quot;</h3>\n<p>Word2Vec is based on a brilliant linguistic intuition: <strong>words that appear in similar contexts have similar meanings.</strong></p>\n<p>If you see: &quot;___ runs in the park and chases pigeons&quot;, what fits there? Dog? Cat? Rather not &quot;car&quot; or &quot;democracy&quot;. Context defines the word.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1425.8763\" height=\"502\" viewBox=\"0 0 1425.8763 502\"><rect x=\"0\" y=\"0\" width=\"1425.8763\" height=\"502\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.13\" y=\"236.50\" width=\"1401.75\" height=\"249.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"709.00\" y=\"264.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"709.00\" dy=\"0.00\">Context of the word &apos;cat&apos;</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"1092.88\" height=\"148.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"554.44\" y=\"35.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"554.44\" dy=\"0.00\">Context of the word &apos;dog&apos;</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 242.081,90.000 L 251.706,90.000 Q 259.581,90.000 259.581,97.875 L 259.581,188.750 Q 259.581,198.750 249.581,198.750 L 27.629,198.750 Q 17.629,198.750 17.629,208.750 L 17.629,400.625 Q 17.629,408.500 25.504,408.500 L 35.129,408.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(35.13 408.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"50.06\" y=\"168.35\" width=\"177.09\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"138.60\" y=\"186.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"138.60\" dy=\"0.00\">&quot;shared context!&quot;</tspan></text></g><rect x=\"1123.89\" y=\"277.00\" width=\"258.99\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1253.38\" y=\"306.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1253.38\" dy=\"0.00\">___ sleeps on the couch</tspan></text><rect x=\"566.46\" y=\"277.00\" width=\"224.38\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"678.66\" y=\"306.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"678.66\" dy=\"0.00\">My ___ catches mice</tspan></text><rect x=\"35.13\" y=\"399.00\" width=\"207.08\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"138.67\" y=\"428.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"138.67\" dy=\"0.00\">I feed ___ kibble</tspan></text><rect x=\"840.85\" y=\"48.50\" width=\"233.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"957.37\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"957.37\" dy=\"0.00\">___ runs in the park</tspan></text><rect x=\"292.08\" y=\"48.50\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"404.27\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"404.27\" dy=\"0.00\">My ___ barks at the</tspan><tspan x=\"404.27\" dy=\"21.00\">mailman</tspan></text><rect x=\"35.00\" y=\"48.50\" width=\"207.08\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"138.54\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"138.54\" dy=\"0.00\">I feed ___ kibble</tspan></text></svg></div>\n<p>&quot;I feed ___ kibble&quot; - both dog and cat fit. That means the context of these words is partly shared. And that's exactly what Word2Vec exploits.</p>\n<p>Remember <strong>Saussure</strong> from the <a href=\"semiotics-and-llm.html\">second post</a>? Meaning is relational. &quot;Cat&quot; means what it means because it is NOT &quot;dog&quot;, it is NOT &quot;house&quot;. Word2Vec is the mathematical implementation of that idea!</p>\n<h3><a href=\"#cbow-and-skip-gram---two-sides-of-the-same-coin\" aria-hidden=\"true\" class=\"anchor\" id=\"cbow-and-skip-gram---two-sides-of-the-same-coin\"></a>CBOW and Skip-gram - two sides of the same coin</h3>\n<p>Word2Vec has two variants. Let's see both:</p>\n<p><strong>CBOW (Continuous Bag of Words):</strong> from context we guess the middle word.</p>\n<p><code>&quot;The cat ___ on the mat&quot; -&gt; sits? lies? sleeps?</code></p>\n<p><strong>Skip-gram:</strong> from the middle word we guess the context.</p>\n<p><code>&quot;sits&quot; -&gt; The? cat? on? the? mat?</code></p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1070.7925\" height=\"367.79407\" viewBox=\"0 0 1070.7925 367.79407\"><rect x=\"0\" y=\"0\" width=\"1070.7925\" height=\"367.79407\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"32.00\" width=\"613.68\" height=\"319.79\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"314.84\" y=\"59.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"314.84\" dy=\"0.00\">CBOW: context -&gt; word</tspan></text><rect x=\"654.33\" y=\"8.00\" width=\"400.46\" height=\"343.79\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"854.56\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"854.56\" dy=\"0.00\">Skip-gram: word -&gt;</tspan><tspan x=\"854.56\" dy=\"21.00\">context</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 386.290,123.500 L 386.290,129.785 Q 386.290,134.926 381.368,136.415 L 358.821,143.232 Q 353.899,144.721 353.899,149.862 L 353.899,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(353.90 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 231.673,123.500 L 231.673,130.493 Q 231.673,134.926 232.153,139.334 L 232.260,140.313 Q 232.740,144.721 232.740,149.154 L 232.740,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(232.74 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 114.438,123.500 L 114.438,132.478 Q 114.438,139.824 121.784,139.824 L 180.112,139.824 Q 187.458,139.824 187.458,147.169 L 187.458,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(187.46 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 309.666,123.500 L 309.666,130.490 Q 309.666,134.926 309.155,139.334 L 309.042,140.313 Q 308.532,144.721 308.532,149.157 L 308.532,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(308.53 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 504.975,123.500 L 504.975,129.785 Q 504.975,134.926 499.834,134.926 L 398.339,134.926 Q 388.790,134.926 388.790,144.476 L 388.790,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(388.79 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 277.667,228.147 L 277.667,234.486 Q 277.667,239.573 275.125,243.981 L 274.560,244.960 Q 272.018,249.368 272.018,254.455 L 272.018,260.794\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(272.02 260.79) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 796.030,123.500 L 796.030,129.785 Q 796.030,134.926 799.284,138.908 L 800.781,140.739 Q 804.035,144.721 804.035,149.862 L 804.035,156.147\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(804.03 156.15) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 864.736,207.147 L 864.736,260.794\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(864.74 260.79) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-8\" class=\"edgePath\" data-edge-id=\"edge-8\" d=\"M 893.024,207.147 L 893.024,213.432 Q 893.024,218.573 897.026,221.803 L 927.184,246.139 Q 931.185,249.368 931.185,254.510 L 931.185,260.794\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(931.19 260.79) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-9\" class=\"edgePath\" data-edge-id=\"edge-9\" d=\"M 816.061,207.147 L 816.061,213.432 Q 816.061,218.573 811.766,221.401 L 773.579,246.540 Q 769.284,249.368 769.284,254.510 L 769.284,260.794\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(769.28 260.79) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"385.29\" y=\"72.50\" width=\"86.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"428.31\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"428.31\" dy=\"0.00\">The</tspan></text><rect x=\"148.09\" y=\"72.50\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"191.06\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"191.06\" dy=\"0.00\">cat</tspan></text><rect x=\"38.00\" y=\"72.50\" width=\"77.44\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"76.72\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"76.72\" dy=\"0.00\">on</tspan></text><rect x=\"266.69\" y=\"72.50\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"309.67\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"309.67\" dy=\"0.00\">the</tspan></text><rect x=\"503.98\" y=\"72.50\" width=\"87.71\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"547.83\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"547.83\" dy=\"0.00\">mat</tspan></text><rect x=\"174.06\" y=\"156.15\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"281.92\" y=\"185.15\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"281.92\" dy=\"0.00\">🧠 Hidden layer</tspan><tspan x=\"281.92\" dy=\"21.00\">(averaged vectors)</tspan></text><rect x=\"754.09\" y=\"156.15\" width=\"181.13\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"844.66\" y=\"185.15\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"844.66\" dy=\"0.00\">🧠 Hidden layer</tspan></text><rect x=\"213.28\" y=\"260.79\" width=\"111.91\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"269.24\" y=\"289.79\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"269.24\" dy=\"0.00\">sits ✅</tspan></text><rect x=\"802.93\" y=\"260.79\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"850.23\" y=\"289.79\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"850.23\" dy=\"0.00\">The?</tspan></text><rect x=\"930.19\" y=\"260.79\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"977.49\" y=\"289.79\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"977.49\" dy=\"0.00\">cat?</tspan></text><rect x=\"684.33\" y=\"260.79\" width=\"85.96\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"727.31\" y=\"289.79\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"727.31\" dy=\"0.00\">on?</tspan></text><rect x=\"704.39\" y=\"72.50\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"751.69\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"751.69\" dy=\"0.00\">sits</tspan></text></svg></div>\n<p>How does it work inside? A neural network with one hidden layer:</p>\n<ol>\n<li>Each word starts as a one-hot vector (e.g. [0, 0, 1, 0, ...])</li>\n<li>We multiply by a weight matrix <strong>W</strong> (size: vocabulary x embedding dimension, e.g. 50 000 x 300)</li>\n<li>The result is a vector of size <strong>E</strong> (e.g. 300 numbers) - that's our embedding!</li>\n<li>In CBOW: we average the context vectors and predict the middle. In Skip-gram: we take the middle and predict the neighbors.</li>\n<li>The network trains on millions of (word, context) pairs, updating the matrix <strong>W</strong></li>\n<li>After training, <strong>the row of the matrix W corresponding to a given word is its embedding</strong></li>\n</ol>\n<p>Sounds complicated? Let's do it in code - from scratch, without any ML libraries:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>import</a-k> <a-v>numpy</a-v> <a-k>as</a-k> <a-v>np</a-v>\n\n<a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>seed</a-pr>(<a-n>42</a-n>)\n\n<a-c># --- 1. Vocabulary and one-hot encoding ---</a-c>\n<a-v>corpus</a-v> <a-o>=</a-o> <a-s>&quot;cat sits on the mat and sleeps dog sits on the rug and sleeps cat runs around the room dog runs in the park&quot;</a-s>.<a-pr>split</a-pr>()\n<a-v>vocab</a-v> <a-o>=</a-o> <a-f>list</a-f>(<a-f>set</a-f>(<a-v>corpus</a-v>))\n<a-v>word2idx</a-v> <a-o>=</a-o> {<a-v>w</a-v>: <a-v>i</a-v> <a-k>for</a-k> <a-v>i</a-v>, <a-v>w</a-v> <a-o>in</a-o> <a-f>enumerate</a-f>(<a-v>vocab</a-v>)}\n<a-v>vocab_size</a-v> <a-o>=</a-o> <a-f>len</a-f>(<a-v>vocab</a-v>)\n\n<a-k>def</a-k> <a-f>one_hot</a-f>(<a-v>word</a-v>):\n    <a-v>vec</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>zeros</a-pr>(<a-v>vocab_size</a-v>)\n    <a-v>vec</a-v>[<a-v>word2idx</a-v>[<a-v>word</a-v>]] <a-o>=</a-o> <a-n>1</a-n>\n    <a-k>return</a-k> <a-v>vec</a-v>\n\n<a-f>print</a-f>(<a-s>f&#39;One-hot &quot;cat&quot;: </a-s><a-p>{</a-p><a-f>one_hot</a-f><a-eb>(</a-eb><a-s>&quot;cat&quot;</a-s><a-eb>)</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)\n<a-c># [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]  - only a single one!</a-c>\n\n<a-c># --- 2. Weight matrix (these will be our embeddings) ---</a-c>\n<a-v>embed_dim</a-v> <a-o>=</a-o> <a-n>5</a-n>  <a-c># in real Word2Vec this is 100-300</a-c>\n<a-cr>W1</a-cr> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>randn</a-pr>(<a-v>vocab_size</a-v>, <a-v>embed_dim</a-v>) <a-o>*</a-o> <a-n>0.01</a-n>  <a-c># vocabulary -&gt; embedding</a-c>\n<a-cr>W2</a-cr> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>random</a-pr>.<a-pr>randn</a-pr>(<a-v>embed_dim</a-v>, <a-v>vocab_size</a-v>) <a-o>*</a-o> <a-n>0.01</a-n>  <a-c># embedding -&gt; vocabulary</a-c>\n\n<a-c># --- 3. Training pairs (CBOW: context -&gt; middle) ---</a-c>\n<a-v>window</a-v> <a-o>=</a-o> <a-n>2</a-n>\n<a-v>pairs</a-v> <a-o>=</a-o> []\n<a-k>for</a-k> <a-v>i</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-v>window</a-v>, <a-f>len</a-f>(<a-v>corpus</a-v>) <a-o>-</a-o> <a-v>window</a-v>):\n    <a-v>context</a-v> <a-o>=</a-o> <a-v>corpus</a-v>[<a-v>i</a-v> <a-o>-</a-o> <a-v>window</a-v>:<a-v>i</a-v>] <a-o>+</a-o> <a-v>corpus</a-v>[<a-v>i</a-v> <a-o>+</a-o> <a-n>1</a-n>:<a-v>i</a-v> <a-o>+</a-o> <a-v>window</a-v> <a-o>+</a-o> <a-n>1</a-n>]\n    <a-v>target</a-v> <a-o>=</a-o> <a-v>corpus</a-v>[<a-v>i</a-v>]\n    <a-v>pairs</a-v>.<a-pr>append</a-pr>((<a-v>context</a-v>, <a-v>target</a-v>))\n\n<a-f>print</a-f>(<a-s>f&#39;Context: </a-s><a-p>{</a-p><a-v>pairs</a-v><a-eb>[</a-eb><a-n>0</a-n><a-eb>][</a-eb><a-n>0</a-n><a-eb>]</a-eb><a-p>}</a-p><a-s> -&gt; Target: </a-s><a-p>{</a-p><a-v>pairs</a-v><a-eb>[</a-eb><a-n>0</a-n><a-eb>][</a-eb><a-n>1</a-n><a-eb>]</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)\n<a-c># Context: [&#39;cat&#39;, &#39;sits&#39;, &#39;the&#39;, &#39;mat&#39;] -&gt; Target: on</a-c>\n\n<a-c># --- 4. Training (gradient descent) ---</a-c>\n<a-k>def</a-k> <a-f>softmax</a-f>(<a-v>x</a-v>):\n    <a-v>e</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>exp</a-pr>(<a-v>x</a-v> <a-o>-</a-o> <a-v>np</a-v>.<a-pr>max</a-pr>(<a-v>x</a-v>))\n    <a-k>return</a-k> <a-v>e</a-v> <a-o>/</a-o> <a-v>e</a-v>.<a-pr>sum</a-pr>()\n\n<a-k>for</a-k> <a-v>epoch</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-n>500</a-n>):\n    <a-v>loss</a-v> <a-o>=</a-o> <a-n>0</a-n>\n    <a-k>for</a-k> <a-v>context_words</a-v>, <a-v>target_word</a-v> <a-o>in</a-o> <a-v>pairs</a-v>:\n        <a-v>context_idx</a-v> <a-o>=</a-o> [<a-v>word2idx</a-v>[<a-v>w</a-v>] <a-k>for</a-k> <a-v>w</a-v> <a-o>in</a-o> <a-v>context_words</a-v>]\n        <a-v>target_idx</a-v> <a-o>=</a-o> <a-v>word2idx</a-v>[<a-v>target_word</a-v>]\n\n        <a-c># forward: averaged context embeddings -&gt; predict the middle</a-c>\n        <a-v>hidden</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>mean</a-pr>(<a-cr>W1</a-cr>[<a-v>context_idx</a-v>], <a-v>axis</a-v><a-o>=</a-o><a-n>0</a-n>)\n        <a-v>output</a-v> <a-o>=</a-o> <a-f>softmax</a-f>(<a-v>hidden</a-v> @ <a-cr>W2</a-cr>)\n        <a-v>loss</a-v> <a-o>-=</a-o> <a-v>np</a-v>.<a-pr>log</a-pr>(<a-v>output</a-v>[<a-v>target_idx</a-v>] <a-o>+</a-o> <a-n>1e-8</a-n>)\n\n        <a-c># backward: update the weights</a-c>\n        <a-v>grad</a-v> <a-o>=</a-o> <a-v>output</a-v>.<a-pr>copy</a-pr>()\n        <a-v>grad</a-v>[<a-v>target_idx</a-v>] <a-o>-=</a-o> <a-n>1</a-n>\n        <a-cr>W2</a-cr> <a-o>-=</a-o> <a-n>0.05</a-n> <a-o>*</a-o> <a-v>np</a-v>.<a-pr>outer</a-pr>(<a-v>hidden</a-v>, <a-v>grad</a-v>)\n        <a-v>grad_hidden</a-v> <a-o>=</a-o> <a-v>grad</a-v> @ <a-cr>W2</a-cr>.<a-pr>T</a-pr>\n        <a-k>for</a-k> <a-v>idx</a-v> <a-o>in</a-o> <a-v>context_idx</a-v>:\n            <a-cr>W1</a-cr>[<a-v>idx</a-v>] <a-o>-=</a-o> <a-n>0.05</a-n> <a-o>*</a-o> <a-v>grad_hidden</a-v> <a-o>/</a-o> <a-f>len</a-f>(<a-v>context_idx</a-v>)\n\n<a-c># --- 5. Result: embeddings! ---</a-c>\n<a-k>for</a-k> <a-v>word</a-v> <a-o>in</a-o> [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;dog&quot;</a-s>, <a-s>&quot;sits&quot;</a-s>, <a-s>&quot;runs&quot;</a-s>]:\n    <a-f>print</a-f>(<a-s>f&quot;</a-s><a-p>{</a-p><a-v>word</a-v><a-p>}</a-p><a-s>: </a-s><a-p>{</a-p><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-v>word</a-v><a-eb>]].</a-eb><a-pr>round</a-pr><a-eb>(</a-eb><a-n>3</a-n><a-eb>)</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)\n\n<a-c># --- 6. Cosine similarity ---</a-c>\n<a-k>def</a-k> <a-f>cosine</a-f>(<a-v>a</a-v>, <a-v>b</a-v>):\n    <a-k>return</a-k> <a-v>np</a-v>.<a-pr>dot</a-pr>(<a-v>a</a-v>, <a-v>b</a-v>) <a-o>/</a-o> (<a-v>np</a-v>.<a-pr>linalg</a-pr>.<a-pr>norm</a-pr>(<a-v>a</a-v>) <a-o>*</a-o> <a-v>np</a-v>.<a-pr>linalg</a-pr>.<a-pr>norm</a-pr>(<a-v>b</a-v>) <a-o>+</a-o> <a-n>1e-8</a-n>)\n\n<a-f>print</a-f>(<a-s>f&#39;cat &lt;-&gt; dog: </a-s><a-p>{</a-p><a-f>cosine</a-f><a-eb>(</a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;cat&quot;</a-s><a-eb>]], </a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;dog&quot;</a-s><a-eb>]]):.3f</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)\n<a-f>print</a-f>(<a-s>f&#39;cat &lt;-&gt; sits: </a-s><a-p>{</a-p><a-f>cosine</a-f><a-eb>(</a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;cat&quot;</a-s><a-eb>]], </a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;sits&quot;</a-s><a-eb>]]):.3f</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)\n<a-f>print</a-f>(<a-s>f&#39;cat &lt;-&gt; runs: </a-s><a-p>{</a-p><a-f>cosine</a-f><a-eb>(</a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;cat&quot;</a-s><a-eb>]], </a-eb><a-cr>W1</a-cr><a-eb>[</a-eb><a-v>word2idx</a-v><a-eb>[</a-eb><a-s>&quot;runs&quot;</a-s><a-eb>]]):.3f</a-eb><a-p>}</a-p><a-s>&#39;</a-s>)</code></pre>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">One-hot &quot;cat&quot;: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\nContext: ['cat', 'sits', 'the', 'mat'] -&gt; Target: on\ncat: [-2.866 -0.264 -0.225 -1.822  2.783]\ndog: [-1.133  0.678 -1.537  1.989  2.241]\nsits: [ 1.524 -0.023  1.804 -2.355 -0.788]\nruns: [ 2.     4.098 -0.315  2.971  0.815]\ncat &lt;-&gt; dog: 0.378\ncat &lt;-&gt; sits: -0.177\ncat &lt;-&gt; runs: -0.407\n</code></pre>\n<p>Notice: <strong>cat and dog</strong> (0.378) are more similar than <strong>cat and runs</strong> (-0.407). The network discovered on its own that &quot;cat&quot; and &quot;dog&quot; are animals, because they appear in similar contexts. Zero labels, zero supervision - just text and math.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p>This is <strong>all of Word2Vec in ~30 lines</strong>. Real Word2Vec adds negative sampling (because softmax over 50 000 words is slow) and optimizations, but the principle is exactly the same.</p>\n</div>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>The &quot;fake task&quot;:</strong> What we care about is not what the network predicts, but the <strong>hidden layer weights</strong>. We train the network on an &quot;artificial&quot; task of predicting context, but what we want to extract is the matrix W - our embeddings. It's a bit like training someone to solve crosswords not so they solve crosswords well, but so they expand their vocabulary ;-)</p>\n</div>\n<h3><a href=\"#cbow-vs-skip-gram\" aria-hidden=\"true\" class=\"anchor\" id=\"cbow-vs-skip-gram\"></a>CBOW vs Skip-gram</h3>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>CBOW</th>\n<th>Skip-gram</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Direction</strong></td>\n<td>Context -&gt; Middle word</td>\n<td>Middle word -&gt; Context</td>\n</tr>\n<tr>\n<td><strong>Speed</strong></td>\n<td>Faster</td>\n<td>Slower</td>\n</tr>\n<tr>\n<td><strong>Rare words</strong></td>\n<td>Handles worse</td>\n<td>Handles better</td>\n</tr>\n<tr>\n<td><strong>Frequent words</strong></td>\n<td>Handles better</td>\n<td>Handles worse</td>\n</tr>\n<tr>\n<td><strong>When to use</strong></td>\n<td>Large corpus, frequent words</td>\n<td>Small corpus, rare words</td>\n</tr>\n</tbody>\n</table>\n<p>According to Mikolov et al.'s original paper: <strong>Skip-gram is better for rare words and small datasets. CBOW is faster and better for frequent words.</strong></p>\n<h3><a href=\"#the-magical-vector-space\" aria-hidden=\"true\" class=\"anchor\" id=\"the-magical-vector-space\"></a>The magical vector space</h3>\n<p>After training Word2Vec, each word is a vector (e.g. 300 numbers). And this space has remarkable properties:</p>\n<p><strong>Similar words are close:</strong></p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">distance(&quot;cat&quot;, &quot;dog&quot;) &lt; distance(&quot;cat&quot;, &quot;car&quot;)\ndistance(&quot;France&quot;, &quot;Germany&quot;) &lt; distance(&quot;France&quot;, &quot;banana&quot;)\n</code></pre>\n<p><strong>Analogies work like adding and subtracting vectors:</strong></p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">vector(&quot;king&quot;) - vector(&quot;man&quot;) + vector(&quot;woman&quot;) ≈ vector(&quot;queen&quot;)\n</code></pre>\n<p>Why? Because the &quot;king&quot; vector encodes many semantic dimensions - in one of them is information about &quot;gender&quot; (man/woman), in another about &quot;power&quot; (monarchy). By subtracting &quot;man&quot; and adding &quot;woman&quot;, we change the gender dimension while keeping the rest.</p>\n<p>Other analogy examples:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">France - Paris + Berlin ≈ Germany\nsmall - smaller + big ≈ bigger\nboat - water + air ≈ airplane\n</code></pre>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"781.35175\" height=\"369\" viewBox=\"0 0 781.35175 369\"><rect x=\"0\" y=\"0\" width=\"781.35175\" height=\"369\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 437.818,80.000 L 437.818,89.625 Q 437.818,97.500 445.365,99.748 L 494.066,114.252 Q 501.614,116.500 501.614,124.375 L 501.614,134.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(501.61 134.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"317.20\" y=\"113.46\" width=\"167.20\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"400.81\" y=\"131.16\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"400.81\" dy=\"0.00\">&quot;subtract &apos;man&apos;&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 580.776,227.000 L 580.776,236.625 Q 580.776,244.500 582.486,252.187 L 583.292,255.813 Q 585.002,263.500 585.002,271.375 L 585.002,281.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(585.00 281.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"446.68\" y=\"237.68\" width=\"137.54\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"515.45\" y=\"255.38\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"515.45\" dy=\"0.00\">&quot;add &apos;woman&apos;&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 265.081,44.000 L 215.081,44.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 633.002,281.000 L 633.002,271.375 Q 633.002,263.500 640.877,263.500 L 755.352,263.500 Q 765.352,263.500 765.352,253.500 L 765.352,90.000 Q 765.352,80.000 755.352,80.000 L 625.701,80.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><rect x=\"265.08\" y=\"8.00\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"368.62\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"368.62\" dy=\"0.00\">👑 king</tspan><tspan x=\"368.62\" dy=\"21.00\">[0.50, 0.68, ...]</tspan></text><rect x=\"440.83\" y=\"134.00\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"570.33\" y=\"163.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"570.33\" dy=\"0.00\">[0.35, 0.55, ...]</tspan><tspan x=\"570.33\" dy=\"21.00\">&lt;i&gt;monarch, but without</tspan><tspan x=\"570.33\" dy=\"21.00\">gender&lt;/i&gt;</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"111.54\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"111.54\" dy=\"0.00\">👨 man</tspan><tspan x=\"111.54\" dy=\"21.00\">[0.15, 0.13, ...]</tspan></text><rect x=\"497.46\" y=\"281.00\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ccff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"601.00\" y=\"310.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"601.00\" dy=\"0.00\">👸 queen</tspan><tspan x=\"601.00\" dy=\"21.00\">[0.38, 0.64, ...]</tspan></text><rect x=\"522.16\" y=\"8.00\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ccff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"625.70\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"625.70\" dy=\"0.00\">👩 woman</tspan><tspan x=\"625.70\" dy=\"21.00\">[0.12, 0.20, ...]</tspan></text></svg></div>\n<p>This is what we talked about in the <a href=\"linguistic-features-and-llm.html\">first post</a> on the occasion of semantics. Now you see <strong>how it works under the hood</strong>.</p>\n<h3><a href=\"#word2vec-in-code\" aria-hidden=\"true\" class=\"anchor\" id=\"word2vec-in-code\"></a>Word2Vec in code</h3>\n<p>First let's train our own model on a small corpus to see how it works from scratch:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>gensim</a-v>.<a-v>models</a-v> <a-k>import</a-k> <a-cr>Word2Vec</a-cr>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;sits&quot;</a-s>, <a-s>&quot;on&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;mat&quot;</a-s>, <a-s>&quot;and&quot;</a-s>, <a-s>&quot;sleeps&quot;</a-s>],\n    [<a-s>&quot;dog&quot;</a-s>, <a-s>&quot;sits&quot;</a-s>, <a-s>&quot;on&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;rug&quot;</a-s>, <a-s>&quot;and&quot;</a-s>, <a-s>&quot;sleeps&quot;</a-s>],\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;runs&quot;</a-s>, <a-s>&quot;around&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;room&quot;</a-s>],\n    [<a-s>&quot;dog&quot;</a-s>, <a-s>&quot;runs&quot;</a-s>, <a-s>&quot;in&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;park&quot;</a-s>],\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;and&quot;</a-s>, <a-s>&quot;dog&quot;</a-s>, <a-s>&quot;play&quot;</a-s>, <a-s>&quot;in&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;garden&quot;</a-s>],\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;eats&quot;</a-s>, <a-s>&quot;kibble&quot;</a-s>, <a-s>&quot;from&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;bowl&quot;</a-s>],\n    [<a-s>&quot;dog&quot;</a-s>, <a-s>&quot;eats&quot;</a-s>, <a-s>&quot;kibble&quot;</a-s>, <a-s>&quot;from&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;bowl&quot;</a-s>],\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;catches&quot;</a-s>, <a-s>&quot;a&quot;</a-s>, <a-s>&quot;mouse&quot;</a-s>, <a-s>&quot;in&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;house&quot;</a-s>],\n    [<a-s>&quot;dog&quot;</a-s>, <a-s>&quot;chases&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;cat&quot;</a-s>, <a-s>&quot;in&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;garden&quot;</a-s>],\n    [<a-s>&quot;bird&quot;</a-s>, <a-s>&quot;sits&quot;</a-s>, <a-s>&quot;on&quot;</a-s>, <a-s>&quot;a&quot;</a-s>, <a-s>&quot;branch&quot;</a-s>, <a-s>&quot;of&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;tree&quot;</a-s>],\n    [<a-s>&quot;fish&quot;</a-s>, <a-s>&quot;swims&quot;</a-s>, <a-s>&quot;in&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;aquarium&quot;</a-s>],\n    [<a-s>&quot;car&quot;</a-s>, <a-s>&quot;drives&quot;</a-s>, <a-s>&quot;on&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;road&quot;</a-s>],\n    [<a-s>&quot;bike&quot;</a-s>, <a-s>&quot;rides&quot;</a-s>, <a-s>&quot;on&quot;</a-s>, <a-s>&quot;the&quot;</a-s>, <a-s>&quot;path&quot;</a-s>],\n    [<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;purrs&quot;</a-s>, <a-s>&quot;when&quot;</a-s>, <a-s>&quot;you&quot;</a-s>, <a-s>&quot;pet&quot;</a-s>, <a-s>&quot;it&quot;</a-s>],\n    [<a-s>&quot;dog&quot;</a-s>, <a-s>&quot;wags&quot;</a-s>, <a-s>&quot;its&quot;</a-s>, <a-s>&quot;tail&quot;</a-s>, <a-s>&quot;when&quot;</a-s>, <a-s>&quot;it&quot;</a-s>, <a-s>&quot;sees&quot;</a-s>, <a-s>&quot;its&quot;</a-s>, <a-s>&quot;owner&quot;</a-s>],\n]\n\n<a-v>model</a-v> <a-o>=</a-o> <a-f>Word2Vec</a-f>(\n    <a-v>sentences</a-v><a-o>=</a-o><a-v>corpus</a-v>,\n    <a-v>vector_size</a-v><a-o>=</a-o><a-n>10</a-n>,   <a-c># vector dimension (small = educational)</a-c>\n    <a-v>window</a-v><a-o>=</a-o><a-n>3</a-n>,         <a-c># context window size</a-c>\n    <a-v>min_count</a-v><a-o>=</a-o><a-n>1</a-n>,      <a-c># ignore words rarer than N</a-c>\n    <a-v>sg</a-v><a-o>=</a-o><a-n>0</a-n>,             <a-c># 0 = CBOW, 1 = Skip-gram</a-c>\n    <a-v>epochs</a-v><a-o>=</a-o><a-n>200</a-n>,       <a-c># how many passes over the data</a-c>\n)\n\n<a-f>print</a-f>(<a-v>model</a-v>.<a-pr>wv</a-pr>.<a-pr>most_similar</a-pr>(<a-s>&quot;cat&quot;</a-s>, <a-v>topn</a-v><a-o>=</a-o><a-n>3</a-n>))\n<a-c># [(&#39;dog&#39;, 0.96), (&#39;sleeps&#39;, 0.95), (&#39;on&#39;, 0.95)]</a-c>\n\n<a-f>print</a-f>(<a-v>model</a-v>.<a-pr>wv</a-pr>.<a-pr>similarity</a-pr>(<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;dog&quot;</a-s>))    <a-c># ~0.96</a-c>\n<a-f>print</a-f>(<a-v>model</a-v>.<a-pr>wv</a-pr>.<a-pr>similarity</a-pr>(<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;car&quot;</a-s>))    <a-c># ~0.83</a-c></code></pre>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p>Notice: our corpus is TINY (15 sentences), so the results are far from ideal - &quot;cat&quot; and &quot;car&quot; have as much as 0.83 similarity, which makes no sense. But the model correctly puts &quot;dog&quot; closest to &quot;cat&quot;! On real corpora (billions of sentences) these vectors become very accurate.</p>\n</div>\n<p>And here's how we use a <strong>pretrained model</strong> trained on billions of words:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>gensim</a-v>.<a-v>downloader</a-v> <a-k>import</a-k> <a-v>load</a-v>\n\n<a-v>model</a-v> <a-o>=</a-o> <a-f>load</a-f>(<a-s>&quot;glove-wiki-gigaword-50&quot;</a-s>)\n\n<a-v>result</a-v> <a-o>=</a-o> <a-v>model</a-v>.<a-pr>most_similar</a-pr>(\n    <a-v>positive</a-v><a-o>=</a-o>[<a-s>&quot;king&quot;</a-s>, <a-s>&quot;woman&quot;</a-s>],\n    <a-v>negative</a-v><a-o>=</a-o>[<a-s>&quot;man&quot;</a-s>],\n    <a-v>topn</a-v><a-o>=</a-o><a-n>5</a-n>\n)\n\n<a-k>for</a-k> <a-v>word</a-v>, <a-v>score</a-v> <a-o>in</a-o> <a-v>result</a-v>:\n    <a-f>print</a-f>(<a-s>f&quot;</a-s><a-p>{</a-p><a-v>word</a-v><a-p>}</a-p><a-s>: </a-s><a-p>{</a-p><a-v>score</a-v><a-eb>:.3f</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)\n\n<a-c># queen: 0.852</a-c>\n<a-c># throne: 0.737</a-c>\n<a-c># ...</a-c></code></pre>\n<p>You can also check the similarity between words:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-f>print</a-f>(<a-v>model</a-v>.<a-pr>similarity</a-pr>(<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;dog&quot;</a-s>))    <a-c># ~0.92</a-c>\n<a-f>print</a-f>(<a-v>model</a-v>.<a-pr>similarity</a-pr>(<a-s>&quot;cat&quot;</a-s>, <a-s>&quot;car&quot;</a-s>))    <a-c># ~0.15</a-c></code></pre>\n<p>&quot;Cat&quot; and &quot;dog&quot; - similarity 0.92. &quot;Cat&quot; and &quot;car&quot; - 0.15. The model &quot;knows&quot; that a cat is closer to a dog than to a car.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Experiment:</strong> Go to the <a href=\"https://projector.tensorflow.org/\">TensorFlow Embedding Projector</a> - it's an interactive visualization of the vector space. You can type words and see what's close. It's ONE of the most beautiful visualizations in all of ML. Seriously, check it out!</p>\n</div>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Watch out for bias:</strong> Word2Vec learns from data. If in the training data &quot;programmer&quot; appears more often near &quot;man&quot; than &quot;woman&quot; - the model will pick that up. A famous example: <code>vector(&quot;programmer&quot;) - vector(&quot;man&quot;) + vector(&quot;woman&quot;) ≈ &quot;homemaker&quot;</code>. That's a bias hidden in the data that the model unreflectively reproduces. Remember the semiosphere from the <a href=\"semiotics-and-llm.html\">second post</a>? The semiosphere isn't neutral - and neither is the training data.</p>\n</div>\n<h3><a href=\"#from-sparse-vectors-to-dense\" aria-hidden=\"true\" class=\"anchor\" id=\"from-sparse-vectors-to-dense\"></a>From sparse vectors to dense</h3>\n<p>Let's make the comparison again, to make it stick:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"741.849\" height=\"461\" viewBox=\"0 0 741.849 461\"><rect x=\"0\" y=\"0\" width=\"741.849\" height=\"461\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"717.85\" height=\"205.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"366.92\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"366.92\" dy=\"0.00\">BoW / TF-IDF: sparse</tspan><tspan x=\"366.92\" dy=\"21.00\">vector</tspan></text><rect x=\"8.00\" y=\"263.50\" width=\"674.59\" height=\"181.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"345.29\" y=\"291.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"345.29\" dy=\"0.00\">Word2Vec: dense vector</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 320.295,129.508 L 370.295,129.508\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(370.29 129.51) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 147.259,360.992 L 370.295,360.992\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(370.29 360.99) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"44.00\" y=\"335.48\" width=\"103.26\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"95.63\" y=\"364.48\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"95.63\" dy=\"0.00\">&apos;cat&apos;</tspan></text><rect x=\"370.29\" y=\"304.00\" width=\"276.29\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"508.44\" y=\"333.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"508.44\" dy=\"0.00\">[0.23, -0.45, 0.67, 0.12,</tspan><tspan x=\"508.44\" dy=\"21.00\">-0.89, ...]</tspan><tspan x=\"508.44\" dy=\"21.00\">Length = 300</tspan><tspan x=\"508.44\" dy=\"21.00\">All values NON-ZERO</tspan></text><rect x=\"44.00\" y=\"104.02\" width=\"276.29\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"182.15\" y=\"133.02\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"182.15\" dy=\"0.00\">&apos;The cat sits on the mat&apos;</tspan></text><rect x=\"370.29\" y=\"72.50\" width=\"319.55\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"530.07\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"530.07\" dy=\"0.00\">[0, 0, 1, 0, 0, 1, 0, 0, 1, 0,</tspan><tspan x=\"530.07\" dy=\"21.00\">0, 1, ...]</tspan><tspan x=\"530.07\" dy=\"21.00\">Length = vocabulary size</tspan><tspan x=\"530.07\" dy=\"21.00\">Mostly ZEROS</tspan></text></svg></div>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>BoW / TF-IDF</th>\n<th>Word2Vec</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Type</strong></td>\n<td>Sparse</td>\n<td>Dense</td>\n</tr>\n<tr>\n<td><strong>Vector length</strong></td>\n<td>= vocabulary size (can be 100 000+)</td>\n<td>= embedding dimension (usually 100-300)</td>\n</tr>\n<tr>\n<td><strong>Values</strong></td>\n<td>Mostly zeros</td>\n<td>All non-zero</td>\n</tr>\n<tr>\n<td><strong>Similarity</strong></td>\n<td>Hard to capture</td>\n<td>Cosine similarity works great</td>\n</tr>\n<tr>\n<td><strong>Context</strong></td>\n<td>None</td>\n<td>Captured through the context window</td>\n</tr>\n<tr>\n<td><strong>Analogies</strong></td>\n<td>None</td>\n<td>Work (king - man + woman ≈ queen)</td>\n</tr>\n</tbody>\n</table>\n<h3><a href=\"#can-word2vec-generate-text\" aria-hidden=\"true\" class=\"anchor\" id=\"can-word2vec-generate-text\"></a>Can Word2Vec generate text?</h3>\n<p>No. Word2Vec creates a <strong>map of meanings</strong> - it tells you that &quot;cat&quot; is close to &quot;dog&quot;, but it can't compose a sentence out of that. It's like a synonym dictionary: you know what's similar, but you won't write a poem.</p>\n<p>But... what if we combine Word2Vec with Markov chains? A Markov chain picks the next word based on frequency. And if instead of drawing equally, we make words more similar to the context have a higher chance?</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>gensim</a-v>.<a-v>models</a-v> <a-k>import</a-k> <a-cr>Word2Vec</a-cr>\n<a-k>import</a-k> <a-v>numpy</a-v> <a-k>as</a-k> <a-v>np</a-v>\n<a-k>from</a-k> <a-v>collections</a-v> <a-k>import</a-k> <a-v>defaultdict</a-v>\n<a-k>import</a-k> <a-v>random</a-v>\n\n<a-v>corpus</a-v> <a-o>=</a-o> [\n    <a-s>&quot;cat sits on the mat and sleeps&quot;</a-s>,\n    <a-s>&quot;dog sits on the rug and sleeps&quot;</a-s>,\n    <a-s>&quot;cat runs around the room&quot;</a-s>,\n    <a-s>&quot;dog runs in the park&quot;</a-s>,\n    <a-s>&quot;cat and dog play in the garden&quot;</a-s>,\n    <a-s>&quot;cat eats kibble from the bowl&quot;</a-s>,\n    <a-s>&quot;dog eats kibble from the bowl&quot;</a-s>,\n    <a-s>&quot;cat catches a mouse in the house&quot;</a-s>,\n    <a-s>&quot;dog chases the cat in the garden&quot;</a-s>,\n    <a-s>&quot;bird sits on a branch of the tree&quot;</a-s>,\n    <a-s>&quot;cat looks through the window and purrs&quot;</a-s>,\n    <a-s>&quot;dog barks at the mailman&quot;</a-s>,\n    <a-s>&quot;cat sleeps all day on the couch&quot;</a-s>,\n]\n\n<a-v>tokenized</a-v> <a-o>=</a-o> [<a-v>sentence</a-v>.<a-pr>split</a-pr>() <a-k>for</a-k> <a-v>sentence</a-v> <a-o>in</a-o> <a-v>corpus</a-v>]\n\n<a-v>w2v_model</a-v> <a-o>=</a-o> <a-f>Word2Vec</a-f>(<a-v>sentences</a-v><a-o>=</a-o><a-v>tokenized</a-v>, <a-v>vector_size</a-v><a-o>=</a-o><a-n>10</a-n>, <a-v>window</a-v><a-o>=</a-o><a-n>3</a-n>, <a-v>min_count</a-v><a-o>=</a-o><a-n>1</a-n>, <a-v>epochs</a-v><a-o>=</a-o><a-n>200</a-n>)\n\n<a-c># build the transition matrix (like in Markov chains)</a-c>\n<a-v>transitions</a-v> <a-o>=</a-o> <a-f>defaultdict</a-f>(<a-v>list</a-v>)\n<a-k>for</a-k> <a-v>sentence</a-v> <a-o>in</a-o> <a-v>tokenized</a-v>:\n    <a-k>for</a-k> <a-v>i</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-f>len</a-f>(<a-v>sentence</a-v>) <a-o>-</a-o> <a-n>1</a-n>):\n        <a-v>transitions</a-v>[<a-v>sentence</a-v>[<a-v>i</a-v>]].<a-pr>append</a-pr>(<a-v>sentence</a-v>[<a-v>i</a-v> <a-o>+</a-o> <a-n>1</a-n>])\n\n<a-k>def</a-k> <a-f>generate</a-f>(<a-v>start</a-v>, <a-v>length</a-v><a-o>=</a-o><a-n>6</a-n>):\n    <a-v>words</a-v> <a-o>=</a-o> [<a-v>start</a-v>]\n    <a-k>for</a-k> <a-v>_</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-v>length</a-v>):\n        <a-v>current</a-v> <a-o>=</a-o> <a-v>words</a-v>[<a-o>-</a-o><a-n>1</a-n>]\n        <a-k>if</a-k> <a-v>current</a-v> <a-o>not in</a-o> <a-v>transitions</a-v>:\n            <a-k>break</a-k>\n\n        <a-v>candidates</a-v> <a-o>=</a-o> <a-v>transitions</a-v>[<a-v>current</a-v>]\n\n        <a-c># averaged vector of the last words = context</a-c>\n        <a-v>context_vector</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>mean</a-pr>(\n            [<a-v>w2v_model</a-v>.<a-pr>wv</a-pr>[<a-v>w</a-v>] <a-k>for</a-k> <a-v>w</a-v> <a-o>in</a-o> <a-v>words</a-v>[<a-o>-</a-o><a-n>3</a-n>:] <a-k>if</a-k> <a-v>w</a-v> <a-o>in</a-o> <a-v>w2v_model</a-v>.<a-pr>wv</a-pr>],\n            <a-v>axis</a-v><a-o>=</a-o><a-n>0</a-n>,\n        )\n\n        <a-c># score candidates by similarity to the context</a-c>\n        <a-v>scored</a-v> <a-o>=</a-o> []\n        <a-k>for</a-k> <a-v>candidate</a-v> <a-o>in</a-o> <a-v>candidates</a-v>:\n            <a-k>if</a-k> <a-v>candidate</a-v> <a-o>in</a-o> <a-v>w2v_model</a-v>.<a-pr>wv</a-pr>:\n                <a-v>similarity</a-v> <a-o>=</a-o> <a-v>np</a-v>.<a-pr>dot</a-pr>(<a-v>context_vector</a-v>, <a-v>w2v_model</a-v>.<a-pr>wv</a-pr>[<a-v>candidate</a-v>]) <a-o>/</a-o> (\n                    <a-v>np</a-v>.<a-pr>linalg</a-pr>.<a-pr>norm</a-pr>(<a-v>context_vector</a-v>) <a-o>*</a-o> <a-v>np</a-v>.<a-pr>linalg</a-pr>.<a-pr>norm</a-pr>(<a-v>w2v_model</a-v>.<a-pr>wv</a-pr>[<a-v>candidate</a-v>]) <a-o>+</a-o> <a-n>1e-8</a-n>\n                )\n                <a-v>scored</a-v>.<a-pr>append</a-pr>((<a-v>candidate</a-v>, <a-v>similarity</a-v>))\n\n        <a-k>if</a-k> <a-v>scored</a-v>:\n            <a-c># draw, but with weights - similar words have a higher chance</a-c>\n            <a-v>weights</a-v> <a-o>=</a-o> [<a-v>score</a-v> <a-o>+</a-o> <a-n>1</a-n> <a-k>for</a-k> <a-v>_</a-v>, <a-v>score</a-v> <a-o>in</a-o> <a-v>scored</a-v>]\n            <a-v>chosen</a-v> <a-o>=</a-o> <a-v>random</a-v>.<a-pr>choices</a-pr>([<a-v>w</a-v> <a-k>for</a-k> <a-v>w</a-v>, <a-v>_</a-v> <a-o>in</a-o> <a-v>scored</a-v>], <a-v>weights</a-v><a-o>=</a-o><a-v>weights</a-v>, <a-v>k</a-v><a-o>=</a-o><a-n>1</a-n>)[<a-n>0</a-n>]\n            <a-v>words</a-v>.<a-pr>append</a-pr>(<a-v>chosen</a-v>)\n        <a-k>else</a-k>:\n            <a-v>words</a-v>.<a-pr>append</a-pr>(<a-v>random</a-v>.<a-pr>choice</a-pr>(<a-v>candidates</a-v>))\n    <a-k>return</a-k> <a-s>&quot; &quot;</a-s>.<a-pr>join</a-pr>(<a-v>words</a-v>)\n\n<a-k>for</a-k> <a-v>_</a-v> <a-o>in</a-o> <a-f>range</a-f>(<a-n>5</a-n>):\n    <a-f>print</a-f>(<a-f>generate</a-f>(<a-s>&quot;cat&quot;</a-s>))</code></pre>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">cat sits on the mat and sleeps\ncat looks through the window and purrs\ncat eats kibble from the bowl\ncat sleeps all day on the couch\ncat catches a mouse in the house\n</code></pre>\n<p>It's not Shakespeare, but the texts are more coherent than pure random Markov. The idea is simple:</p>\n<ol>\n<li>The Markov chain gives <strong>candidates</strong> for the next word</li>\n<li>Word2Vec <strong>scores</strong> the candidates based on similarity to the context</li>\n<li>We pick randomly, but with a <strong>bias</strong> - words that fit better have a higher chance</li>\n</ol>\n<p>This is a tiny step toward what today's LLMs do. They also predict the next word, but instead of a simple transition matrix they have multi-layer Transformer networks with an attention mechanism. There, &quot;scoring candidates&quot; is much, much more advanced.</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>The key difference:</strong> Word2Vec gives each word ONE vector. But &quot;bank&quot; in &quot;bank account&quot; and &quot;bank&quot; of a river are completely different meanings! Word2Vec doesn't distinguish them - that's why in the next posts we get into Transformers, where <strong>context changes the meaning</strong> of every word.</p>\n</div>\n<hr />\n<h2><a href=\"#summary---the-whole-path-in-one-place\" aria-hidden=\"true\" class=\"anchor\" id=\"summary---the-whole-path-in-one-place\"></a>Summary - the whole path in one place</h2>\n<p>Here's our roadmap, from cutting text to the geometry of meanings:</p>\n<table>\n<thead>\n<tr>\n<th>Method</th>\n<th>What it does</th>\n<th>Context?</th>\n<th>What it can't do</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Tokenization (BPE)</strong></td>\n<td>Cuts text into pieces</td>\n<td>No</td>\n<td>Doesn't understand what it cuts</td>\n</tr>\n<tr>\n<td><strong>BoW / TF-IDF</strong></td>\n<td>Counts words, weights by rarity</td>\n<td>No</td>\n<td>Ignores order</td>\n</tr>\n<tr>\n<td><strong>N-grams</strong></td>\n<td>Looks at word sequences</td>\n<td>Local (2-3 words)</td>\n<td>Short context, fast-growing vocabulary</td>\n</tr>\n<tr>\n<td><strong>Naive Bayes</strong></td>\n<td>Classifies based on probability</td>\n<td>No (words &quot;independent&quot;)</td>\n<td>Doesn't capture dependencies between words</td>\n</tr>\n<tr>\n<td><strong>Word2Vec</strong></td>\n<td>Turns words into meaning vectors</td>\n<td>Yes (context window)</td>\n<td>One word = one vector (ignores polysemy)</td>\n</tr>\n</tbody>\n</table>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"368.94678\" height=\"893.5\" viewBox=\"0 0 368.94678 893.5\"><rect x=\"0\" y=\"0\" width=\"368.94678\" height=\"893.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"344.95\" height=\"869.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"180.47\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"180.47\" dy=\"0.00\">Evolution: from counting</tspan><tspan x=\"180.47\" dy=\"21.00\">to understanding</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 180.474,144.500 L 180.474,198.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 198.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"62.74\" y=\"110.56\" width=\"157.32\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"141.39\" y=\"128.26\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"141.39\" dy=\"0.00\">&quot;how to count?&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 180.474,291.500 L 180.473,345.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 345.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"177.84\" y=\"303.04\" width=\"137.54\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.95\" stroke=\"#94A3B8\" stroke-opacity=\"0.45\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"246.61\" y=\"320.74\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"246.61\" dy=\"0.00\">&quot;no context!&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 180.473,417.500 L 180.473,471.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 471.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"67.21\" y=\"381.04\" width=\"226.53\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"180.47\" y=\"398.74\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"180.47\" dy=\"0.00\">&quot;we want to classify!&quot;</tspan></text></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 180.473,543.500 L 180.473,597.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(180.47 597.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"62.26\" y=\"507.04\" width=\"236.42\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"180.47\" y=\"524.74\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"180.47\" dy=\"0.00\">&quot;words aren&apos;t numbers!&quot;</tspan></text></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 196.473,690.500 L 196.473,744.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(196.47 744.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-4\" data-label-kind=\"center\" x=\"86.15\" y=\"654.04\" width=\"147.43\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-4\" data-label-kind=\"center\"><text x=\"159.87\" y=\"671.74\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"159.87\" dy=\"0.00\">&quot;what&apos;s next?&quot;</tspan></text></g><rect x=\"89.91\" y=\"198.50\" width=\"181.13\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"227.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">🔢 BoW / TF-IDF</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;pieces -&gt;</tspan><tspan x=\"180.47\" dy=\"21.00\">numbers&lt;/i&gt;</tspan></text><rect x=\"46.65\" y=\"744.50\" width=\"267.64\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"773.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"180.47\" dy=\"0.00\">🤖 Transformers / LLM</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;context + attention +</tspan><tspan x=\"180.47\" dy=\"21.00\">scale&lt;/i&gt;</tspan></text><rect x=\"68.28\" y=\"345.50\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"374.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">🔗 N-grams / Markov</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;adding order&lt;/i&gt;</tspan></text><rect x=\"38.00\" y=\"471.50\" width=\"284.95\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ccff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"500.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">📊 Naive Bayes</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;class probabilities&lt;/i&gt;</tspan></text><rect x=\"59.63\" y=\"72.50\" width=\"241.69\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">✂️ Tokenization</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;text -&gt; pieces&lt;/i&gt;</tspan></text><rect x=\"89.91\" y=\"597.50\" width=\"181.13\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ccff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"180.47\" y=\"626.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"180.47\" dy=\"0.00\">📐 Word2Vec</tspan><tspan x=\"180.47\" dy=\"21.00\">&lt;i&gt;geometry of</tspan><tspan x=\"180.47\" dy=\"21.00\">meanings&lt;/i&gt;</tspan></text></svg></div>\n<p>And the key perspective: <strong>from each of these methods, the LLM took something for itself.</strong></p>\n<ul>\n<li><strong>Tokenization (BPE)</strong> is the first step of every LLM's pipeline. ChatGPT cuts your text into tokens BEFORE it does anything with it.</li>\n<li><strong>TF-IDF and BoW</strong> are the foundations of thinking about text as numbers. Without that idea, that words can be &quot;counted&quot;, there would be no representation learning.</li>\n<li><strong>N-grams and Markov chains</strong> are the prototype of next-token prediction. That's exactly what an LLM does - except an LLM has a context of thousands of tokens, not 2-3.</li>\n<li><strong>Naive Bayes</strong> showed that a probabilistic approach to text works surprisingly well. An LLM is also a probabilistic model - it predicts the probability of the next token.</li>\n<li><strong>Word2Vec</strong> is the ancestor of what we today call the &quot;embedding layer&quot; in Transformers. GPT no longer uses Word2Vec as a separate step, but its embedding layer realizes the same idea: token -&gt; vector.</li>\n</ul>\n<p><strong>The LLM didn't fall from the sky. It stands on the shoulders of giants.</strong></p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>What's in the next post?</strong> We have word vectors - but how do we build something out of them that understands <strong>whole sentences</strong>? In the <a href=\"from-neurons-to-memory.html\">next post</a> we'll walk the whole path from a single neuron (perceptron, 1958), through MLP, RNN with the forgetting problem, to LSTM with memory gates. The evolution of architectures that prepared the ground for <strong>Transformers</strong> and ChatGPT. Stay tuned!</p>\n</div>\n<hr />\n<p>I know this post is a lot, but I wanted the path from &quot;cutting text&quot; to &quot;meaning vectors&quot; to be complete and understandable.</p>\n<p>I hope you'll say &quot;aha!&quot; at least a few times. If anything is unclear - <strong>let me know in the comments</strong>, I'll try to explain. And if you have better Word2Vec analogy examples - even more reason to let me know.</p>\n<p>Which method surprised you the most? Did you know that ChatGPT &quot;thinks&quot; in tokens, not words? And that its &quot;thinking&quot; is really a descendant of Markov chains?</p>\n<p>See you next time!</p>\n<hr />\n<p><strong>Sources and interesting links:</strong></p>\n<p>If you want to go deeper, here are the materials I used:</p>\n<ul>\n<li><a href=\"https://huggingface.co/learn/llm-course/chapter6/5\">Byte-Pair Encoding tokenization - Hugging Face</a> - a great, step-by-step introduction to BPE with code</li>\n<li><a href=\"https://huggingface.co/docs/transformers/en/tokenizer_summary\">Tokenization algorithms - Hugging Face</a> - an overview of BPE, WordPiece, Unigram, SentencePiece</li>\n<li><a href=\"https://sebastianraschka.com/blog/2025/bpe-from-scratch.html\">BPE Tokenizer From Scratch - Sebastian Raschka</a> - a BPE implementation from scratch in Python, very educational</li>\n<li><a href=\"https://codesignal.com/learn/courses/foundations-of-nlp-data-processing-2/lessons/introduction-to-tf-idf-vectorization-in-nlp\">Introduction to TF-IDF Vectorization in NLP - CodeSignal</a> - a readable introduction to TF-IDF with examples</li>\n<li><a href=\"https://stackabuse.com/python-for-nlp-developing-an-automatic-text-filler-using-n-grams/\">Python for NLP: Developing an Automatic Text Filler using N-grams - StackAbuse</a> - a great article on n-grams with a text generator</li>\n<li><a href=\"https://medium.com/in-pursuit-of-artificial-intelligence/brief-introduction-to-n-gram-and-tf-idf-tokenization-e58d22555bab\">Brief Introduction to N-gram and TF-IDF - Medium</a> - a comparison of TF-IDF vs n-grams with code</li>\n<li><a href=\"https://www.baeldung.com/cs/word-embeddings-cbow-vs-skip-gram\">Word Embeddings: CBOW vs Skip-Gram - Baeldung</a> - a clear comparison of both Word2Vec architectures</li>\n<li><a href=\"https://medium.com/data-science/nlp-101-word2vec-skip-gram-and-cbow-93512ee24314\">NLP 101: Word2Vec - Skip-gram and CBOW - Medium</a> - good pictures and intuition for Word2Vec</li>\n<li><a href=\"https://aclanthology.org/2020.aespen-1.6/\">TF-IDF Character N-grams versus Word Embedding-based Models - ACL Anthology</a> - a contrast between classic features and embeddings</li>\n<li><a href=\"https://projector.tensorflow.org/\">TensorFlow Embedding Projector</a> - an interactive visualization of the vector space (mandatory!)</li>\n</ul>\n<section class=\"footnotes\" data-footnotes>\n<ol>\n<li id=\"fn-1\">\n<p>Tokenization quiz answers: 1) &quot;lowest&quot; -&gt; [&quot;low&quot;, &quot;est&quot;] (l+o-&gt;lo, lo+w-&gt;low; &quot;e&quot; and &quot;s&quot; might be merged to &quot;es&quot;, then &quot;est&quot;? depends on the merges - with our merges &quot;es&quot; exists, so &quot;lowest&quot; -&gt; [&quot;low&quot;, &quot;es&quot;, &quot;t&quot;]). 2) &quot;newer&quot; -&gt; [&quot;new&quot;, &quot;er&quot;] (n+e-&gt;ne, ne+w-&gt;new; &quot;er&quot; is not merged in our dictionary). 3) &quot;widower&quot; -&gt; [&quot;w&quot;, &quot;i&quot;, &quot;d&quot;, &quot;o&quot;, &quot;w&quot;, &quot;er&quot;] or similar - &quot;widow&quot; isn't a merge we have, so it gets split (w+i+d+ow... but &quot;ow&quot; isn't merged either, only &quot;lo&quot;). The exact split depends on which merges made it into the dictionary. <a href=\"#fnref-1\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"1\" aria-label=\"Back to reference 1\">↩</a></p>\n</li>\n</ol>\n</section>\n",
      "summary": "\"From tokenization through TF-IDF and Markov chains, to Word2Vec. How a computer turns text into numbers so that language models can process it.\"",
      "date_published": "2026-06-09T00:00:00-00:00",
      "image": "",
      "authors": [
        {
          "name": "Blazej Gruszka",
          "url": "https://www.linkedin.com/in/blazejgruszka/",
          "avatar": "https://github.com/bgruszka.png"
        }
      ],
      "tags": [
        "llm",
        "ai",
        "nlp",
        "tokenization",
        "word2vec",
        "embeddings",
        "tf-idf",
        "markov",
        "bayes",
        "language-models"
      ],
      "language": "en"
    },
    {
      "id": "https://gruszka.dev/en/semiotics-and-llm.html",
      "url": "https://gruszka.dev/en/semiotics-and-llm.html",
      "title": "Semiotics - why an LLM doesn't \"think\", yet still means something",
      "content_html": "<p>In the previous post we built our linguistic onion - five layers, from phonetics to pragmatics, and we saw how an LLM handles each of them. But after writing that post, one big &quot;but...&quot; lingered in my head.</p>\n<p>Because - <strong>does an LLM even &quot;understand&quot; what it generates?</strong> Does it have some internal model of the world? Does it think?</p>\n<p>And then I stumbled into semiotics. And it turns out that semiotics gives us a brilliant frame for thinking about LLMs - not as an artificial mind, but as a <strong>machine of signs</strong>. And suddenly everything starts to make sense. Or at least it makes more sense than before ;-)</p>\n<p>This is the <strong>second post in the &quot;Understanding LLM&quot; series</strong>. Today we shift perspective: instead of looking at the <em>layers of language</em>, we look at the very nature of what <strong>signs</strong> are and how <strong>meaning</strong> comes into being at all. And why that is key to understanding what an LLM is - and what it is not.</p>\n<hr />\n<h2><a href=\"#what-is-semiotics\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-semiotics\"></a>What is semiotics?</h2>\n<p>Before we get to LLMs, we need to nail down the basics. Because &quot;semiotics&quot; is one of those words that sounds smart, but what does it actually mean?</p>\n<p><strong>Semiotics</strong> is the study of signs and of how signs create meaning. That's it. Doesn't sound so scary anymore, right? ;-)</p>\n<p>And a &quot;sign&quot; in semiotics is anything that <em>means something</em>. Something that stands for something else. Simple examples:</p>\n<ul>\n<li>🔴 A red light at an intersection = <strong>STOP</strong></li>\n<li>😂 A tears-of-joy emoji = <strong>I'm laughing</strong> (or: <em>I'm dying of laughter</em>)</li>\n<li>💨 The smell of smoke = <strong>a fire is somewhere nearby</strong></li>\n<li>🐾 Paw prints in the snow = <strong>a dog passed by here</strong> (or a wolf, or... better not think about it :D)</li>\n</ul>\n<p>Each of these signs <em>represents something else</em>. And that &quot;representing&quot; is exactly what semiotics studies.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Experiment:</strong> Look around you - how many signs do you see right now? At this moment I see: a WiFi icon (I have internet), a notification on my phone (someone texted), a logo on my coffee mug (a brand). Three signs and I didn't even get up from my chair.</p>\n</div>\n<h3><a href=\"#semiotics-vs-semantics\" aria-hidden=\"true\" class=\"anchor\" id=\"semiotics-vs-semantics\"></a>Semiotics vs semantics</h3>\n<p>In the previous post we had semantics - the study of the meaning of words and sentences. So how does semiotics differ?</p>\n<p>In short:</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>What it asks</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Semantics</strong></td>\n<td>&quot;What does this mean?&quot;</td>\n<td>What does the word &quot;zamek&quot; mean?</td>\n</tr>\n<tr>\n<td><strong>Semiotics</strong></td>\n<td>&quot;How does this sign even work?&quot;</td>\n<td>How is it that a red light MEANS &quot;stop&quot;?</td>\n</tr>\n</tbody>\n</table>\n<p>Semantics asks about specific meanings. Semiotics asks about the <strong>mechanism of meaning</strong> - how it is that anything means anything at all.</p>\n<p>And that is exactly why semiotics is so important for understanding LLMs. Because the question is not &quot;what does an LLM mean&quot;, but &quot;<strong>how an LLM operates on signs</strong>&quot;.</p>\n<hr />\n<h2><a href=\"#two-giants-saussure-vs-peirce\" aria-hidden=\"true\" class=\"anchor\" id=\"two-giants-saussure-vs-peirce\"></a>Two giants: Saussure vs Peirce</h2>\n<p>In semiotics there are two main traditions you need to know. Two approaches, two ways of thinking about signs. And note - both are important for understanding LLMs, but each from a different angle.</p>\n<h3><a href=\"#ferdinand-de-saussure-the-sign-as-a-pair\" aria-hidden=\"true\" class=\"anchor\" id=\"ferdinand-de-saussure-the-sign-as-a-pair\"></a>Ferdinand de Saussure: the sign as a pair</h3>\n<p>Saussure (a Swiss linguist, who lived at the turn of the 19th and 20th centuries) said: <strong>a sign consists of two parts</strong>.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"436.25037\" height=\"260\" viewBox=\"0 0 436.25037 260\"><rect x=\"0\" y=\"0\" width=\"436.25037\" height=\"260\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 163.170,105.784 L 173.435,105.784 Q 180.670,105.784 187.420,103.181 L 188.920,102.603 Q 195.670,100.000 202.904,100.000 L 213.170,100.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(213.17 100.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 163.170,150.781 L 173.898,150.781 Q 180.670,150.781 187.420,151.329 L 188.920,151.451 Q 195.670,152.000 202.442,152.000 L 213.170,152.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(213.17 152.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"213.17\" y=\"151.00\" width=\"189.78\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"308.06\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"308.06\" dy=\"0.00\">SIGNIFIED</tspan><tspan x=\"308.06\" dy=\"21.00\">&lt;i&gt;signifie&lt;/i&gt;</tspan><tspan x=\"308.06\" dy=\"21.00\">concept, idea</tspan></text><rect x=\"213.17\" y=\"8.00\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"316.71\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"316.71\" dy=\"0.00\">SIGNIFIER</tspan><tspan x=\"316.71\" dy=\"21.00\">&lt;i&gt;signifiant&lt;/i&gt;</tspan><tspan x=\"316.71\" dy=\"21.00\">form: sound, text</tspan></text><rect x=\"8.00\" y=\"89.76\" width=\"155.17\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"85.58\" y=\"118.76\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"85.58\" dy=\"0.00\">SIGN</tspan><tspan x=\"85.58\" dy=\"21.00\">&lt;i&gt;sign&lt;/i&gt;</tspan></text></svg></div>\n<ul>\n<li><strong>Signifier</strong> (signifiant) - the form of the sign. What you see, hear, touch. E.g. the sequence of letters &quot;c-a-t&quot; or the sound /kat/.</li>\n<li><strong>Signified</strong> (signifie) - the concept, the idea that this form triggers in your head. E.g. a furry animal that meows and ignores you for most of the day :D</li>\n</ul>\n<p>And the key thing: <strong>the relationship between signifier and signified is arbitrary</strong>. There is no logical reason why the sequence of letters &quot;c-a-t&quot; means that particular animal. It just... caught on. In Polish it's &quot;kot&quot;, in German &quot;Katze&quot;, in Japanese &quot;猫&quot; (neko) - every language has a different sequence of sounds/letters for the same concept.</p>\n<p>But Saussure says something even more important: <strong>the meaning of a word arises from its relationship to other words in the system</strong>. &quot;Cat&quot; means what it means because it is NOT &quot;dog&quot;, it is NOT &quot;house&quot;, it is NOT &quot;car&quot;. Meaning is <strong>differential</strong> - it arises from difference.</p>\n<blockquote>\n<p>This sounds abstract, but in a moment you'll see that this is <strong>exactly</strong> what embeddings do in an LLM. Really ;-)</p>\n</blockquote>\n<h3><a href=\"#charles-sanders-peirce-the-sign-as-a-process\" aria-hidden=\"true\" class=\"anchor\" id=\"charles-sanders-peirce-the-sign-as-a-process\"></a>Charles Sanders Peirce: the sign as a process</h3>\n<p>Peirce (an American philosopher, a bit earlier than Saussure, but roughly around the same time) had a different approach. For him a sign is not a static pair, but a <strong>dynamic process</strong>.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"696.58215\" height=\"281\" viewBox=\"0 0 696.58215 281\"><rect x=\"0\" y=\"0\" width=\"696.58215\" height=\"281\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 249.232,101.000 L 249.232,110.625 Q 249.232,118.500 241.818,121.155 L 214.751,130.845 Q 207.337,133.500 207.337,141.375 L 207.337,151.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(207.34 151.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 387.652,101.000 L 387.652,110.625 Q 387.652,118.500 395.063,121.163 L 421.982,130.837 Q 429.393,133.500 429.393,141.375 L 429.393,151.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(429.39 151.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 556.333,151.000 L 659.115,151.000 Q 669.115,151.000 669.115,141.000 L 669.115,86.500 Q 669.115,76.500 659.115,76.500 L 567.016,76.500 Q 559.141,76.500 559.141,68.625 L 559.141,59.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(559.14 59.00) rotate(-90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"455.76\" y=\"78.11\" width=\"206.76\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"559.14\" y=\"95.81\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"559.14\" dy=\"0.00\">&quot;creates a new sign&quot;</tspan></text></g><rect x=\"378.33\" y=\"151.00\" width=\"302.25\" height=\"114.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"529.46\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"529.46\" dy=\"0.00\">INTERPRETANT</tspan><tspan x=\"529.46\" dy=\"21.00\">&lt;i&gt;interpretation&lt;/i&gt;</tspan><tspan x=\"529.46\" dy=\"21.00\">the effect in the receiver&apos;s</tspan><tspan x=\"529.46\" dy=\"21.00\">mind</tspan></text><rect x=\"8.00\" y=\"151.00\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.50\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.50\" dy=\"0.00\">OBJECT</tspan><tspan x=\"137.50\" dy=\"21.00\">&lt;i&gt;object&lt;/i&gt;</tspan><tspan x=\"137.50\" dy=\"21.00\">what the sign refers to</tspan></text><rect x=\"203.86\" y=\"8.00\" width=\"198.43\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"303.07\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"303.07\" dy=\"0.00\">REPRESENTAMEN</tspan><tspan x=\"303.07\" dy=\"21.00\">&lt;i&gt;sign&lt;/i&gt;</tspan><tspan x=\"303.07\" dy=\"21.00\">the form you see</tspan></text><rect x=\"452.29\" y=\"8.00\" width=\"220.93\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"562.75\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"562.75\" dy=\"0.00\">NEW REPRESENTAMEN</tspan></text></svg></div>\n<p>Peirce's triad:</p>\n<ul>\n<li><strong>Representamen</strong> - the sign itself, the form (equivalent of Saussure's &quot;signifier&quot;)</li>\n<li><strong>Object</strong> - what the sign refers to (a thing in the world, a concept)</li>\n<li><strong>Interpretant</strong> - the effect the sign produces in the receiver's mind. And note: this interpretant ITSELF becomes a new sign, which again has its own interpretant, and so on... an <strong>infinite chain of interpretation</strong>.</li>\n</ul>\n<p>And that is the key difference: for Saussure a sign is static (a pair), for Peirce it is <strong>dynamic, alive, a process</strong>. Meaning is not &quot;contained&quot; in the sign - it arises in the process of interpretation.</p>\n<h3><a href=\"#three-kinds-of-signs-according-to-peirce\" aria-hidden=\"true\" class=\"anchor\" id=\"three-kinds-of-signs-according-to-peirce\"></a>Three kinds of signs according to Peirce</h3>\n<p>Peirce divided signs into three categories that are super intuitive:</p>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Description</th>\n<th>Examples</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Icon</strong></td>\n<td>A resemblance between the sign and the object</td>\n<td>A portrait, a map, the emoji 😺 (looks a bit like a cat), a folder icon on a computer</td>\n</tr>\n<tr>\n<td><strong>Index</strong></td>\n<td>A causal or physical connection</td>\n<td>Footprints in the sand (someone walked here), smoke (fire), a cough (illness), a thermometer (temperature)</td>\n</tr>\n<tr>\n<td><strong>Symbol</strong></td>\n<td>A convention, a social agreement</td>\n<td>The word &quot;cat&quot;, a national flag, a red light = stop, the mathematical &quot;=&quot;</td>\n</tr>\n</tbody>\n</table>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p>The word &quot;symbol&quot; in everyday language means something different than in Peirce's semiotics! In semiotics a symbol is a sign based <strong>purely on convention</strong> - it doesn't resemble the object (like an icon) and isn't physically tied to it (like an index). The Polish flag doesn't &quot;resemble&quot; Poland and isn't physically connected to it - we simply agreed that these colors stand for that country.</p>\n</div>\n<p>Test yourself - what type of sign is this?<sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\" data-footnote-ref>1</a></sup></p>\n<ol>\n<li>🌡️ A thermometer showing 37°C</li>\n<li>📸 A photo of your dog</li>\n<li>🟢 A green light = &quot;go&quot;</li>\n<li>🐾 Boot prints in the snow</li>\n<li>♿ An accessibility icon</li>\n</ol>\n<hr />\n<h2><a href=\"#hall-of-mirrors---or-the-llm-is-stuck-in-mirrors\" aria-hidden=\"true\" class=\"anchor\" id=\"hall-of-mirrors---or-the-llm-is-stuck-in-mirrors\"></a>Hall of Mirrors - or, the LLM is stuck in mirrors</h2>\n<p>David Manheim, an AI researcher, used a beautiful metaphor coming from Peirce's semiotics. He called it the <strong>&quot;Hall of Mirrors Problem&quot;</strong>.</p>\n<p>Imagine: you're in a room full of mirrors. You see reflections of reflections of reflections... and there's no window to the outside anywhere. You don't see the real world - you see only... more mirrors.</p>\n<p>That is exactly what an LLM does.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1451.2133\" height=\"170.66351\" viewBox=\"0 0 1451.2133 170.66351\"><rect x=\"0\" y=\"0\" width=\"1451.2133\" height=\"170.66351\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 189.125,118.660 L 334.278,118.660\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(334.28 118.66) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-0\" data-label-kind=\"center\" x=\"197.88\" y=\"120.56\" width=\"127.65\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-0\" data-label-kind=\"center\"><text x=\"261.70\" y=\"138.26\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"261.70\" dy=\"0.00\">&quot;experience&quot;</tspan></text></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 550.011,118.653 L 655.613,118.653\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(655.61 118.65) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-1\" data-label-kind=\"center\" x=\"558.76\" y=\"120.55\" width=\"88.10\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-1\" data-label-kind=\"center\"><text x=\"602.81\" y=\"138.25\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"602.81\" dy=\"0.00\">&quot;create&quot;</tspan></text></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 888.649,118.650 L 1038.649,118.650\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1038.65 118.65) rotate(-0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"904.77\" y=\"120.65\" width=\"117.77\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"963.65\" y=\"138.35\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"963.65\" dy=\"0.00\">&quot;trains on&quot;</tspan></text></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 1144.778,118.650 L 1280.043,118.650\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1280.04 118.65) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"1153.53\" y=\"88.35\" width=\"117.77\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"1212.41\" y=\"106.05\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1212.41\" dy=\"0.00\">&quot;generates&quot;</tspan></text></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 1341.628,93.150 L 1341.628,48.400 Q 1341.628,38.400 1331.628,38.400 L 830.131,38.400 Q 820.131,38.400 820.131,48.400 L 820.131,82.650\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(820.13 82.65) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-4\" data-label-kind=\"center\" x=\"965.28\" y=\"8.00\" width=\"167.20\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-4\" data-label-kind=\"center\"><text x=\"1048.88\" y=\"25.70\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1048.88\" dy=\"0.00\">&quot;flow back into&quot;</tspan></text></g><rect x=\"334.28\" y=\"82.66\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"442.14\" y=\"111.66\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"442.14\" dy=\"0.00\">🧑 People</tspan><tspan x=\"442.14\" dy=\"21.00\">&lt;i&gt;write texts&lt;/i&gt;</tspan></text><rect x=\"1038.65\" y=\"93.15\" width=\"106.13\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1091.71\" y=\"122.15\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1091.71\" dy=\"0.00\">🤖 LLM</tspan></text><rect x=\"655.61\" y=\"82.65\" width=\"233.04\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"772.13\" y=\"111.65\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"772.13\" dy=\"0.00\">📝 Texts</tspan><tspan x=\"772.13\" dy=\"21.00\">&lt;i&gt;training data&lt;/i&gt;</tspan></text><rect x=\"1280.04\" y=\"93.15\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1357.63\" y=\"122.15\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1357.63\" dy=\"0.00\">📝 New texts</tspan></text><rect x=\"8.00\" y=\"82.66\" width=\"181.13\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"98.56\" y=\"111.66\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"98.56\" dy=\"0.00\">🌍 World</tspan><tspan x=\"98.56\" dy=\"21.00\">&lt;i&gt;reality&lt;/i&gt;</tspan></text></svg></div>\n<p>Let's look at this through the lens of Peirce's triad:</p>\n<ul>\n<li><strong>Representamen</strong> (sign) - text, tokens, words - ✅ the LLM has access</li>\n<li><strong>Object</strong> (reality) - the world, experience, physics - ❌ the LLM has no access</li>\n<li><strong>Interpretant</strong> (interpretation) - understanding - ❓ the LLM generates something that <em>looks</em> like interpretation</li>\n</ul>\n<p>An LLM has never seen the world. It has never tasted a strawberry, never touched ice, never heard laughter. It draws all its &quot;knowledge&quot; about the world from text - from what <strong>other people wrote</strong> about the world.</p>\n<p>So when an LLM writes &quot;strawberries are sweet&quot; - it doesn't <em>know</em> they are sweet. It knows that in the texts it was trained on, the word &quot;strawberries&quot; often appears near the word &quot;sweet&quot;. That is the difference. And that is precisely the <strong>semiotic</strong> difference.</p>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Paradox:</strong> An LLM can write a beautiful description of a sunset, even though it has never seen the sun. But it can also write a beautiful description of a sunset <strong>on Mars</strong> - even though nobody has ever seen a sunset there yet. How does it &quot;know&quot;? From science fiction text. So: signs refer to signs, which refer to signs... a hall of mirrors ;-)</p>\n</div>\n<hr />\n<h2><a href=\"#saussure-in-code-embeddings-as-a-system-of-signs\" aria-hidden=\"true\" class=\"anchor\" id=\"saussure-in-code-embeddings-as-a-system-of-signs\"></a>Saussure in code: embeddings as a system of signs</h2>\n<p>OK, now what I promised - let's see how Saussure's theory plays out in code. Because this is <strong>genuinely</strong> fascinating.</p>\n<p>Remember what Saussure said? <strong>The meaning of a word arises from its relationship to other words</strong>. &quot;Cat&quot; means what it means because it isn't &quot;dog&quot;, it isn't &quot;house&quot;, etc. Meaning is relational.</p>\n<p>Now think about <strong>word embeddings</strong> - which we met in the previous post. Each word is represented as a vector in a high-dimensional space. And words with similar meanings are <strong>close</strong> to each other in that space.</p>\n<p>This is <strong>exactly</strong> Saussure's relational theory of the sign, just implemented in math!</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>gensim</a-v>.<a-v>downloader</a-v> <a-k>import</a-k> <a-v>load</a-v>\n\n<a-v>model</a-v> <a-o>=</a-o> <a-f>load</a-f>(<a-s>&quot;glove-wiki-gigaword-50&quot;</a-s>)\n\n<a-v>king</a-v> <a-o>=</a-o> <a-v>model</a-v>[<a-s>&quot;king&quot;</a-s>]\n<a-v>queen</a-v> <a-o>=</a-o> <a-v>model</a-v>[<a-s>&quot;queen&quot;</a-s>]\n<a-v>man</a-v> <a-o>=</a-o> <a-v>model</a-v>[<a-s>&quot;man&quot;</a-s>]\n<a-v>woman</a-v> <a-o>=</a-o> <a-v>model</a-v>[<a-s>&quot;woman&quot;</a-s>]\n\n<a-v>result</a-v> <a-o>=</a-o> <a-v>king</a-v> <a-o>-</a-o> <a-v>man</a-v> <a-o>+</a-o> <a-v>woman</a-v>\n\n<a-k>from</a-k> <a-v>gensim</a-v>.<a-v>models</a-v> <a-k>import</a-k> <a-cr>KeyedVectors</a-cr>\n<a-v>similarities</a-v> <a-o>=</a-o> <a-v>model</a-v>.<a-pr>cosine_similarities</a-pr>(<a-v>result</a-v>, [<a-v>queen</a-v>])\n<a-f>print</a-f>(<a-s>f&quot;Similarity to &#39;queen&#39;: </a-s><a-p>{</a-p><a-v>similarities</a-v><a-eb>[</a-eb><a-n>0</a-n><a-eb>]:.3f</a-eb><a-p>}</a-p><a-s>&quot;</a-s>)</code></pre>\n<p>It will print something like: <code>Similarity to 'queen': 0.850</code></p>\n<p>But look at this from Saussure's perspective:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"653.68677\" height=\"735\" viewBox=\"0 0 653.68677 735\"><rect x=\"0\" y=\"0\" width=\"653.68677\" height=\"735\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"299.69\" y=\"382.50\" width=\"338.00\" height=\"336.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"468.69\" y=\"411.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"468.69\" dy=\"0.00\">Word2Vec: word = vector</tspan><tspan x=\"468.69\" dy=\"21.00\">in a relational space</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"303.39\" height=\"294.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"159.70\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"159.70\" dy=\"0.00\">Saussure: sign = position</tspan><tspan x=\"159.70\" dy=\"21.00\">in a system of relations</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 160.429,165.500 L 160.429,175.464 Q 160.429,183.000 163.779,189.750 L 164.524,191.250 Q 167.874,198.000 167.874,205.536 L 167.874,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(167.87 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 467.340,540.000 L 467.340,550.642 Q 467.340,557.500 468.553,564.250 L 468.822,565.750 Q 470.034,572.500 470.034,579.358 L 470.034,590.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(470.03 590.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 167.874,266.500 L 167.874,284.000 L 167.874,555.000 Q 167.874,565.000 177.874,565.000 L 306.892,565.000 Q 316.892,565.000 316.892,575.000 L 316.892,583.125 Q 316.892,591.000 324.767,591.000 L 334.392,591.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(334.39 591.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-2\" data-label-kind=\"center\" x=\"95.42\" y=\"566.55\" width=\"177.09\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-2\" data-label-kind=\"center\"><text x=\"183.97\" y=\"584.25\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"183.97\" dy=\"0.00\">&quot;the same thing!&quot;</tspan></text></g><rect x=\"35.00\" y=\"72.50\" width=\"241.69\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"155.84\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"155.84\" dy=\"0.00\">&apos;king&apos; is not &apos;queen&apos;</tspan><tspan x=\"155.84\" dy=\"21.00\">&apos;king&apos; is not &apos;man&apos;</tspan><tspan x=\"155.84\" dy=\"21.00\">&apos;king&apos; is not &apos;woman&apos;</tspan></text><rect x=\"51.36\" y=\"215.50\" width=\"233.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"167.87\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"167.87\" dy=\"0.00\">meaning = difference</tspan></text><rect x=\"326.69\" y=\"447.00\" width=\"276.29\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"464.84\" y=\"476.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"464.84\" dy=\"0.00\">king = [0.50, 0.68, ...]</tspan><tspan x=\"464.84\" dy=\"21.00\">queen = [0.38, 0.64, ...]</tspan><tspan x=\"464.84\" dy=\"21.00\">man = [0.31, 0.43, ...]</tspan></text><rect x=\"334.39\" y=\"590.00\" width=\"276.29\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"472.54\" y=\"619.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"472.54\" dy=\"0.00\">meaning = the vector&apos;s</tspan><tspan x=\"472.54\" dy=\"21.00\">position</tspan><tspan x=\"472.54\" dy=\"21.00\">relative to other vectors</tspan></text></svg></div>\n<p>Both Saussure and Word2Vec say the same thing: <strong>meaning is not in the sign itself - it's in its relation to other signs</strong>. Saussure came up with this as a theory of language. Engineers at Google came up with Word2Vec as an algorithm. And they reached the same conclusion.</p>\n<p>Well... almost. Because there's one catch. Saussure assumed that behind the signifier (form) stands the <strong>signified</strong> (concept). In embeddings we only have a position in space - we have relations, but do we have a &quot;concept&quot;? Is the vector <code>[0.50, 0.68, ...]</code> <strong>the</strong> concept of &quot;king&quot;?</p>\n<p>And that is exactly the question that leads us to the next semiotician...</p>\n<hr />\n<h2><a href=\"#derrida-writing-as-the-foundation\" aria-hidden=\"true\" class=\"anchor\" id=\"derrida-writing-as-the-foundation\"></a>Derrida: writing as the foundation</h2>\n<p>Jacques Derrida (a French philosopher, 1960s and 70s) did something bold. He looked at all of Saussure and said: <strong>&quot;Wait. And why do you assume speech is more important than writing?&quot;</strong></p>\n<p>Saussure (and the entire Western philosophical tradition) treated speech as &quot;primary&quot; - closer to thought, closer to meaning. Writing was &quot;derivative&quot; - merely a record of speech, a &quot;sign of a sign&quot;. Derrida called this <strong>logocentrism</strong> - the belief that at the end of the chain of signs there is some &quot;presence&quot;, some &quot;thought&quot;, some &quot;intention&quot; that bestows meaning.</p>\n<p>And Derrida turned this upside down: <strong>writing is not subordinate to speech. Writing is a system in its own right.</strong></p>\n<p>Why does this matter for LLMs? Because Elad Vromen, in his paper &quot;Language Models as Semiotic Machines&quot;, noticed something brilliant:</p>\n<blockquote>\n<p>An LLM trains on <strong>writing</strong> (text). It builds a model of <strong>writing</strong>. It generates new <strong>writing</strong>. Nowhere in this process is there &quot;speech&quot;, &quot;mind&quot;, or &quot;intention&quot;. Saussure's entire hierarchy - speech &gt; writing - gets inverted. Writing is the only reality an LLM knows.</p>\n</blockquote>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"873.06335\" height=\"383.00885\" viewBox=\"0 0 873.06335 383.00885\"><rect x=\"0\" y=\"0\" width=\"873.06335\" height=\"383.00885\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"12.00\" y=\"203.51\" width=\"845.06\" height=\"163.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"434.53\" y=\"232.51\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"434.53\" dy=\"0.00\">LLM model (Derrida&apos;s</tspan><tspan x=\"434.53\" dy=\"21.00\">inversion)</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"686.16\" height=\"145.51\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"351.08\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"351.08\" dy=\"0.00\">Traditional model</tspan><tspan x=\"351.08\" dy=\"21.00\">(logocentrism)</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 168.563,98.000 L 192.563,98.001\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(192.56 98.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 330.429,98.001 L 354.429,98.002\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(354.43 98.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 492.295,98.004 L 516.295,98.004\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(516.29 98.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 281.036,304.007 L 305.036,304.008\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(305.04 304.01) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 589.983,304.008 L 613.983,304.009\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(613.98 304.01) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"48.00\" y=\"72.50\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"108.28\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"108.28\" dy=\"0.00\">🌍 World</tspan></text><rect x=\"192.56\" y=\"72.50\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"261.50\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"261.50\" dy=\"0.00\">🧠 Thought</tspan></text><rect x=\"354.43\" y=\"72.50\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"423.36\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"423.36\" dy=\"0.00\">🗣️ Speech</tspan></text><rect x=\"516.29\" y=\"72.51\" width=\"137.87\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"585.23\" y=\"101.51\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"585.23\" dy=\"0.00\">📝 Writing</tspan></text><rect x=\"48.00\" y=\"268.01\" width=\"233.04\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"164.52\" y=\"297.01\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"164.52\" dy=\"0.00\">📝 Writing</tspan><tspan x=\"164.52\" dy=\"21.00\">&lt;i&gt;training data&lt;/i&gt;</tspan></text><rect x=\"305.04\" y=\"268.01\" width=\"284.95\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"447.51\" y=\"297.01\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"447.51\" dy=\"0.00\">🧮 Model</tspan><tspan x=\"447.51\" dy=\"21.00\">&lt;i&gt;statistics of signs&lt;/i&gt;</tspan></text><rect x=\"613.98\" y=\"268.01\" width=\"207.08\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"717.52\" y=\"297.01\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"717.52\" dy=\"0.00\">📝 New writing</tspan><tspan x=\"717.52\" dy=\"21.00\">&lt;i&gt;LLM output&lt;/i&gt;</tspan></text></svg></div>\n<p>So when we ask &quot;does an LLM understand language?&quot; - we're asking a <strong>bad question</strong>. It's like asking &quot;does a book understand what is written in it?&quot; A book doesn't &quot;understand&quot; - but it <strong>contains signs</strong> that we - the readers - interpret. An LLM is something in between: it isn't a book (because it generates new text), but it isn't a mind either (because it has no access to meanings outside of text).</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>Derrida in a nutshell for LLMs:</strong> An LLM doesn't model a &quot;mind&quot; or a &quot;world&quot;. An LLM models <strong>writing</strong> - a system of signs that has its own logic, its own rules, its own coherence. And that writing is enough to generate text that <em>means something to us</em>. But it is <strong>us</strong> who give it meaning - not the model.</p>\n</div>\n<p>This also explains a phenomenon you've probably noticed: an LLM sometimes says things that are <strong>statistically correct, but nonsensical</strong>. Because in the system of writing the model operates in, those words fit together well. But we - as humans with access to the world (to objects in Peirce's sense) - see that it makes no sense. The model lacks that &quot;grounding&quot; in reality.</p>\n<details>\n<summary>For the curious: Derrida and iterability</summary>\n<p>Derrida, in his famous essay &quot;Signature Event Context&quot;, spoke of the <strong>iterability</strong> of signs - the fact that a sign can be repeated in a new context and take on new meaning. The word &quot;good&quot; can be a compliment, irony, or part of &quot;good evening&quot; - context changes everything.</p>\n<p>And that is exactly what we see in LLMs: the same prompt in a different context yields a different answer. The model doesn't &quot;understand&quot; context - but <strong>statistically</strong> it picks up contextual patterns from the training data. So: iterability of signs in its purest, mathematical form.</p>\n</details>\n<hr />\n<h2><a href=\"#the-prompt-as-a-semiotic-act\" aria-hidden=\"true\" class=\"anchor\" id=\"the-prompt-as-a-semiotic-act\"></a>The prompt as a semiotic act</h2>\n<p>Now we move onto very practical ground. Because if an LLM is a machine of signs, then a <strong>prompt</strong> - what you type into it - is a <strong>semiotic act</strong>. Not simply &quot;a command&quot;. But an act that creates the frame for meaning.</p>\n<h3><a href=\"#peirces-triad-in-practice\" aria-hidden=\"true\" class=\"anchor\" id=\"peirces-triad-in-practice\"></a>Peirce's triad in practice</h3>\n<p>Let's look at the interaction with an LLM through the lens of Peirce's triad:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"402.31592\" height=\"525\" viewBox=\"0 0 402.31592 525\"><rect x=\"0\" y=\"0\" width=\"402.31592\" height=\"525\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 133.170,101.000 L 133.170,151.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(133.17 151.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 149.170,223.000 L 149.170,273.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(149.17 273.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 149.170,366.000 L 149.170,416.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(149.17 416.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 245.362,446.500 L 329.025,446.500 Q 339.025,446.500 339.025,436.500 L 339.025,80.500 Q 339.025,70.500 329.025,70.500 L 249.688,70.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(249.69 70.50) rotate(180.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-3\" data-label-kind=\"center\" x=\"266.66\" y=\"448.50\" width=\"127.65\" height=\"28.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-3\" data-label-kind=\"center\"><text x=\"330.49\" y=\"466.20\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"330.49\" dy=\"0.00\">&quot;new prompt&quot;</tspan></text></g><rect x=\"8.00\" y=\"151.00\" width=\"250.34\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"133.17\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"133.17\" dy=\"0.00\">🤖 LLM</tspan><tspan x=\"133.17\" dy=\"21.00\">&lt;i&gt;sign processing&lt;/i&gt;</tspan></text><rect x=\"29.63\" y=\"273.00\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"133.17\" y=\"302.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"133.17\" dy=\"0.00\">💬 ANSWER</tspan><tspan x=\"133.17\" dy=\"21.00\">&lt;i&gt;new</tspan><tspan x=\"133.17\" dy=\"21.00\">representamen&lt;/i&gt;</tspan></text><rect x=\"16.65\" y=\"8.00\" width=\"233.04\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"133.17\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"133.17\" dy=\"0.00\">📝 PROMPT</tspan><tspan x=\"133.17\" dy=\"21.00\">&lt;i&gt;representamen&lt;/i&gt;</tspan><tspan x=\"133.17\" dy=\"21.00\">input sign</tspan></text><rect x=\"20.98\" y=\"416.00\" width=\"224.38\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"133.17\" y=\"445.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"133.17\" dy=\"0.00\">🧑 USER</tspan><tspan x=\"133.17\" dy=\"21.00\">&lt;i&gt;interpretant&lt;/i&gt;</tspan><tspan x=\"133.17\" dy=\"21.00\">assigns meaning</tspan></text></svg></div>\n<p>So:</p>\n<ol>\n<li><strong>You</strong> create the prompt (representamen)</li>\n<li><strong>The LLM</strong> processes signs and generates an answer (a new representamen)</li>\n<li><strong>You</strong> interpret the answer (you become the interpretant)</li>\n<li>Your interpretation leads to a new prompt... and the cycle repeats</li>\n</ol>\n<p>Notice: <strong>meaning arises only in step 3</strong>. The LLM generates a sequence of tokens, but it's you who gives it sense. This is exactly what Umberto Eco meant with his concept of the <strong>&quot;open work&quot;</strong> - a text doesn't have one fixed meaning. A text is a &quot;frame&quot; that the reader fills with interpretation.</p>\n<h3><a href=\"#experiment-how-a-prompt-changes-the-semiotic-frame\" aria-hidden=\"true\" class=\"anchor\" id=\"experiment-how-a-prompt-changes-the-semiotic-frame\"></a>Experiment: how a prompt changes the semiotic frame</h3>\n<p>Try it yourself. Fire up ChatGPT (or Claude, Gemini - whatever you have) and send these three prompts, each in a <strong>new conversation</strong>:</p>\n<ol>\n<li><code>&quot;Explain what gravity is.&quot;</code></li>\n<li><code>&quot;Explain gravity to a five-year-old.&quot;</code></li>\n<li><code>&quot;Explain gravity in the style of a Shakespearean sonnet.&quot;</code></li>\n</ol>\n<p>Each prompt is about the same topic (gravity). But each one <strong>changes the semiotic frame</strong> - it shifts the tone, the register, the genre, the expected form of the answer.</p>\n<table>\n<thead>\n<tr>\n<th>Prompt</th>\n<th>What changes...</th>\n<th>Semiotic frame</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>&quot;Explain gravity&quot;</td>\n<td>-</td>\n<td>Neutral, encyclopedic</td>\n</tr>\n<tr>\n<td>&quot;...to a five-year-old&quot;</td>\n<td>The audience, the simplicity of language</td>\n<td>Educational, age-appropriate</td>\n</tr>\n<tr>\n<td>&quot;...in the style of Shakespeare&quot;</td>\n<td>The genre, the form, the style</td>\n<td>Literary, artistic</td>\n</tr>\n</tbody>\n</table>\n<p>This is exactly what Picca calls the <strong>&quot;semiotic contract&quot;</strong>. When you write a prompt, you don't &quot;ask for information&quot; - <strong>you set the conditions under which meaning will be constructed</strong>. You ask for gravity in Shakespeare mode? You get a hybrid of physics and poetry. That's neither &quot;real&quot; gravity nor &quot;real&quot; Shakespeare - it's a <strong>semiotic collage</strong>, a new configuration of signs.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Bonus experiment:</strong> Try this: <em>&quot;Explain the concept of entropy using metaphors from fairy tales.&quot;</em> You'll see how an LLM connects two completely different semiotic zones - physics and fairy tales. That is exactly what semiotics calls <strong>translation between cultural codes</strong>.</p>\n</div>\n<hr />\n<h2><a href=\"#the-semiosphere---the-ecology-of-signs\" aria-hidden=\"true\" class=\"anchor\" id=\"the-semiosphere---the-ecology-of-signs\"></a>The semiosphere - the ecology of signs</h2>\n<p>One more concept worth knowing. Juri Lotman, a Russian semiotician, came up with the concept of the <strong>semiosphere</strong>.</p>\n<p>The semiosphere is the space in which signs live. It's an ecology of meanings - a network of cultural codes, genres, discourses, ideologies that interact with one another. Just as the biosphere is the space in which organisms live, the semiosphere is the space in which signs live.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1818.7339\" height=\"378.9\" viewBox=\"0 0 1818.7339 378.9\"><rect x=\"0\" y=\"0\" width=\"1818.7339\" height=\"378.9\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"189.40\" width=\"1794.73\" height=\"173.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"905.37\" y=\"216.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"905.37\" dy=\"0.00\">Semiosphere</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 752.753,185.600 L 752.753,195.225 Q 752.753,203.100 744.881,203.317 L 423.796,212.183 Q 415.924,212.400 415.924,220.275 L 415.924,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(415.92 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 799.945,185.600 L 799.945,195.225 Q 799.945,203.100 792.638,206.037 L 784.114,209.463 Q 776.807,212.400 776.807,220.275 L 776.807,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(776.81 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 974.170,185.600 L 974.170,195.225 Q 974.170,203.100 982.041,203.345 L 1265.398,212.155 Q 1273.269,212.400 1273.269,220.275 L 1273.269,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1273.27 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 768.753,185.600 L 768.753,190.880 Q 768.753,195.200 773.073,195.200 L 983.417,195.200 Q 984.137,195.200 984.137,194.480 L 984.137,194.320 Q 984.137,193.600 983.417,193.600 L 752.235,193.600 Q 743.753,193.600 743.753,185.118 L 743.753,183.232 Q 743.753,174.750 735.270,174.750 L 254.081,174.750 Q 244.081,174.750 244.081,184.750 L 244.081,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(244.08 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 914.654,185.600 L 914.654,195.225 Q 914.654,203.100 922.361,204.718 L 951.244,210.782 Q 958.951,212.400 958.951,220.275 L 958.951,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(958.95 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 975.137,185.600 L 975.137,195.225 Q 975.137,203.100 983.012,203.100 L 1496.091,203.100 Q 1506.091,203.100 1506.091,213.100 L 1506.091,229.900\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"   stroke-dasharray=\"4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1506.09 229.90) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 865.043,59.000 L 865.043,68.625 Q 865.043,76.500 864.830,84.372 L 864.158,109.228 Q 863.945,117.100 863.945,124.975 L 863.945,134.600\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(863.95 134.60) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect data-edge-id=\"edge-6\" data-label-kind=\"center\" x=\"866.99\" y=\"78.36\" width=\"256.19\" height=\"52.40\" rx=\"2\" ry=\"2\" fill=\"#FFFFFF\" fill-opacity=\"0.00\" stroke=\"#94A3B8\" stroke-opacity=\"0.00\" stroke-width=\"0.8\"/><g class=\"edgeLabel\" data-edge-id=\"edge-6\" data-label-kind=\"center\"><text x=\"995.09\" y=\"97.56\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"995.09\" dy=\"0.00\">&quot;navigates the</tspan><tspan x=\"995.09\" dy=\"21.00\">zones of the semiosphere&quot;</tspan></text></g><rect x=\"751.75\" y=\"134.60\" width=\"224.38\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"863.95\" y=\"163.60\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"863.95\" dy=\"0.00\">📊 LLM training data</tspan></text><rect x=\"38.00\" y=\"229.90\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"141.54\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"141.54\" dy=\"0.00\">💬 Internet</tspan><tspan x=\"141.54\" dy=\"21.00\">&lt;i&gt;forums, social</tspan><tspan x=\"141.54\" dy=\"21.00\">media&lt;/i&gt;</tspan></text><rect x=\"878.46\" y=\"229.90\" width=\"258.99\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1007.95\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1007.95\" dy=\"0.00\">🎭 Culture</tspan><tspan x=\"1007.95\" dy=\"21.00\">&lt;i&gt;film, art, music&lt;/i&gt;</tspan></text><rect x=\"586.77\" y=\"229.90\" width=\"241.69\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"707.61\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"707.61\" dy=\"0.00\">📚 Literature</tspan><tspan x=\"707.61\" dy=\"21.00\">&lt;i&gt;novels, poetry&lt;/i&gt;</tspan></text><rect x=\"811.98\" y=\"8.00\" width=\"106.13\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"865.04\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"865.04\" dy=\"0.00\">🤖 LLM</tspan></text><rect x=\"295.08\" y=\"229.90\" width=\"241.69\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"415.92\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"415.92\" dy=\"0.00\">📰 Media</tspan><tspan x=\"415.92\" dy=\"21.00\">&lt;i&gt;news, articles&lt;/i&gt;</tspan></text><rect x=\"1505.09\" y=\"229.90\" width=\"267.64\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1638.91\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1638.91\" dy=\"0.00\">⚖️ Law</tspan><tspan x=\"1638.91\" dy=\"21.00\">&lt;i&gt;statutes, rulings&lt;/i&gt;</tspan></text><rect x=\"1187.45\" y=\"229.90\" width=\"267.64\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1321.27\" y=\"258.90\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1321.27\" dy=\"0.00\">🔬 Science</tspan><tspan x=\"1321.27\" dy=\"21.00\">&lt;i&gt;papers, textbooks&lt;/i&gt;</tspan></text></svg></div>\n<p>An LLM's training data is nothing else but a <strong>giant cross-section of the semiosphere</strong>. When the model reads Wikipedia, Twitter, books, scientific papers, source code - it absorbs (statistically!) all that diversity of cultural codes.</p>\n<p>And that's why it can write in the style of Shakespeare, translate from German, joke like a comedian, and quote legal regulations - because all of that lives in the semiosphere, and the model has &quot;seen&quot; samples from every zone.</p>\n<p>But there's a flip side: the model also absorbs the <strong>prejudices, stereotypes, and dominant narratives</strong> contained in the semiosphere. Because the semiosphere isn't neutral - it's a cultural space with a history, with power, with ideology. And the LLM, operating on signs from that space, reproduces them in its outputs.</p>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Why does an LLM sometimes talk nonsense?</strong> Because the semiosphere is full of contradictions. On one page of the internet &quot;the earth is round&quot;, on another &quot;the earth is flat&quot;. The model sees both signs and has no access to the &quot;object&quot; (the actual earth) to decide which sign is true. It operates in a hall of mirrors - signs refer to signs, not to reality.</p>\n</div>\n<hr />\n<h2><a href=\"#quiz-saussure-or-peirce\" aria-hidden=\"true\" class=\"anchor\" id=\"quiz-saussure-or-peirce\"></a>Quiz: Saussure or Peirce?</h2>\n<p>Test which semiotician better explains these LLM phenomena. A reminder:</p>\n<ul>\n<li><strong>Saussure</strong>: sign = a pair (signifier + signified), relational meaning, a static system</li>\n<li><strong>Peirce</strong>: sign = a triad (representamen + object + interpretant), a process of interpretation, dynamics</li>\n</ul>\n<p>Who better explains the fact that...?<sup class=\"footnote-ref\"><a href=\"#fn-2\" id=\"fnref-2\" data-footnote-ref>2</a></sup></p>\n<ol>\n<li><strong>An LLM can write poetry, even though it has never felt poetry</strong> - Saussure or Peirce?</li>\n<li><strong>The embedding &quot;king&quot; - &quot;man&quot; + &quot;woman&quot; = &quot;queen&quot;</strong> - Saussure or Peirce?</li>\n<li><strong>The same prompt gives different answers depending on the context of the conversation</strong> - Saussure or Peirce?</li>\n<li><strong>An LLM has no access to the world, only to text</strong> - Saussure or Peirce?</li>\n<li><strong>We all know someone who asked ChatGPT for a medical diagnosis and got one</strong> - Saussure or Peirce?</li>\n</ol>\n<hr />\n<h2><a href=\"#summary---a-semiotic-map-of-the-llm\" aria-hidden=\"true\" class=\"anchor\" id=\"summary---a-semiotic-map-of-the-llm\"></a>Summary - a semiotic map of the LLM</h2>\n<p>Here's our semiotic map in a nutshell:</p>\n<table>\n<thead>\n<tr>\n<th>Semiotician</th>\n<th>Key concept</th>\n<th>What it tells us about LLMs</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Saussure</strong></td>\n<td>Meaning = relation between signs</td>\n<td>Embeddings realize the relational concept of the sign</td>\n</tr>\n<tr>\n<td><strong>Peirce</strong></td>\n<td>Triad sign-object-interpretant</td>\n<td>An LLM has no access to the object, only to signs (hall of mirrors)</td>\n</tr>\n<tr>\n<td><strong>Derrida</strong></td>\n<td>Writing as a system in itself</td>\n<td>An LLM models writing, not mind; training data = the only source</td>\n</tr>\n<tr>\n<td><strong>Lotman</strong></td>\n<td>Semiosphere - the ecology of signs</td>\n<td>Training data is a cross-section of the semiosphere; an LLM navigates its zones</td>\n</tr>\n<tr>\n<td><strong>Eco</strong></td>\n<td>The open work</td>\n<td>An LLM's output has no single meaning - it requires your interpretation</td>\n</tr>\n</tbody>\n</table>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1474.8566\" height=\"364.5\" viewBox=\"0 0 1474.8566 364.5\"><rect x=\"0\" y=\"0\" width=\"1474.8566\" height=\"364.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"1450.86\" height=\"340.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"733.43\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"733.43\" dy=\"0.00\">A semiotic perspective on</tspan><tspan x=\"733.43\" dy=\"21.00\">LLMs</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 994.835,144.500 L 994.835,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(994.83 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 698.830,165.500 L 698.830,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(698.83 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 1290.219,144.500 L 1290.219,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(1290.22 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 420.132,144.500 L 420.132,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(420.13 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 154.417,144.500 L 154.417,215.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(154.42 215.50) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"1177.54\" y=\"215.50\" width=\"224.38\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1289.73\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1289.73\" dy=\"0.00\">Training data</tspan><tspan x=\"1289.73\" dy=\"21.00\">= writing, not mind</tspan></text><rect x=\"1152.56\" y=\"72.50\" width=\"276.29\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1290.71\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"1290.71\" dy=\"0.00\">Derrida</tspan><tspan x=\"1290.71\" dy=\"21.00\">writing is the foundation</tspan></text><rect x=\"85.38\" y=\"72.50\" width=\"137.87\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"154.32\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"154.32\" dy=\"0.00\">Eco</tspan><tspan x=\"154.32\" dy=\"21.00\">open work</tspan></text><rect x=\"878.46\" y=\"215.50\" width=\"233.04\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"994.97\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"994.97\" dy=\"0.00\">Embeddings</tspan><tspan x=\"994.97\" dy=\"21.00\">vectors = relational</tspan><tspan x=\"994.97\" dy=\"21.00\">positions</tspan></text><rect x=\"569.46\" y=\"215.50\" width=\"258.99\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"698.96\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"698.96\" dy=\"0.00\">Hall of Mirrors</tspan><tspan x=\"698.96\" dy=\"21.00\">no access to the object</tspan></text><rect x=\"38.00\" y=\"215.50\" width=\"233.04\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"154.52\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"154.52\" dy=\"0.00\">Output requires</tspan><tspan x=\"154.52\" dy=\"21.00\">human interpretation</tspan></text><rect x=\"342.43\" y=\"72.50\" width=\"155.17\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"420.01\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"420.01\" dy=\"0.00\">Lotman</tspan><tspan x=\"420.01\" dy=\"21.00\">semiosphere</tspan></text><rect x=\"321.04\" y=\"215.50\" width=\"198.43\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"420.25\" y=\"244.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"420.25\" dy=\"0.00\">An LLM navigates</tspan><tspan x=\"420.25\" dy=\"21.00\">the zones of the</tspan><tspan x=\"420.25\" dy=\"21.00\">semiosphere</tspan></text><rect x=\"595.16\" y=\"72.50\" width=\"207.08\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"698.70\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"698.70\" dy=\"0.00\">Peirce</tspan><tspan x=\"698.70\" dy=\"21.00\">sign -&gt; object -&gt;</tspan><tspan x=\"698.70\" dy=\"21.00\">interpretant</tspan></text><rect x=\"886.83\" y=\"72.50\" width=\"215.73\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"994.70\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"994.70\" dy=\"0.00\">Saussure</tspan><tspan x=\"994.70\" dy=\"21.00\">meaning = relation</tspan></text></svg></div>\n<p>So: <strong>an LLM has no mind.</strong> But that doesn't mean it does nothing interesting. An LLM operates on signs - it reconfigures them, connects zones of the semiosphere, creates new configurations of signs. And those new configurations <strong>mean something to us - as interpreters</strong>.</p>\n<p>That is the semiotic answer to &quot;does an LLM understand?&quot;. An LLM doesn't &quot;understand&quot; in the human sense. But it generates signs that enter our semiosphere and become part of our process of interpretation. And that process is real, important, and powerful.</p>\n<hr />\n<p>I know semiotics sounds at first like something from another planet, but I hope you now see how it connects to LLMs.</p>\n<p>Which semiotic concept do you find most useful for understanding LLMs? Saussure and his relationality? Peirce and his hall of mirrors? Or maybe Derrida and his &quot;writing&quot;?</p>\n<p>Because frankly - I'm still learning this perspective myself. But I feel this is the moment where linguistics, philosophy, and programming meet in one place and create something genuinely fascinating.</p>\n<blockquote>\n<p><strong>What's in the next post?</strong> We move from theory to practice: <a href=\"how-computer-reads-text.html\">How a computer reads text - from counting words to vectors</a>. We'll see how tokenization, TF-IDF, Markov chains, and Word2Vec realize in code what Saussure (meaning is relational!) and Derrida (writing is a system in its own right!) were talking about.</p>\n</blockquote>\n<p>See you next time!</p>\n<hr />\n<p><strong>Sources and interesting links:</strong></p>\n<p>If you want to go deeper, here are the materials I used:</p>\n<ul>\n<li><a href=\"https://arxiv.org/abs/2505.17080\">Davide Picca, &quot;Not Minds, but Signs: Reframing LLMs through Semiotics&quot; - arXiv</a> - the main inspiration for this post; a proposal to look at LLMs as semiotic machines</li>\n<li><a href=\"https://arxiv.org/abs/2410.13065\">Elad Vromen, &quot;Language Models as Semiotic Machines&quot; - arXiv</a> - a brilliant connection of Saussure, Derrida, and embeddings</li>\n<li><a href=\"https://philpapers.org/rec/MANLMH-2\">David Manheim, &quot;Language Models' Hall of Mirrors Problem&quot; - PhilPapers</a> - the source of the &quot;hall of mirrors&quot; metaphor</li>\n<li><a href=\"https://arxiv.org/pdf/2509.14250.pdf\">&quot;Semiotic reflections and modelling&quot; - arXiv</a> - prompts as semiotic phenomena</li>\n<li><a href=\"https://www.emerald.com/jd/article/doi/10.1108/JD-03-2026-0140/1367688/The-meaning-of-prompts-a-semiotic-approach-to\">&quot;The meaning of prompts: a semiotic approach to human-LLM interaction&quot; - Emerald</a> - prompts as meaning-making acts</li>\n<li><a href=\"https://www.turtlesai.it/it/pages-391/a_semiotic_perspective_on_generative_ai_and_llms\">&quot;A Semiotic Perspective on Generative AI and LLMs&quot; - TurtlesAI</a> - an accessible introduction to the semiotics of generative AI</li>\n<li><a href=\"https://www.sciencedirect.com/science/article/pii/S1877042814057139\">&quot;The Semiotic Perspectives of Peirce and Saussure: A Brief Comparative Study&quot; - ScienceDirect</a> - a comparison of the two main semiotic traditions</li>\n<li><a href=\"https://www.linkedin.com/posts/ceperez_the-difference-between-semantics-and-semiotics-activity-7358534695254388737-gebY\">Carlos E. Perez, &quot;Semantics vs Semiotics: How LLMs Should Be Understood&quot; - LinkedIn</a> - a short post on why semiotics &gt; semantics for LLMs</li>\n</ul>\n<section class=\"footnotes\" data-footnotes>\n<ol>\n<li id=\"fn-1\">\n<p>Answers: 1) index (causal - temperature causes the liquid to expand), 2) icon (a resemblance to the dog), 3) symbol (pure convention), 4) index (a physical trace of someone who walked here), 5) icon (a resemblance to a person in a wheelchair). <a href=\"#fnref-1\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"1\" aria-label=\"Back to reference 1\">↩</a></p>\n</li>\n<li id=\"fn-2\">\n<p>My answers: 1) <strong>Peirce</strong> - the model has no access to the object (the experience of poetry), but it generates representamens (text) that we interpret. 2) <strong>Saussure</strong> - this is pure relationality! A king is defined by what it is not. 3) <strong>Peirce</strong> - context changes interpretation, and the interpretant creates a new sign. 4) <strong>Peirce</strong> - the absence of the object in the triad. 5) <strong>Peirce + Lotman</strong> - the model reproduces signs from the medical zone of the semiosphere without access to the real object (the patient's body). The diagnosis is a sign without grounding. <a href=\"#fnref-2\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"2\" aria-label=\"Back to reference 2\">↩</a></p>\n</li>\n</ol>\n</section>\n",
      "summary": "\"Saussure, Peirce and Derrida as the key to understanding LLMs. Why a model is not a mind, but a machine of signs - and why that is enough to generate meaningful text.\"",
      "date_published": "2026-06-07T00:00:00-00:00",
      "image": "",
      "authors": [
        {
          "name": "Blazej Gruszka",
          "url": "https://www.linkedin.com/in/blazejgruszka/",
          "avatar": "https://github.com/bgruszka.png"
        }
      ],
      "tags": [
        "llm",
        "ai",
        "semiotics",
        "signs",
        "linguistics",
        "language-models",
        "saussure",
        "peirce",
        "derrida"
      ],
      "language": "en"
    },
    {
      "id": "https://gruszka.dev/en/linguistic-features-and-llm.html",
      "url": "https://gruszka.dev/en/linguistic-features-and-llm.html",
      "title": "Linguistic features - what you need to know before you understand how an LLM thinks",
      "content_html": "<p>LLMs (Large Language Models, i.e. ChatGPT, Claude, Gemini and friends) have been with us for a while now, and I decided to dig deeper into the topic, and one big question came up: <strong>but how does it even work that a model &quot;understands&quot; language?</strong> After all, underneath it's just &quot;math and statistics&quot;, right? Well... yes and no ;-)</p>\n<p>And then I stumbled into linguistics. And it turned out that to truly understand what an LLM does with language, you first need to understand what language is made of. And since a programmer trying to read about linguistics is a rather funny picture, I thought: <strong>I'll share it with you</strong> ;-)</p>\n<p>This is the <strong>first post in a series</strong> in which we'll survey different levels of language analysis and see how it all connects to LLMs. In today's post we'll build the foundation - we'll get to know the five main layers of language and see why each of them matters for language models.</p>\n<hr />\n<h2><a href=\"#language-is-like-an-onion---layer-upon-layer\" aria-hidden=\"true\" class=\"anchor\" id=\"language-is-like-an-onion---layer-upon-layer\"></a>Language is like an onion - layer upon layer</h2>\n<p>Before we get into the details, imagine language as a sort of... onion. Or a layer cake, if you prefer sweet metaphors :D</p>\n<p>Each layer is a different level on which language &quot;works&quot;. From the lowest - sounds - to the highest - what we <em>really</em> meant to say, even when we said something completely different.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"282.9914\" height=\"647\" viewBox=\"0 0 282.9914 647\"><rect x=\"0\" y=\"0\" width=\"282.9914\" height=\"647\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 137.494,101.000 L 137.494,151.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(137.49 151.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 137.490,223.000 L 137.490,273.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(137.49 273.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 137.486,366.000 L 137.486,416.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(137.49 416.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 137.484,488.000 L 137.484,538.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(137.48 538.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"8.00\" y=\"8.00\" width=\"258.99\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.50\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.50\" dy=\"0.00\">🔊 Phonetics &amp; phonology</tspan><tspan x=\"137.50\" dy=\"21.00\">&lt;i&gt;sounds and the</tspan><tspan x=\"137.50\" dy=\"21.00\">system of sounds&lt;/i&gt;</tspan></text><rect x=\"16.65\" y=\"151.00\" width=\"241.69\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.49\" y=\"180.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.49\" dy=\"0.00\">🧩 Morphology</tspan><tspan x=\"137.49\" dy=\"21.00\">&lt;i&gt;word structure&lt;/i&gt;</tspan></text><rect x=\"51.25\" y=\"273.00\" width=\"172.47\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#ffff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.49\" y=\"302.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.49\" dy=\"0.00\">📐 Syntax</tspan><tspan x=\"137.49\" dy=\"21.00\">&lt;i&gt;sentence</tspan><tspan x=\"137.49\" dy=\"21.00\">structure&lt;/i&gt;</tspan></text><rect x=\"46.92\" y=\"416.00\" width=\"181.13\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.48\" y=\"445.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.48\" dy=\"0.00\">💡 Semantics</tspan><tspan x=\"137.48\" dy=\"21.00\">&lt;i&gt;meaning&lt;/i&gt;</tspan></text><rect x=\"51.25\" y=\"538.00\" width=\"172.47\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"137.48\" y=\"567.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"137.48\" dy=\"0.00\">🎭 Pragmatics</tspan><tspan x=\"137.48\" dy=\"21.00\">&lt;i&gt;meaning in</tspan><tspan x=\"137.48\" dy=\"21.00\">context&lt;/i&gt;</tspan></text></svg></div>\n<p>Five layers, five ways in which language gets &quot;analyzed&quot;. And note - <strong>an LLM has to handle each of these levels</strong> to come across as a sensible conversational partner. Of course it doesn't do this consciously - but the structures it learns during training somehow &quot;catch&quot; these layers.</p>\n<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p><strong>The five layers of language in a nutshell:</strong></p>\n<ol>\n<li><strong>Phonetics &amp; phonology</strong> - sounds and how they're organized into a system</li>\n<li><strong>Morphology</strong> - how words are built from smaller pieces</li>\n<li><strong>Syntax</strong> - the rules of word order in a sentence</li>\n<li><strong>Semantics</strong> - the meaning of words and sentences</li>\n<li><strong>Pragmatics</strong> - how context changes the meaning of an utterance</li>\n</ol>\n</div>\n<p>OK, let's get to it. We start at the bottom of our onion ;-)</p>\n<hr />\n<h2><a href=\"#phonetics-and-phonology---the-sounds-an-llm-never-hears\" aria-hidden=\"true\" class=\"anchor\" id=\"phonetics-and-phonology---the-sounds-an-llm-never-hears\"></a>Phonetics and phonology - the sounds an LLM never hears</h2>\n<h3><a href=\"#what-is-phonetics\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-phonetics\"></a>What is phonetics?</h3>\n<p><strong>Phonetics</strong> studies speech sounds as physical phenomena. Put simply: how we produce sounds, how they travel through the air, and how we receive them.</p>\n<p>It has three branches:</p>\n<table>\n<thead>\n<tr>\n<th>Branch</th>\n<th>What it studies</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Articulatory</strong></td>\n<td>How the speech organs produce sounds</td>\n<td>Where is your tongue when you say &quot;sh&quot;?</td>\n</tr>\n<tr>\n<td><strong>Acoustic</strong></td>\n<td>The physical properties of sound waves</td>\n<td>Frequency, amplitude</td>\n</tr>\n<tr>\n<td><strong>Auditory</strong></td>\n<td>How the ear and brain receive sounds</td>\n<td>How the cochlea turns waves into a nerve signal</td>\n</tr>\n</tbody>\n</table>\n<h3><a href=\"#and-phonology\" aria-hidden=\"true\" class=\"anchor\" id=\"and-phonology\"></a>And phonology?</h3>\n<p><strong>Phonology</strong> is a level up. It's not interested in sounds as physical phenomena, but in <strong>how sounds are organized in a particular language</strong>.</p>\n<p>Key concept: the <strong>phoneme</strong> - the smallest unit of sound that distinguishes the meaning of words.</p>\n<p>A simple example in English:</p>\n<ul>\n<li><strong>pat</strong> vs <strong>bat</strong> - the words differ by one sound (/p/ vs /b/), and the meaning is completely different</li>\n<li><strong>rat</strong> vs <strong>mat</strong> - /r/ vs /m/ again changes everything</li>\n</ul>\n<p>Or in Polish:</p>\n<ul>\n<li><strong>kot</strong> (cat) vs <strong>lot</strong> (flight) - /k/ vs /l/ and we have a totally different word</li>\n</ul>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>Experiment:</strong> Say &quot;cat&quot; out loud, once as a plain statement (&quot;My cat sleeps.&quot;), and once as a surprised question (&quot;Cat?!&quot; with raised eyebrows). The same word, but intonation, stress, and melody completely change what the listener &quot;hears&quot;. That is phonology in action - sounds + their organization in a system.</p>\n</div>\n<h3><a href=\"#why-does-this-matter-for-an-llm\" aria-hidden=\"true\" class=\"anchor\" id=\"why-does-this-matter-for-an-llm\"></a>Why does this matter for an LLM?</h3>\n<p>Right - <strong>an LLM gets text, not sound</strong>. It has never heard pronunciation. And yet...</p>\n<ul>\n<li>it knows that &quot;cat&quot; and &quot;hat&quot; rhyme (because it saw it in texts)</li>\n<li>it handles puns and wordplay based on sounds</li>\n<li>it can write rhyming poetry</li>\n</ul>\n<p>So the model somehow <strong>absorbs phonological information</strong> from text data alone. A bit like never having seen the ocean, but having read so many books about it that you can describe it ;-)</p>\n<p>But of course there are limitations. A text-based LLM can't distinguish homophones (words that sound the same but mean different things) based on phonetics - it handles them purely at the semantic level (more on that in a moment).</p>\n<p>And a fun fact: models like <strong>Whisper</strong> (speech-to-text from OpenAI) already connect phonetics with text. But that's a topic for a separate post in this series ;-)</p>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Paradox:</strong> An LLM has never heard a single sound, yet from training data it &quot;knows&quot; about rhymes, wordplay, and sound patterns. It's a bit like a person deaf from birth who can write rhyming poetry - because they've read millions of them.</p>\n</div>\n<hr />\n<h2><a href=\"#morphology---how-words-are-built-from-blocks\" aria-hidden=\"true\" class=\"anchor\" id=\"morphology---how-words-are-built-from-blocks\"></a>Morphology - how words are built from blocks</h2>\n<h3><a href=\"#what-is-morphology\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-morphology\"></a>What is morphology?</h3>\n<p><strong>Morphology</strong> studies the structure of words - how they're assembled from smaller, meaningful pieces called <strong>morphemes</strong>.</p>\n<p>A morpheme is the <strong>smallest unit of language that carries meaning</strong>. It can't be divided into anything smaller that would still carry meaning.</p>\n<p>An example from English, often used in textbooks:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">unhappiness = un + happy + ness\n               ↑       ↑       ↑\n            &quot;not&quot;   &quot;happy&quot;   makes a noun\n</code></pre>\n<p>Or in Polish:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">nieszczęśliwy = nie + szczęśliw + y\n                   ↑        ↑       ↑\n               &quot;not&quot;  &quot;happy/fortune&quot;  masculine gender\n</code></pre>\n<p>Or even more:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">nieprzystojny = nie + przy + stoj + ny\n              &quot;not&quot; + &quot;at&quot; + &quot;stand&quot; + adjective suffix\n</code></pre>\n<p>Each of these pieces has its own meaning. Those are morphemes.</p>\n<h3><a href=\"#two-kinds-of-morphemes\" aria-hidden=\"true\" class=\"anchor\" id=\"two-kinds-of-morphemes\"></a>Two kinds of morphemes</h3>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Description</th>\n<th>Examples</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Free</strong></td>\n<td>Can stand alone as a word</td>\n<td>cat, house, runs</td>\n</tr>\n<tr>\n<td><strong>Bound</strong></td>\n<td>Must be attached to another morpheme</td>\n<td>un-, -ness, -s, -ed</td>\n</tr>\n</tbody>\n</table>\n<p>And among bound morphemes we have <strong>affixes</strong>:</p>\n<ul>\n<li><strong>Prefixes</strong> (before the root): <em>un-</em>, <em>re-</em>, <em>pre-</em>, <em>dis-</em></li>\n<li><strong>Suffixes</strong> (after the root): <em>-ness</em>, <em>-ful</em>, <em>-ize</em>, <em>-ed</em></li>\n<li><strong>Infixes</strong> (inside the root): practically absent in English, but present in other languages! E.g. in Tagalog (Philippines): <em>sulat</em> (to write) -&gt; <em>s<strong>um</strong>ulat</em> (to write something) - the morpheme <em>-um-</em> is inserted into the middle of the root. Or think of the English <em>abso-bloody-lutely</em> ;-)</li>\n</ul>\n<h3><a href=\"#inflection-vs-derivation\" aria-hidden=\"true\" class=\"anchor\" id=\"inflection-vs-derivation\"></a>Inflection vs derivation</h3>\n<p>This is an important distinction:</p>\n<p><strong>Inflection</strong> - changes the grammatical form, but doesn't create a new word:</p>\n<ul>\n<li>house -&gt; house<strong>s</strong> (plural)</li>\n<li>run -&gt; ran (past tense)</li>\n</ul>\n<p><strong>Derivation</strong> (word formation) - creates a new word, often changing the part of speech:</p>\n<ul>\n<li>teach -&gt; <strong>teacher</strong> (verb -&gt; noun)</li>\n<li>house -&gt; <strong>household</strong> (noun -&gt; adjective/noun)</li>\n</ul>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>Polish morphology is a nightmare for an LLM!</strong> The Polish language is highly inflectional - we have 7 cases, 2 numbers, 3 genders, verb aspects, and tons of exceptions. For comparison: in English, declining a noun means at most adding <em>-s</em>. In Polish? &quot;Dom, domu, domowi, dom, domem, domu, domie, domy, domow...&quot; and so on :D</p>\n</div>\n<h3><a href=\"#how-does-an-llm-handle-morphology\" aria-hidden=\"true\" class=\"anchor\" id=\"how-does-an-llm-handle-morphology\"></a>How does an LLM handle morphology?</h3>\n<p>Here's a fun fact. An LLM doesn't &quot;know&quot; what morphemes are. It uses <strong>BPE tokenization</strong> (Byte Pair Encoding), which splits text into tokens - but tokens are <strong>not the same</strong> as morphemes.</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"542.85754\" height=\"335\" viewBox=\"0 0 542.85754 335\"><rect x=\"0\" y=\"0\" width=\"542.85754\" height=\"335\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"176.50\" width=\"518.86\" height=\"142.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"267.43\" y=\"205.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"267.43\" dy=\"0.00\">GPT-4o sees (BPE</tspan><tspan x=\"267.43\" dy=\"21.00\">tokenization):</tspan></text><rect x=\"8.00\" y=\"8.00\" width=\"492.90\" height=\"118.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"254.45\" y=\"35.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"254.45\" dy=\"0.00\">A linguist sees:</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 207.822,74.000 L 257.822,74.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(257.82 74.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 199.170,266.500 L 257.822,266.500\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(257.82 266.50) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"44.00\" y=\"48.50\" width=\"163.82\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"125.91\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"125.91\" dy=\"0.00\">un-happiness</tspan></text><rect x=\"257.82\" y=\"48.50\" width=\"207.08\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"361.36\" y=\"77.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"361.36\" dy=\"0.00\">un + happy + ness</tspan></text><rect x=\"44.00\" y=\"241.00\" width=\"155.17\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"121.58\" y=\"270.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"121.58\" dy=\"0.00\">unhappiness</tspan></text><rect x=\"257.82\" y=\"241.00\" width=\"233.04\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"374.34\" y=\"270.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"374.34\" dy=\"0.00\">un + h + app + iness</tspan></text></svg></div>\n<p>The BPE tokenizer splits text based on <strong>frequency of occurrence</strong> in the training data, not on linguistic structure. Sometimes that overlaps with morphemes, sometimes it doesn't.</p>\n<p>That means the model doesn't learn morphology &quot;directly&quot; - it learns it indirectly, through statistics. And somehow it works ;-)</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>A challenge for you:</strong> Can you break these words into morphemes?</p>\n<ul>\n<li><em>unbelievable</em></li>\n<li><em>antidisestablishmentarianism</em></li>\n<li><em>reimplementation</em></li>\n</ul>\n</div>\n<hr />\n<h2><a href=\"#syntax---the-rules-of-the-sentence-arranging-game\" aria-hidden=\"true\" class=\"anchor\" id=\"syntax---the-rules-of-the-sentence-arranging-game\"></a>Syntax - the rules of the sentence-arranging game</h2>\n<h3><a href=\"#what-is-syntax\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-syntax\"></a>What is syntax?</h3>\n<p><strong>Syntax</strong> is the set of rules that determine how words are combined into sentences. Thanks to syntax we know that &quot;The cat sits on the mat&quot; is a valid sentence, and &quot;The cat the on mat sits&quot; is gibberish.</p>\n<p>Simple? Well... more or less ;-)</p>\n<h3><a href=\"#word-order\" aria-hidden=\"true\" class=\"anchor\" id=\"word-order\"></a>Word order</h3>\n<p>Different languages have different word-order rules:</p>\n<table>\n<thead>\n<tr>\n<th>Language</th>\n<th>Basic order</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>English</td>\n<td>SVO (Subject-Verb-Object)</td>\n<td>The cat sits on the mat</td>\n</tr>\n<tr>\n<td>Polish</td>\n<td>&quot;Flexible&quot; SVO, but...</td>\n<td>Kot siedzi na macie / Na macie siedzi kot / Siedzi kot na macie</td>\n</tr>\n<tr>\n<td>Japanese</td>\n<td>SOV</td>\n<td>猫がマットの上に座っている</td>\n</tr>\n<tr>\n<td>Latin</td>\n<td>Free (because endings say everything)</td>\n<td>Felix in tapete sedet</td>\n</tr>\n</tbody>\n</table>\n<p>Polish is nice because we have quite a lot of freedom in word order. While in English &quot;On the mat sits the cat&quot; sounds poetic or unnatural, for us it's a normal sentence ;-)</p>\n<h3><a href=\"#the-syntax-tree\" aria-hidden=\"true\" class=\"anchor\" id=\"the-syntax-tree\"></a>The syntax tree</h3>\n<p>Sentences have a hierarchical structure - words group into phrases, and phrases into larger phrases. You can draw it as a tree:</p>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"791.7824\" height=\"479\" viewBox=\"0 0 791.7824 479\"><rect x=\"0\" y=\"0\" width=\"791.7824\" height=\"479\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 223.401,59.000 L 223.401,68.625 Q 223.401,76.500 215.799,78.553 L 175.463,89.447 Q 167.860,91.500 167.860,99.375 L 167.860,109.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(167.86 109.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 343.582,59.000 L 343.582,68.625 Q 343.582,76.500 351.163,78.631 L 389.363,89.369 Q 396.945,91.500 396.945,99.375 L 396.945,109.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(396.94 109.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 104.330,160.000 L 104.330,170.286 Q 104.330,177.500 101.785,184.250 L 101.219,185.750 Q 98.674,192.500 98.674,199.714 L 98.674,210.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(98.67 210.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 424.479,160.000 L 424.479,169.625 Q 424.479,177.500 417.210,180.528 L 395.732,189.472 Q 388.462,192.500 388.462,200.375 L 388.462,210.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(388.46 210.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-4\" class=\"edgePath\" data-edge-id=\"edge-4\" d=\"M 504.072,160.000 L 504.072,169.625 Q 504.072,177.500 511.094,181.065 L 526.591,188.935 Q 533.612,192.500 533.612,200.375 L 533.612,210.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(533.61 210.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-5\" class=\"edgePath\" data-edge-id=\"edge-5\" d=\"M 541.823,261.000 L 541.823,270.625 Q 541.823,278.500 535.962,283.760 L 530.969,288.240 Q 525.108,293.500 525.108,301.375 L 525.108,311.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(525.11 311.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-6\" class=\"edgePath\" data-edge-id=\"edge-6\" d=\"M 629.612,261.000 L 629.612,270.625 Q 629.612,278.500 636.207,282.804 L 645.999,289.196 Q 652.594,293.500 652.594,301.375 L 652.594,311.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(652.59 311.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-7\" class=\"edgePath\" data-edge-id=\"edge-7\" d=\"M 676.678,362.000 L 676.678,412.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(676.68 412.00) rotate(90.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"35.51\" y=\"210.00\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"95.79\" y=\"239.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"95.79\" dy=\"0.00\">The cat</tspan></text><rect x=\"616.51\" y=\"412.00\" width=\"120.56\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"676.79\" y=\"441.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"676.79\" dy=\"0.00\">the mat</tspan></text><rect x=\"8.00\" y=\"109.00\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#99ff99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"107.21\" y=\"138.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"107.21\" dy=\"0.00\">NP (noun phrase)</tspan></text><rect x=\"577.35\" y=\"311.00\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"676.57\" y=\"340.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"676.57\" dy=\"0.00\">NP (noun phrase)</tspan></text><rect x=\"448.67\" y=\"311.00\" width=\"77.44\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"487.39\" y=\"340.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"487.39\" dy=\"0.00\">on</tspan></text><rect x=\"443.46\" y=\"210.00\" width=\"276.29\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ff9999\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"581.61\" y=\"239.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"581.61\" dy=\"0.00\">PP (prepositional phrase)</tspan></text><rect x=\"202.14\" y=\"8.00\" width=\"163.82\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#9999ff\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"284.05\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#fff\"><tspan x=\"284.05\" dy=\"0.00\">S (sentence)</tspan></text><rect x=\"296.78\" y=\"210.00\" width=\"94.61\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"344.09\" y=\"239.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"344.09\" dy=\"0.00\">sits</tspan></text><rect x=\"357.26\" y=\"109.00\" width=\"198.43\" height=\"51.00\" rx=\"3\" ry=\"3\" fill=\"#ffcc99\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"456.48\" y=\"138.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#000\"><tspan x=\"456.48\" dy=\"0.00\">VP (verb phrase)</tspan></text></svg></div>\n<p>That's the simple sentence &quot;The cat sits on the mat&quot; and it already has its hierarchy! Now imagine sentences with subordinate clauses, participles, adverbials...</p>\n<h3><a href=\"#colorless-green-ideas-sleep-furiously\" aria-hidden=\"true\" class=\"anchor\" id=\"colorless-green-ideas-sleep-furiously\"></a>&quot;Colorless green ideas sleep furiously&quot;</h3>\n<p>This is a famous example from Noam Chomsky.</p>\n<p>The sentence is <strong>syntactically correct</strong> - it has a subject, a predicate, a proper structure. But <strong>semantically</strong> it's complete nonsense - ideas can't be green or sleep.</p>\n<p>And that's exactly the proof that <strong>syntax and semantics are two different levels</strong>. You can have perfect syntax and zero sense ;-)</p>\n<div class=\"markdown-alert markdown-alert-important\">\n<p class=\"markdown-alert-title\">Important</p>\n<p><strong>Syntax is an LLM's superpower.</strong> The model learns to predict the next token based on a huge amount of text data. In the process it absorbs syntactic patterns - it knows that after &quot;The cat sits on...&quot; we expect a noun, and after &quot;Quickly...&quot; a verb. This is the foundation of why an LLM generates grammatically correct sentences.</p>\n</div>\n<h3><a href=\"#quiz-correct-or-not\" aria-hidden=\"true\" class=\"anchor\" id=\"quiz-correct-or-not\"></a>Quiz: correct or not?</h3>\n<p>Test yourself - which sentences are syntactically correct?<sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\" data-footnote-ref>1</a></sup></p>\n<ol>\n<li>The dog barks at the mailman.</li>\n<li>At the mailman barks the dog.</li>\n<li>Barks the dog at the mailman.</li>\n<li>The dog the mailman at barks.</li>\n<li>Does the dog bark at the mailman?</li>\n</ol>\n<hr />\n<h2><a href=\"#semantics---what-does-meaning-even-mean\" aria-hidden=\"true\" class=\"anchor\" id=\"semantics---what-does-meaning-even-mean\"></a>Semantics - what does &quot;meaning&quot; even mean?</h2>\n<h3><a href=\"#what-is-semantics\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-semantics\"></a>What is semantics?</h3>\n<p>If syntax asks &quot;how is this built?&quot;, semantics asks: <strong>&quot;what does it mean?&quot;</strong></p>\n<p>Semantics studies the meaning of words, phrases, and sentences. And right away it turns out this isn't simple at all.</p>\n<h3><a href=\"#polysemy---one-word-many-meanings\" aria-hidden=\"true\" class=\"anchor\" id=\"polysemy---one-word-many-meanings\"></a>Polysemy - one word, many meanings</h3>\n<p>A classic English example: <strong>bank</strong></p>\n<ul>\n<li>Bank - a financial institution (&quot;I deposited money at the bank&quot;)</li>\n<li>Bank - the side of a river (&quot;The river bank was muddy&quot;)</li>\n<li>Bank - a row of similar things (&quot;A bank of computers&quot;)</li>\n<li>Bank - to tilt an aircraft (&quot;The plane banked to the left&quot;)</li>\n</ul>\n<p>The same word, four completely different meanings. How does an LLM know which one is meant? <strong>From context.</strong> And that's exactly what it does well - because it has seen millions of sentences where &quot;bank&quot; appeared in different contexts.</p>\n<p>Or another classic - polysemy within a single sentence:</p>\n<blockquote>\n<p>&quot;I can can the canning of cans.&quot;</p>\n</blockquote>\n<p>The word &quot;can&quot; three times, three different functions: <strong>can</strong> (be able to), <strong>can</strong> (the verb, to put in a can), <strong>can</strong> (the noun, a container). Context changes everything ;-)</p>\n<h3><a href=\"#synonyms---are-big-large-and-huge-the-same\" aria-hidden=\"true\" class=\"anchor\" id=\"synonyms---are-big-large-and-huge-the-same\"></a>Synonyms - are &quot;big&quot;, &quot;large&quot;, and &quot;huge&quot; the same?</h3>\n<p>Almost. But not quite:</p>\n<ul>\n<li><strong>A big house</strong> - normal, just sizable</li>\n<li><strong>A large house</strong> - sounds a bit more formal</li>\n<li><strong>A huge house</strong> - now that's a mansion :D</li>\n</ul>\n<p>Semantics studies these subtle differences - both <strong>denotation</strong> (literal meaning) and <strong>connotation</strong> (associations, emotional coloring).</p>\n<h3><a href=\"#how-does-an-llm-understand-meaning\" aria-hidden=\"true\" class=\"anchor\" id=\"how-does-an-llm-understand-meaning\"></a>How does an LLM &quot;understand&quot; meaning?</h3>\n<p>Here enters the concept of <strong>word embeddings</strong>. In broad terms: each word is represented as a vector - a sequence of numbers - in a high-dimensional space. Words with similar meanings are &quot;close&quot; to each other in that space.</p>\n<p>The famous example you've probably seen:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner\">vector(&quot;king&quot;) - vector(&quot;man&quot;) + vector(&quot;woman&quot;) ≈ vector(&quot;queen&quot;)\n</code></pre>\n<p>Meaning: the model &quot;knows&quot; that the relationship between &quot;king&quot; and &quot;man&quot; is analogous to the relationship between &quot;queen&quot; and &quot;woman&quot;. And it got that purely from data - nobody taught it that!</p>\n<p>We can even show this in code. Here's a simple example with the <code>gensim</code> library in Python:</p>\n<pre class=\"marmite-code\"><code class=\"marmite-code-inner language-python\"><a-k>from</a-k> <a-v>gensim</a-v>.<a-v>downloader</a-v> <a-k>import</a-k> <a-v>load</a-v>\n\n<a-v>model</a-v> <a-o>=</a-o> <a-f>load</a-f>(<a-s>&quot;glove-wiki-gigaword-50&quot;</a-s>)\n\n<a-v>result</a-v> <a-o>=</a-o> <a-v>model</a-v>.<a-pr>most_similar</a-pr>(\n    <a-v>positive</a-v><a-o>=</a-o>[<a-s>&quot;king&quot;</a-s>, <a-s>&quot;woman&quot;</a-s>],\n    <a-v>negative</a-v><a-o>=</a-o>[<a-s>&quot;man&quot;</a-s>],\n    <a-v>topn</a-v><a-o>=</a-o><a-n>3</a-n>\n)\n\n<a-f>print</a-f>(<a-v>result</a-v>)\n<a-c># [(&#39;queen&#39;, 0.85), ...]  -- in first place: queen!</a-c></code></pre>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>If you want to test this yourself:</strong> install <code>gensim</code> (<code>pip install gensim</code>) and run the code above. Of course you'll need some RAM - the GloVe model isn't small. But the result is genuinely satisfying ;-)</p>\n</div>\n<h3><a href=\"#compositionality\" aria-hidden=\"true\" class=\"anchor\" id=\"compositionality\"></a>Compositionality</h3>\n<p>One of the most important concepts in semantics: <strong>the meaning of a sentence is the result of the meanings of the individual words + the rules for combining them.</strong></p>\n<p>So: &quot;The red cat sits on the mat&quot; = [red] + [cat] + [sits] + [on] + [the mat] + syntactic rules.</p>\n<p>Sounds trivial, but it's a powerful principle. Thanks to it we can understand an infinite number of sentences, even ones we've never heard before. And thanks to it an LLM can generate new, never-before-seen sentences that still make sense.</p>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>But careful:</strong> &quot;I understood that you didn't understand that it wasn't understandable.&quot; - each word is simple, but the sentence as a whole requires analyzing it layer by layer. Compositionality is a powerful tool, but it has its limits.</p>\n</div>\n<hr />\n<h2><a href=\"#pragmatics---what-i-really-meant\" aria-hidden=\"true\" class=\"anchor\" id=\"pragmatics---what-i-really-meant\"></a>Pragmatics - what I really meant</h2>\n<h3><a href=\"#what-is-pragmatics\" aria-hidden=\"true\" class=\"anchor\" id=\"what-is-pragmatics\"></a>What is pragmatics?</h3>\n<p>And so we arrive at the most interesting layer (in my opinion). <strong>Pragmatics</strong> studies <strong>how context influences the meaning of an utterance</strong> - what we <em>really</em> want to say, often by saying something completely different.</p>\n<p>If semantics asks &quot;what does this mean?&quot;, pragmatics asks: <strong>&quot;what did the author mean in this particular situation?&quot;</strong></p>\n<h3><a href=\"#scenes-from-life\" aria-hidden=\"true\" class=\"anchor\" id=\"scenes-from-life\"></a>Scenes from life</h3>\n<p><strong>Scene 1: &quot;It's cold in here.&quot;</strong></p>\n<p>Semantically: information about the temperature in the room.\nPragmatically: <strong>&quot;Close the window!&quot;</strong> or <strong>&quot;Turn up the heating!&quot;</strong> or <strong>&quot;Give me a blanket.&quot;</strong></p>\n<p>Every one of you understands that when someone says &quot;It's cold in here&quot; while standing next to an open window - you don't ask about degrees Celsius, you just close the window.</p>\n<p><strong>Scene 2: &quot;Could you pass the salt?&quot;</strong></p>\n<p>Semantically: a question about your <em>ability</em> to pass the salt.\nPragmatically: <strong>a request to pass the salt.</strong></p>\n<p>Answering &quot;Yes, I could&quot; (and nothing more) is semantically correct, but pragmatically... well, you're being a bit rude ;-)</p>\n<p><strong>Scene 3: Irony</strong></p>\n<blockquote>\n<p>&quot;Well congratulations, you broke it again.&quot;</p>\n</blockquote>\n<p>Semantically: congratulations.\nPragmatically: <strong>irony, criticism, disappointment.</strong></p>\n<p>Does an LLM catch irony? Sometimes yes, sometimes no. It's still an open research problem.</p>\n<h3><a href=\"#speech-act-theory\" aria-hidden=\"true\" class=\"anchor\" id=\"speech-act-theory\"></a>Speech act theory</h3>\n<p>The philosopher J.L. Austin came up with something brilliant: <strong>utterances don't just describe reality, they also <em>do</em> things.</strong></p>\n<table>\n<thead>\n<tr>\n<th>Type of speech act</th>\n<th>Description</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Locutionary</strong></td>\n<td>The utterance itself</td>\n<td>You say &quot;I'm closing the window&quot;</td>\n</tr>\n<tr>\n<td><strong>Illocutionary</strong></td>\n<td>The intention of the utterance</td>\n<td>A promise to close the window</td>\n</tr>\n<tr>\n<td><strong>Perlocutionary</strong></td>\n<td>The effect on the listener</td>\n<td>The listener feels relieved</td>\n</tr>\n</tbody>\n</table>\n<p>Other examples of speech acts:</p>\n<ul>\n<li><strong>A promise:</strong> &quot;I promise I'll do it.&quot; - by saying it, you <em>perform</em> the act of promising</li>\n<li><strong>A declaration:</strong> &quot;I now pronounce you married.&quot; - someone must have the authority for it, but it works!</li>\n<li><strong>An apology:</strong> &quot;I'm sorry.&quot; - that's not a description of a state of affairs, it <em>is</em> the act of apologizing</li>\n</ul>\n<h3><a href=\"#grices-implicatures\" aria-hidden=\"true\" class=\"anchor\" id=\"grices-implicatures\"></a>Grice's implicatures</h3>\n<p>Paul Grice, another philosopher of language, noticed that conversation follows a <strong>cooperative principle</strong> - we say things that are relevant, true, clear, and on topic.</p>\n<p>When someone breaks that principle, we look for an <strong>implicature</strong> - a hidden meaning.</p>\n<p>Example:</p>\n<blockquote>\n<p>A: &quot;Are you going to the party?&quot;\nB: &quot;I have an exam tomorrow.&quot;</p>\n</blockquote>\n<p>B didn't answer &quot;yes&quot; or &quot;no&quot;. But from the context A understands: <strong>I'm not going, because I have to study.</strong> That's a conversational implicature.</p>\n<h3><a href=\"#how-does-an-llm-handle-pragmatics\" aria-hidden=\"true\" class=\"anchor\" id=\"how-does-an-llm-handle-pragmatics\"></a>How does an LLM handle pragmatics?</h3>\n<div class=\"markdown-alert markdown-alert-warning\">\n<p class=\"markdown-alert-title\">Warning</p>\n<p><strong>This is the hardest layer for an LLM.</strong> And that's not just my opinion - researchers all over the world are working on benchmarks that test the pragmatics of language models.</p>\n</div>\n<p>The problems:</p>\n<ul>\n<li><strong>Irony and sarcasm</strong> - the model often takes it literally</li>\n<li><strong>Implicatures</strong> - it doesn't always &quot;catch&quot; what's between the lines</li>\n<li><strong>Speech acts</strong> - it may not recognize whether someone is promising, asking, or threatening</li>\n<li><strong>Cultural context</strong> - what's polite in one culture is rude in another</li>\n</ul>\n<p>But on the other hand - GPT-4 and newer models are getting better and better. Why? Because <strong>the enormous amount of training data contains pragmatics in practice</strong> - dialogues from movies, books, internet forums. The model has &quot;seen&quot; millions of examples of irony, politeness, requests.</p>\n<div class=\"markdown-alert markdown-alert-tip\">\n<p class=\"markdown-alert-title\">Tip</p>\n<p><strong>An experiment for you:</strong> Open ChatGPT (or Claude, or whatever you have at hand) and run this short test:</p>\n<p>Tell the model:</p>\n<p><em>&quot;I just hammered my finger.&quot;</em></p>\n<p>Then, in a new conversation:</p>\n<p><em>&quot;Well congratulations, I hammered my finger again!&quot;</em></p>\n<p>See whether the model notices that in the second case &quot;congratulations&quot; is irony, or whether it starts calling an ambulance?</p>\n</div>\n<hr />\n<h2><a href=\"#summary---the-whole-onion-in-one-place\" aria-hidden=\"true\" class=\"anchor\" id=\"summary---the-whole-onion-in-one-place\"></a>Summary - the whole onion in one place</h2>\n<p>Here are our five layers, in a nutshell:</p>\n<table>\n<thead>\n<tr>\n<th>Layer</th>\n<th>What it studies</th>\n<th>Example</th>\n<th>How the LLM handles it</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Phonetics &amp; phonology</strong></td>\n<td>Sounds and the system of sounds</td>\n<td>/kat/ vs /hat/</td>\n<td>Never hears them, but &quot;knows&quot; from text data</td>\n</tr>\n<tr>\n<td><strong>Morphology</strong></td>\n<td>Word structure from morphemes</td>\n<td>un-happy-ness</td>\n<td>BPE tokenization != morphemes, but it works somehow</td>\n</tr>\n<tr>\n<td><strong>Syntax</strong></td>\n<td>Word order in a sentence</td>\n<td>The cat sits on the mat</td>\n<td>The model's superpower - handles grammar great</td>\n</tr>\n<tr>\n<td><strong>Semantics</strong></td>\n<td>Meaning of words and sentences</td>\n<td>&quot;bank&quot; - which one?</td>\n<td>Word embeddings + context</td>\n</tr>\n<tr>\n<td><strong>Pragmatics</strong></td>\n<td>Meaning in context</td>\n<td>&quot;It's cold&quot; = close the window</td>\n<td>The hardest layer, still an open problem</td>\n</tr>\n</tbody>\n</table>\n<div class=\"mermaid-diagram\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1209.4475\" height=\"211.5\" viewBox=\"0 0 1209.4475 211.5\"><rect x=\"0\" y=\"0\" width=\"1209.4475\" height=\"211.5\" fill=\"#FFFFFF\"/><defs><marker id=\"arrow-0\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker><marker id=\"arrow-start-0\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"1\" stroke-dasharray=\"1,0\"/></marker></defs><rect x=\"8.00\" y=\"8.00\" width=\"1185.45\" height=\"187.50\" rx=\"10\" ry=\"10\" fill=\"#F1F5F9\" stroke=\"#CBD5E1\" stroke-width=\"1\" /><text x=\"600.72\" y=\"37.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"600.72\" dy=\"0.00\">How an LLM processes</tspan><tspan x=\"600.72\" dy=\"21.00\">language</tspan></text><path id=\"edge-0\" class=\"edgePath\" data-edge-id=\"edge-0\" d=\"M 220.473,135.000 L 244.473,135.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(244.47 135.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-1\" class=\"edgePath\" data-edge-id=\"edge-1\" d=\"M 494.813,135.000 L 518.813,135.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(518.81 135.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-2\" class=\"edgePath\" data-edge-id=\"edge-2\" d=\"M 673.983,135.000 L 697.983,135.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(697.98 135.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><path id=\"edge-3\" class=\"edgePath\" data-edge-id=\"edge-3\" d=\"M 956.974,135.000 L 980.974,135.000\" fill=\"none\" stroke=\"#64748B\" stroke-width=\"2\"    stroke-linecap=\"round\" stroke-linejoin=\"round\" /><g transform=\"translate(980.97 135.00) rotate(0.00)\"><polygon points=\"0,0 -7.50,3.90 -7.50,-3.90\" fill=\"#64748B\" stroke=\"#64748B\" stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></g><rect x=\"48.00\" y=\"83.00\" width=\"172.47\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"134.24\" y=\"112.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"134.24\" dy=\"0.00\">Phonetics</tspan><tspan x=\"134.24\" dy=\"21.00\">❌ never hears</tspan></text><rect x=\"244.47\" y=\"72.50\" width=\"250.34\" height=\"93.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"369.64\" y=\"101.50\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"369.64\" dy=\"0.00\">Morphology</tspan><tspan x=\"369.64\" dy=\"21.00\">⚠️ through the lens of</tspan><tspan x=\"369.64\" dy=\"21.00\">tokens</tspan></text><rect x=\"980.97\" y=\"83.00\" width=\"172.47\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"1067.21\" y=\"112.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"1067.21\" dy=\"0.00\">Pragmatics</tspan><tspan x=\"1067.21\" dy=\"21.00\">❓ the hardest</tspan></text><rect x=\"518.81\" y=\"83.00\" width=\"155.17\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"596.40\" y=\"112.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"596.40\" dy=\"0.00\">Syntax</tspan><tspan x=\"596.40\" dy=\"21.00\">✅ very well</tspan></text><rect x=\"697.98\" y=\"83.00\" width=\"258.99\" height=\"72.00\" rx=\"3\" ry=\"3\" fill=\"#F8FAFC\" stroke=\"#94A3B8\" stroke-width=\"1\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"827.48\" y=\"112.00\" text-anchor=\"middle\" font-family=\"Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,DejaVu Sans,Liberation Sans,sans-serif,Noto Color Emoji,Apple Color Emoji,Segoe UI Emoji\" font-size=\"14\" fill=\"#0F172A\"><tspan x=\"827.48\" dy=\"0.00\">Semantics</tspan><tspan x=\"827.48\" dy=\"21.00\">✅ well, with exceptions</tspan></text></svg></div>\n<h3><a href=\"#whats-next\" aria-hidden=\"true\" class=\"anchor\" id=\"whats-next\"></a>What's next?</h3>\n<p>In the next post we change perspective - instead of looking at the layers of language, we look at the very nature of signs and meaning:</p>\n<ul>\n<li><strong><a href=\"semiotics-and-llm.html\">Semiotics - why an LLM doesn't &quot;think&quot;, yet still means something</a></strong></li>\n</ul>\n<hr />\n<p>If you made it all the way here - <strong>thanks!</strong> ;-) I really appreciate that you took the time to read this monster.</p>\n<p>I hope I brought the topic a little closer to you. If anything is unclear - <strong>let me know in the comments</strong>, I'll try to explain. And if you have better examples (and you surely do!) - even more reason to let me know.</p>\n<p>Which layer surprised you the most? Which do you find the most interesting in the context of AI?</p>\n<p>See you in the next post!</p>\n<hr />\n<p><strong>Sources and interesting links:</strong></p>\n<p>If you want to go deeper, here are the materials I used when writing this post:</p>\n<ul>\n<li><a href=\"https://fiveable.me/introduction-study-language/unit-1/branches-linguistics/study-guide/Bbhz9eKIobWh0O9F\">Branches of linguistics - Fiveable</a> - a great overview of linguistics subfields with examples</li>\n<li><a href=\"https://fiveable.me/lists/levels-of-linguistic-analysis\">Levels of Linguistic Analysis - Fiveable</a> - a synthesis of the levels of language analysis</li>\n<li><a href=\"https://relay.libguides.com/science-of-teaching-reading-resource-guide/five-language-domains\">The Five Language Domains - Relay Graduate School</a> - a simple, didactic take on the five language domains</li>\n<li><a href=\"https://www.zenml.io/llmops-database/linguistic-informed-approach-to-production-llm-systems\">Linguistic-Informed Approach to Production LLM Systems - ZenML</a> - a bridge between linguistics and LLM practice</li>\n<li><a href=\"https://www.stat.lmu.de/soda/en/research/research-projects/evaluating-large-language-models-on-linguistic-competence/\">Evaluating Large Language Models on Linguistic Competence - LMU Munich</a> - how the linguistic competence of models is studied</li>\n<li><a href=\"https://arxiv.org/abs/2502.12378\">Pragmatics in the Era of LLMs: A Survey - arXiv</a> - a survey of research on pragmatics in LLMs</li>\n</ul>\n<section class=\"footnotes\" data-footnotes>\n<ol>\n<li id=\"fn-1\">\n<p>Quiz answers: sentences 1 and 5 are correct. Sentence 1 has standard SVO order. Sentence 5 is a grammatical question formed with the auxiliary &quot;does&quot;. Sentences 2 and 3 are understandable but sound archaic or poetic - English allows such inversions only in limited stylistic contexts, unlike Polish where flexible word order is the norm. Sentence 4 (&quot;The dog the mailman at barks&quot;) is syntactically incorrect - the word order is so jumbled it violates the rules of English grammar. <a href=\"#fnref-1\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"1\" aria-label=\"Back to reference 1\">↩</a></p>\n</li>\n</ol>\n</section>\n",
      "summary": "\"Five layers of language - phonetics, morphology, syntax, semantics, pragmatics - and how an LLM handles each of them.\"",
      "date_published": "2026-06-06T00:00:00-00:00",
      "image": "",
      "authors": [
        {
          "name": "Blazej Gruszka",
          "url": "https://www.linkedin.com/in/blazejgruszka/",
          "avatar": "https://github.com/bgruszka.png"
        }
      ],
      "tags": [
        "llm",
        "ai",
        "nlp",
        "linguistics",
        "language-models",
        "chatgpt"
      ],
      "language": "en"
    }
  ]
}