{
  "source_file": "0930",
  "source_platform": "个人博客",
  "author": "3Blue1Brown",
  "title_listed": "What is backpropagation really doing?",
  "keywords": "反向传播,可视化,训练",
  "domain": "机器学习",
  "content_type": "视频/教程",
  "is_paid_flag": "否",
  "url": "https://www.3blue1brown.com/lessons/backpropagation",
  "publish_date": "2017",
  "corpus_stage": "机器学习",
  "notes": "反向传播可视化",
  "id": "57a52b5580f8",
  "collected_at": "2026-10-02T15:17:53",
  "title": "What is backpropagation really doing? | 3Blue1Brown",
  "body_markdown": "Neural Networks\nChapter\n4\nW\nh\na\nt\ni\ns\nb\na\nc\nk\np\nr\no\np\na\ng\na\nt\ni\no\nn\nr\ne\na\nl\nl\ny\nd\no\ni\nn\ng\n?\nAn overview of backpropagation, the algorithm behind how neural networks learn.\nNov 3, 2017\nLesson\nby\nGrant Sanderson\nText adaptation\nby\nJosh Pullen\nSource\nHere we tackle backpropagation, the core algorithm behind how neural networks learn. If you followed the last two lessons or if you're jumping in with the appropriate background, you know what a neural network is and how it feeds forward information.\nQuick Recap\nWe've been looking at the classic example of recognizing handwritten digits. I've been showing a network with...\nAn input layer of 784 neurons (which represent the pixel values of the image)\nTwo hidden layers with 16 neurons each\nAn output layer with 10 neurons (indicating the network's choice of digit)\nOur basic neural network has four layers: An input layer, an output layer, and\ntwo hidden layers in between.\nWe've also discussed\ngradient descent\n, so you should know that when people describe a network as \"learning,\" they mean finding the weights and biases that minimize a certain cost function.\nWe use gradient descent to walk downhill to a local minimum of the cost\nfunction.\nTo calculate the cost of a single training example, you take the output that the network gives, along with the output you wanted it to give, and you add up the squares of the differences between each component:\nThe cost for a single training example is the sum of the squares of the\ndifferences between the actual output and the desired output.\nDoing this for all your tens of thousands of training examples, and averaging all the results, gives you the total cost of the network.\nWhat is Backpropagation?\nRemember, the negative gradient of the cost function is a 13,002-dimensional vector that tells us how to nudge all the weights and biases to decrease the cost most efficiently.\nBackpropagation, the topic of this lesson, is an algorithm for computing that negative gradient.\nThinking about the gradient vector as a direction in a 13,002-dimensional space is, to put it lightly, beyond the scope of our imaginations.\nDirection in 13,002 dimensions?!?\nSo as we talked about in the previous lesson, it's helpful to consider it this way: The magnitude of each component of the gradient tells you how\nsensitive\nthe cost function is to each corresponding weight and bias.\nFor example, let's say you compute the negative gradient, using the process I'm about to describe, and the component associated with the weight on one edge comes out to be 3.2, while the component associated with some other edge is 0.1:\nSuppose the entry of the gradient vector associated with one weight is 32x as\nlarge as the entry associated with some other weight.\nThe way to read this is that the cost function is 32 times more sensitive to changes to that first weight. So if you were to wiggle the value of that weight a bit, it'll cause a change to the cost function 32 times greater than what the same wiggle to the second weight would cause.\nThe Intuition for Backpropagation\nWhen I first learned backpropagation, the most confusing aspect was just the notation and index chasing of it all.\nThere's a lot of notation here. What does it all mean!?\nFor this article, let's begin with a complete disregard for notation and instead step through the effect that each training example has on the weights and biases. Hopefully, these effects will feel intuitive so that by the time we return to the notation, it acts to articulate something you already know, rather than acting as a code to be decrypted.\nBecause the full cost function involves averaging a certain cost-per-example for all the tens of thousands of training examples, the way we adjust all the weights and biases for a single gradient descent step also depends on\nevery single example\n. Or, rather, in principle it should, but for computational efficiency, we'll do a little trick later to keep you from needing to hit every single example for every single step.\nRight now, though, focus your attention on a single example, this image of a 2:\nHow can we adjust the weights and biases to improve the network's performance\non this image?\nWhat effect does this one training example have on how the weights and biases should be adjusted?\nBecause the network is not yet well trained, the activations in that output layer are effectively random. That's no good; we want to change these activations so that they properly identify the digit 2.\nBut remember, we only have control over the weights and biases of the network. So we will have to nudge those weights and biases in a way that improves the output.\nThe activations in the output layer are trash, and we need to fix them by\nadjusting the weights and biases.\nAlthough we can't\ndirectly\nchange the activations, it's helpful to keep track of what adjustments we\nwish\nto take place in this output layer.\nSince we want the network to classify this as a 2, we want the digit 2 neuron's value to be nudged up while all the others get nudged down:\nMoreover, the sizes of these nudges should be proportional to how far off each output value is from the target. Neurons that are way off require big nudges, but neurons that are pretty close to correct only require little nudges.\nZooming in further, let's focus on the one neuron whose activation we wish to increase:\nRemember that its activation value (in this case 0.2) is defined as a weighted sum of all activations from the previous layer, plus a bias, which is then plugged into something like the sigmoid squishification or a ReLU:\nSo there are three avenues that can team up together to increase this activation:\nIncrease the\nbias\nIncrease the\nweights\nChange the\nactivations\nfrom the previous layer\nChanging the Bias\nChanging the bias associated with a neuron is the simplest way to change its activation. Unlike changing the weights or the activations from the previous layer, the effect of a change to the bias on the weighted sum is constant and predictable.\nSince we want to increase the activation of the digit-2 output neuron we've been discussing, how should its associated bias be adjusted? What about the biases associated with all the other output neurons for this training example?\nIncrease\nthe bias associated with the digit-2 neuron and\nincrease\nthe biases associated with all the other neurons.\nIncrease\nthe bias associated with the digit-2 neuron and\ndecrease\nthe biases associated with all the other neurons.\nDecrease\nthe bias associated with the digit-2 neuron and\nincrease\nthe biases associated with all the other neurons.\nDecrease\nthe bias associated with the digit-2 neuron and\ndecrease\nthe biases associated with all the other neurons.\nCheck\nWhat could it be...\nChanging the Weights\nHow should the weights be adjusted? Notice, because they are being multiplied by the activations, the weights have differing levels of influence:\nChanging the weights associated with large activation values will have a\nstronger effect than changing the weights associated with small activation\nvalues.\nThe connections with the brightest neurons from the preceding layer have the biggest effect since those weights are multiplied by larger activation values. So increasing one of those weights has a bigger influence on the cost function than increasing the weight of a connection with a dimmer neuron. (Again, this is all only insofar as this one training example is concerned.)\nRemember, when we talk about gradient descent, we don't just care about whether each component should be nudged up or down. We care about which ones give you the most bang for your buck.\nChanging the Weights\nTo get the most bang for your buck, adjust the weights in proportion to their\nassociated activations.\nThis, by the way, is at least somewhat reminiscent of a theory in neuroscience for how biological networks of neurons learn, Hebbian theory, often summed up in the phrase \"neurons that fire together wire together.\" Here, the biggest increases in weights—the biggest strengthening of connections—happens between neurons that are the most active and the ones which we wish to become more active.\nIn some sense, the neurons that fire while seeing a 2 get more strongly linked to those firing while thinking about a 2.\nConnections are strengthened between neurons that should be activated at the\nsame time.\nThe analogy is not perfect since the untrained network is not really \"thinking\" about a 2 when it sees this example; it's more that the label on the training data is hardcoding what the network\nshould\nbe thinking about. Still, it's satisfying to know that buried beneath all the calculus and linear algebra typically used to describe backpropagation, the actual changes happening to the weights with each training example mirror the ideas of Hebbian theory.\nChanging the Activations\nThe third way we can help increase this neuron's activation is by changing all the activations in the previous layer. Namely, if everything connected to that digit-2 neuron with a positive weight was brighter, and if everything connected with a negative weight was dimmer, that digit-2 neuron would be more active.\nSimilar to the weight changes, you'll get the most bang for your buck by seeking changes proportional to the size of the corresponding weights:\nJust like changing weights in proportion to activations, you get the most bang\nfor your buck by increasing activations in proportion to their associated\nweights.\nOf course, we cannot directly influence these activations. We only have control over the weights and biases. But just as with the last layer, it's helpful to keep note of the desired changes.\nWe can't influence the activations in the previous layer directly. But we can\nchange the weights and biases that determine their values!\nRemember, this is only what that one digit-2 output neuron wants. We also want all the other neurons in the last layer to become less active, and each of those other output neurons has its own influence on what should happen to the second-to-last layer.\nWe want to adjust all these other output neurons too, which means we will have\nmany competing requests for changes to activations in the previous layer.\nSo the desire of this digit-2 neuron is added together with the desires of all the other nine neurons. Each has its own suggested nudge for that second-to-last layer, again in proportion to the corresponding weights and in proportion to how much each neuron needs to change.\nIt's impossible to perfectly satisfy all these competing desires for\nactivations in the second layer. The best we can do is add up all the desired\nnudges to find the overall desired change.\nHere is where the idea of propagating backward comes in. By adding all these desired effects, you can get a list of the nudges you want to happen to this second-to-last layer. From there, you can recursively apply the same process to the relevant weights and biases determining those values, repeating this process as you move backward through the network.\nRepeating for All Training Examples\nEverything we just stepped through only records how a\nsingle\ntraining example wishes to nudge each of the many, many weights and biases.\nSo far we've only identified the nudges to the weights and biases that would\nimprove our results for this digit 2. But we also need to account for all the\nother digits!\nIf we only listened to what that image of a 2 wanted, the network would ultimately be incentivized to just classify all images as a 2.\nTo zoom out a bit, you also go through this same backpropagation routine for every other training example, recording how each of them would like to change the weights and biases. Then you average together all those desired changes.\nEach training example has its own desire for how the weights and biases should\nbe adjusted, and with what relative strengths. By averaging together the\ndesires of all training examples, we get the final result for how a given\nweight or bias should be changed in a single gradient descent step.\nThe collection of these averaged nudges to each weight and bias is, loosely speaking, the negative gradient of the cost function! Or at least something proportional to it.\nThe result of all this backpropagation is that we've found (something\nproportional to) the negative gradient!\nI say \"loosely speaking\" only because I have yet to get quantitatively precise about these nudges. But if you understood each change I referenced above, why some are proportionally bigger than others, and how they all need to be added together, then you understand the mechanics for what backpropagation is actually doing.\nStochastic Gradient Descent\nIn practice, it takes computers an extremely long time to add up the influences of every single training example for every single gradient descent step. Instead, there's a clever trick for speeding up the process in a way that involves more total gradient descent steps but much less time for each one.\nRandomly shuffle your training data and divide it into a bunch of mini-batches, having, say, 100 training examples each.\nThen you compute a gradient descent step according to each minibatch rather than the entire set of training examples. It won't give you the\nactual\ngradient of the cost function, which depends on all the training data, so it's not the most efficient step downhill. But each mini-batch gives a pretty good approximation, and if there are 100 minibatches, each step takes 1/100th of the total time. And after 100 steps, each piece of training data will have had its chance to influence the final result.\nWith these mini-batches, which only\napproximate\nthe gradient, the process of gradient descent looks more like a drunk man stumbling aimlessly down a hill but taking quick steps rather than a carefully calculating man who takes slow, deliberate steps downhill.\nUsing mini-batches means our steps downhill aren't quite as accurate, but\nthey're much faster.\nThis is referred to as\nStochastic gradient descent\n.\nConclusion\nWith that, every line of code that would go into implementing backpropagation corresponds to something you have now seen, at least in informal terms. But sometimes, knowing what the math does is only half the battle, and just representing the damn thing is where it gets all muddled and confusing.\nYou have now seen the intuition behind all the code (like you might find in\nNielsen's book\n) that goes into\nbuilding a simple neural network.\nSo for those of you who want to go deeper, the\nnext lesson\ngoes through the same ideas presented here, but in terms of the underlying calculus, which should hopefully make it more familiar as you see the topic in other resources.\nPrevious Lesson\nAnalyzing our neural network\nNext Lesson\nBackpropagation calculus\nThanks\nSpecial thanks to those below for supporting this lesson.\nRandall Hunt\nBurt Humburg\nCrypticSwarm\nJuan Benet\nDavid Kedmey\nMichael Hardwicke\nNathan Weeks\nMarcus Schiebold\nAli Yahya\nWilliam\nMayank M. Mehrotra\nLukas Biewald\nSamantha D. Suplee\nYana Chernobilsky\nKaustuv DeBiswas\nKathryn Schmiedicke\nYu Jun\nDave Nicponski\nDamion Kistler\nMarkus Persson\nYoni Nazarathy\nEd Kellett\nJoseph John Cox\nLuc Ritchie\n1stViewMaths\nJacob Magnuson\nMark Govea\nDagan Harrington\nClark Gaebel\nEric Chow\nMathias Jansson\nRobert Teed\nPedro Perez Sanchez\nDavid Clark\nMichael Gardner\nHarsev Singh\nMads Elvheim\nErik Sundell\nXueqi Li\nDr. David G. Stork\nTianyu Ge\nTed Suzman\nLinh Tran\nAndrew Busey\nJohn Haley\nAnkalagon\nEric Lavault\nBoris Veselinovich\nJulian Pulgarin\nJeff Linse\nCooper Jones\nRyan Dahl\nJason Hise\nMeshal Alshammari\nBernd Sing\nMustafa Mahdi\nMathew Bramson\nJerry Ling\nVecht\nShimin Kuang\nRish Kundalia\nAchille Brighton\nRipta Pasay\nPsylence\nSoufiane KHIAT\ndim85\nChris\nAlan Stein\nJasim Schluter\nMorten Skaaning\nGokcen Eraslan\nRichard Barthel\nEurghSireAwe\nRyan Cumings\nAlex Samarin\nYixiu Zhao\nJames Park\nJohn C. Vesey\nSuraj Pratap\nSergii Iastremskyi\nTomohiro Furusawa\nSean Bibby\nPatrickJMT\nKenneth Larsen\nSteve Cohen\nGuy rosen\nAnkit Agarwal\nJames Golab\nChad Hurst\nValentin Mayer-Eichberger\nsidwill\nDevin Scott\nHadrien Pierre\nDmitry Chepuryshkin\nKevin Norris\nJake Vartuli - Schonberg\nManuel Garcia\nFlorian Ragwitz\nNikolay Dubina\nMikko\nAlvin Khaled\nBrooks Ryba\nMyles Buckley\nSven Ostertag\nMarcelo Gómez\nMohannad Elhamod\nChris Willis\nJim Lauridson\nJim Mussared\nGabriel Cunha\nLoro Lukic\nLee Burnette\nAlexander Juda\nAndy Petsch\nOtavio Good\nV\nAndrew Mcnab\nMatt Parlmer\nDan Davison\naidan boneham\nHenry Reich\nPaul Constantine\nBen Granger\nShow More",
  "metadata": {
    "title": "What is backpropagation really doing? | 3Blue1Brown",
    "description": "An overview of backpropagation, the algorithm behind how neural networks learn.",
    "keywords": null,
    "author": null,
    "og:type": "website",
    "og:url": "https://www.3blue1brown.com/lessons/backpropagation/",
    "og:title": "What is backpropagation really doing? | 3Blue1Brown",
    "og:description": "An overview of backpropagation, the algorithm behind how neural networks learn.",
    "og:image": "https://www.3blue1brown.com/share.jpg",
    "twitter:card": "summary_large_image",
    "twitter:image": "https://www.3blue1brown.com/share.jpg"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [],
  "images": [
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/neural-network.jpg",
      "bytes": 539769,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/000.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/neural-network.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/gradient-descent.jpg",
      "bytes": 295723,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/001.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/gradient-descent.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/cost-calculation.jpg",
      "bytes": 208853,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/002.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/cost-calculation.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/relative-weight-importance.jpg",
      "bytes": 352415,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/003.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/relative-weight-importance.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/notation.jpg",
      "bytes": 103466,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/004.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/notation.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/cost-of-one-example.jpg",
      "bytes": 518691,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/005.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/cost-of-one-example.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/output-trash.jpg",
      "bytes": 578650,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/006.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/output-trash.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/classify-as-2.jpg",
      "bytes": 570558,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/007.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/classify-as-2.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/focus-on-2-neuron.jpg",
      "bytes": 99387,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/008.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/focus-on-2-neuron.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/output-neuron-equation.jpg",
      "bytes": 26997,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/010.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/output-neuron-equation.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/weights-proportional-to-activations.jpg",
      "bytes": 156651,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/011.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/weights-proportional-to-activations.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/hebbian-theory.jpg",
      "bytes": 167494,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/012.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/hebbian-theory.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/activations-proportional-to-weights.jpg",
      "bytes": 145425,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/013.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/activations-proportional-to-weights.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/no-direct-influence.jpg",
      "bytes": 115564,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/014.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/no-direct-influence.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/other-output-desires.jpg",
      "bytes": 606872,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/015.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/other-output-desires.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/propagate-backwards.jpg",
      "bytes": 287301,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/016.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/propagate-backwards.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/desires-of-2.jpg",
      "bytes": 67214,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/017.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/desires-of-2.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/average-over-all.jpg",
      "bytes": 280730,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/018.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/average-over-all.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/proportional-to-gradient.jpg",
      "bytes": 43352,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/019.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/proportional-to-gradient.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/mini-batches.jpg",
      "bytes": 343596,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/020.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/mini-batches.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/stochastic-comparison.jpg",
      "bytes": 501831,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/021.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/stochastic-comparison.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/code.jpg",
      "bytes": 470302,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/022.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/code.jpg",
      "alt": "Image",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/neural-network-analysis/thumbnail.jpg",
      "bytes": 371298,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/023.jpg",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/neural-network-analysis/thumbnail.jpg",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://img.youtube.com/vi/tIeHLnjs5U8/maxresdefault.jpg",
      "bytes": 74741,
      "reused": true,
      "local_path": "attachments/57a52b5580f8/images/024.jpg",
      "src": "https://img.youtube.com/vi/tIeHLnjs5U8/maxresdefault.jpg",
      "alt": "",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [
    {
      "url": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/nudge-weights.mp4",
      "src": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/nudge-weights.mp4",
      "status": "ok",
      "kind": "direct_video",
      "bytes": 1262261,
      "reused": false,
      "content_type": "video/mp4",
      "valid": true,
      "height": 1080,
      "width": 1920,
      "duration": "19.335983",
      "local_path": "attachments/57a52b5580f8/videos/repair-61cd60e611f12eed5118.mp4"
    }
  ],
  "links": [
    {
      "href": "https://www.3blue1brown.com/?topic=neural-networks",
      "label": "Neural Networks",
      "type": "a"
    },
    {
      "href": "https://www.3blue1brown.com/lessons/backpropagation/",
      "label": "W h a t i s b a c k p r o p a g a t i o n r e a l l y d o i n g ?",
      "type": "a"
    },
    {
      "href": "https://www.3blue1brown.com/about",
      "label": "Grant Sanderson",
      "type": "a"
    },
    {
      "href": "https://www.joshuapullen.com/",
      "label": "Josh Pullen",
      "type": "a"
    },
    {
      "href": "https://github.com/3b1b/videos/blob/master/_2017/nn/part3.py",
      "label": "Source",
      "type": "a"
    },
    {
      "href": "https://storage.googleapis.com/3blue1brown-website-bucket/lessons/2017/backpropagation/nudge-weights.mp4",
      "label": "",
      "type": "source"
    },
    {
      "href": "http://neuralnetworksanddeeplearning.com/",
      "label": "Nielsen's book",
      "type": "a"
    },
    {
      "href": "https://www.3blue1brown.com/lessons/neural-network-analysis",
      "label": "Previous Lesson Analyzing our neural network",
      "type": "a"
    },
    {
      "href": "https://www.3blue1brown.com/lessons/backpropagation-calculus",
      "label": "Next Lesson Backpropagation calculus",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:53:12Z",
  "source_url": "https://www.3blue1brown.com/lessons/backpropagation",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 16448,
  "expected_body_images": 24,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/57a52b5580f8/pages/source.html",
  "local_html": "attachments/57a52b5580f8/pages/article.html",
  "body_base_path": "attachments/57a52b5580f8/pages/",
  "body_markdown_path": "attachments/57a52b5580f8/pages/article.md"
}