{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "zeromathai",
  "title_listed": "Generative Modeling: From Data Distributions to Deep Generative Models",
  "keywords": "",
  "domain": "文本处理",
  "content_type": "技术教程",
  "is_paid_flag": "否",
  "url": "https://dev.to/zeromathai/generative-modeling-from-data-distributions-to-deep-generative-models-5h6e",
  "publish_date": "2026-09-02",
  "corpus_stage": "",
  "notes": "",
  "id": "10079cdd2633",
  "collected_at": "2026-10-02T13:50:36",
  "title": "Generative Modeling: From Data Distributions to Deep Generative Models - DEV Community",
  "body_markdown": "If you approach generative models as \"\"networks that create images,\"\" the field quickly turns into a collection of disconnected architectures.\nA more useful developer mental model starts one level lower:\nWhat probability structure could have produced the data, and how can we represent, learn, and infer that structure without making the computation impossible?\nThat question connects autoregressive models, VAEs, flow-based models, GANs, and diffusion models. Their architectures look very different, but they all respond to the same underlying tension: high-dimensional data distributions are difficult to represent, learn, normalize, sample from, and reason about.\nGenerative modeling can therefore be organized around three interacting problems:\nRepresentation:\nHow do we represent a complex high-dimensional joint distribution?\nLearning:\nHow do we make the model distribution approach the data distribution?\nInference:\nGiven an observation, how do we reason backward about hidden variables or the process that generated it?\nOnce these three pieces are connected, the major families of deep generative models become much easier to understand.\nFrom prediction to distribution learning\nA discriminative model usually begins with a prediction problem. Given an input\nx\nx\nx\n, predict the most likely output\ny\ny\ny\n:\nf\n(\nx\n)\n=\narg\n⁡\nmax\n⁡\ny\np\n(\ny\n∣\nx\n)\nf(x)=\\underset{y}{\\arg\\max}\\;p(y\\mid x)\nf\n(\nx\n)\n=\ny\nar\ng\nmax\n​\np\n(\ny\n∣\nx\n)\nThe model focuses directly on the conditional relationship required for prediction.\nA generative model asks a broader question. Instead of learning only the path from\nx\nx\nx\nto\ny\ny\ny\n, it models the probability structure from which the data arises.\nFor class-conditional modeling, for example, we can model\np\n(\nx\n∣\ny\n)\np(x\\mid y)\np\n(\nx\n∣\ny\n)\ntogether with the prior\np\n(\ny\n)\np(y)\np\n(\ny\n)\nand recover the posterior using Bayes' rule:\np\n(\ny\n∣\nx\n)\n=\np\n(\nx\n∣\ny\n)\np\n(\ny\n)\np\n(\nx\n)\np(y\\mid x)=\\frac{p(x\\mid y)p(y)}{p(x)}\np\n(\ny\n∣\nx\n)\n=\np\n(\nx\n)\np\n(\nx\n∣\ny\n)\np\n(\ny\n)\n​\nIn unsupervised generative modeling, the target becomes the data distribution itself. We assume the training samples come from some unknown distribution:\nx\n1\n,\nx\n2\n,\n…\n,\nx\nN\n∼\ni\n.\ni\n.\nd\n.\np\nd\na\nt\na\n(\nx\n)\n{x_1,x_2,\\ldots,x_N}\\overset{\\mathrm{i.i.d.}}{\\sim}p_{\\mathrm{data}}(x)\nx\n1\n​\n,\nx\n2\n​\n,\n…\n,\nx\nN\n​\n∼\ni.i.d.\np\ndata\n​\n(\nx\n)\nThe model then constructs a parameterized distribution intended to approximate it.\nThis perspective connects tasks that can otherwise seem separate:\nx\nt\nr\na\ni\nn\n∼\np\nd\na\nt\na\n(\nx\n)\n,\nx\nn\ne\nw\n∼\np\nm\no\nd\ne\nl\n(\nx\n)\nx_{\\mathrm{train}}\\sim p_{\\mathrm{data}}(x),\\qquad x_{\\mathrm{new}}\\sim p_{\\mathrm{model}}(x)\nx\ntrain\n​\n∼\np\ndata\n​\n(\nx\n)\n,\nx\nnew\n​\n∼\np\nmodel\n​\n(\nx\n)\nDensity estimation\nasks how probable an observation is under the model.\nGeneration\ndraws new samples from the learned model distribution.\nUnsupervised representation learning\ncan capture latent structure shared by the data while learning that distribution.\nAll three begin with the same underlying goal: learning the probability structure of the data.\nWhy high-dimensional data makes this hard\nReal data usually lives in a high-dimensional space. An image, for example, is described by many variables, while valid observations occupy only a limited and complicated region among all possible combinations.\nSo the first problem is not simply \"\"use a neural network.\"\" It is:\nHow do we represent the joint distribution of many random variables compactly enough to compute with, while keeping enough flexibility to describe the data?\nThis connects naturally to inverse problems.\nA forward problem moves from a cause\nx\nx\nx\nto an observation\ny\ny\ny\n. An inverse problem starts from an observed\ny\ny\ny\nand asks which possible\nx\nx\nx\ncould have produced it. Conditional generation extends the same idea by generating possible\nx\nx\nx\nvalues consistent with a given condition.\nForward:\ncause x  ──────────>  observation y\n\nInverse:\npossible cause x  <──────────  observation y\n\nConditional generation:\ncondition y  ──────────>  possible samples x\nEnter fullscreen mode\nExit fullscreen mode\nRecovering a high-resolution image from a low-resolution one, estimating color from grayscale data, reconstructing missing regions, or recovering a CT slice from a sparse-view sinogram all share this structure.\nThe difficulty is that the inverse may not be unique. A single observation can be consistent with multiple possible causes. Inverse problems are therefore not simply about running a function backward; they require reasoning over possible causes that are compatible with the observation.\nLatent variables turn inversion into posterior inference\nSuppose a model contains an observed variable\nx\nx\nx\nand a hidden variable\nz\nz\nz\n.\nThe generative direction models the relationship between\nz\nz\nz\nand\nx\nx\nx\n. Once\nx\nx\nx\nhas been observed, the reverse question is which values of\nz\nz\nz\ncould have produced it.\nThat is posterior inference:\np\n(\nz\n∣\nx\n)\n=\np\n(\nz\n,\nx\n)\np\n(\nx\n)\np(z\\mid x)=\\frac{p(z,x)}{p(x)}\np\n(\nz\n∣\nx\n)\n=\np\n(\nx\n)\np\n(\nz\n,\nx\n)\n​\nPosterior inference can require both computing the posterior distribution and calculating expectations under it. The E-step of the EM algorithm is a direct example:\nQ\n(\nθ\n,\nθ\no\nl\nd\n)\n=\n∑\nz\np\n(\nz\n∣\nx\n;\nθ\no\nl\nd\n)\nlog\n⁡\np\n(\nx\n,\nz\n;\nθ\n)\nQ(\\theta,\\theta^{\\mathrm{old}})=\\sum_z p(z\\mid x;\\theta^{\\mathrm{old}})\\log p(x,z;\\theta)\nQ\n(\nθ\n,\nθ\nold\n)\n=\nz\n∑\n​\np\n(\nz\n∣\nx\n;\nθ\nold\n)\nlo\ng\np\n(\nx\n,\nz\n;\nθ\n)\nHere the posterior over the unobserved\nz\nz\nz\nis used to compute the expected complete-data log-likelihood.\nAs the latent space grows and interactions among hidden variables become more complicated, direct posterior computation can become intractable. Increasing model expressivity therefore leads naturally to another question: how can the required inference remain computationally feasible?\nmore expressive representation\n        ↓\nmore complicated latent structure\n        ↓\nharder posterior inference\n        ↓\nneed for approximate inference\nEnter fullscreen mode\nExit fullscreen mode\nWhen the posterior is intractable\nTwo major approaches are MCMC and Variational Inference. Both approximate a posterior that is difficult to compute directly, but the approximation arises in different ways.\nMCMC: approximate with samples\nMCMC constructs an ergodic Markov chain whose stationary distribution is the target posterior. Samples generated by running the chain are then used to approximate the posterior and the expectations we need.\ntarget posterior\n      ↓\nconstruct Markov chain\n      ↓\nrun the chain\n      ↓\ncollect samples\n      ↓\napproximate posterior expectations\nEnter fullscreen mode\nExit fullscreen mode\nThe practical approximation comes from finite computation. In real problems, only a limited amount of time is available for generating samples, and exploring the relevant probability regions can be expensive in high-dimensional or complex models.\nMCMC therefore has a\nfinite-time sampling approximation\nin practice.\nVariational Inference: approximate with optimization\nVariational Inference makes a different tradeoff. Instead of sampling directly from the posterior, it defines a tractable family of distributions\nQ\n\\mathcal{Q}\nQ\nand searches within that family for a distribution close to the true posterior:\nq\n∗\n(\nz\n)\n=\narg\n⁡\nmin\n⁡\nq\n(\nz\n)\n∈\nQ\nD\nK\nL\n!\n[\nq\n(\nz\n)\n∥\np\n(\nz\n∣\nx\n)\n]\nq^*(z)=\\underset{q(z)\\in\\mathcal{Q}}{\\arg\\min}\\;D_{\\mathrm{KL}}!\\left[q(z)\\parallel p(z\\mid x)\\right]\nq\n∗\n(\nz\n)\n=\nq\n(\nz\n)\n∈\nQ\nar\ng\nmin\n​\nD\nKL\n​\n!\n[\nq\n(\nz\n)\n∥\np\n(\nz\n∣\nx\n)\n]\nThis turns posterior inference into an optimization problem.\nThe tractability comes from restricting the search space. If the true posterior cannot be represented by the chosen variational family, more optimization time alone cannot eliminate the mismatch.\nThe contrast is useful:\nMCMC approximation source:\nfinite-time sampling\n\nVariational Inference approximation source:\nrestricted distribution family\nEnter fullscreen mode\nExit fullscreen mode\nThis distinction becomes concrete in a VAE. Rather than computing a complicated latent posterior directly, the model uses a variational distribution, with the Encoder acting as a Recognition Network that constructs the approximation. The Decoder generates observations from the latent variable.\nAn abstract inference problem has now become part of a trainable model architecture.\nThe real bottleneck: flexibility versus tractability\nRepresentation and computation collide when we try to model realistic high-dimensional distributions.\nA simple probability model can be easy to normalize and evaluate but may lack enough flexibility to describe complex data. A deep neural network can represent much richer functions, but its output is not automatically a valid probability density.\nA probability density must be nonnegative and integrate to one. One way to construct such a density is:\np\nθ\n(\nx\n)\n=\ne\nf\nθ\n(\nx\n)\nZ\nθ\np_\\theta(x)=\\frac{e^{f_\\theta(x)}}{Z_\\theta}\np\nθ\n​\n(\nx\n)\n=\nZ\nθ\n​\ne\nf\nθ\n​\n(\nx\n)\n​\nwhere\nZ\nθ\n=\n∫\ne\nf\nθ\n(\nx\n)\nd\nx\nZ_\\theta=\\int e^{f_\\theta(x)}\\,dx\nZ\nθ\n​\n=\n∫\ne\nf\nθ\n​\n(\nx\n)\nd\nx\nExponentiation gives a positive quantity, while the normalizing constant\nZ\nθ\nZ_\\theta\nZ\nθ\n​\nensures that the density integrates to one.\nFor a complex neural function over a high-dimensional space, however, computing that integral can itself become intractable.\nsimple probability model\n    → tractable\n    → limited flexibility\n\ndeep neural representation\n    → flexible\n    → normalization or inference may become intractable\nEnter fullscreen mode\nExit fullscreen mode\nThis is the\nTractability-Flexibility Tradeoff\n.\nIt provides a useful way to compare deep generative models. Rather than asking only which network architecture a model uses, ask which difficult probability computation its structure makes manageable.\nLearning a model distribution\nIn likelihood-based generative modeling, learning can be viewed as reducing the difference between the data distribution and the model distribution:\nD\nK\nL\n!\n[\np\nd\na\nt\na\n(\nx\n)\n∥\np\nm\no\nd\ne\nl\n(\nx\n;\nθ\n)\n]\nE\nx\n∼\np\nd\na\nt\na\n!\n[\nlog\n⁡\np\nd\na\nt\na\n(\nx\n)\np\nm\no\nd\ne\nl\n(\nx\n;\nθ\n)\n]\nD_{\\mathrm{KL}}!\\left[p_{\\mathrm{data}}(x)\\parallel p_{\\mathrm{model}}(x;\\theta)\\right]\n\n\n\\mathbb{E}{x\\sim p{\\mathrm{data}}}\n!\\left[\n\\log\\frac{p_{\\mathrm{data}}(x)}{p_{\\mathrm{model}}(x;\\theta)}\n\\right]\nD\nKL\n​\n!\n[\np\ndata\n​\n(\nx\n)\n∥\np\nmodel\n​\n(\nx\n;\nθ\n)\n]\nE\nx\n∼\np\ndata\n!\n[\nlo\ng\np\nmodel\n​\n(\nx\n;\nθ\n)\np\ndata\n​\n(\nx\n)\n​\n]\nExpanding this expression separates a term that depends only on the data distribution from a term containing the model log probability. The data-only term is independent of\nθ\n\\theta\nθ\n, so it does not change as the model parameters are optimized.\nThe learning objective therefore connects to increasing the model's log probability on observed data. With a finite training set, this gives the progression:\nminimize KL divergence\n        ↓\nminimize cross-entropy\n        ↓\nminimize negative log-likelihood\nEnter fullscreen mode\nExit fullscreen mode\nThe challenge is to make\np\nm\no\nd\ne\nl\n(\nx\n;\nθ\n)\np_{\\mathrm{model}}(x;\\theta)\np\nmodel\n​\n(\nx\n;\nθ\n)\nexpressive enough for high-dimensional data while keeping the required probability computations feasible.\nThis is where the major generative model families diverge.\nAutoregressive models: factorize the joint distribution\nAn autoregressive model handles a high-dimensional joint distribution by decomposing it into sequential conditional distributions:\np\n(\nx\n)\n=\n∏\ni\n=\n1\nn\np\n(\nx\ni\n∣\nx\n1\n,\n…\n,\nx\ni\n−\n1\n)\np(x)=\\prod_{i=1}^{n}p(x_i\\mid x_1,\\ldots,x_{i-1})\np\n(\nx\n)\n=\ni\n=\n1\n∏\nn\n​\np\n(\nx\ni\n​\n∣\nx\n1\n​\n,\n…\n,\nx\ni\n−\n1\n​\n)\nInstead of directly modeling one complicated joint distribution, the model works with a product of conditional probabilities.\nThe key structural idea is\nfactorization\n. The model represents the high-dimensional joint distribution through a sequence of conditional distributions that can be modeled in a computationally manageable form.\nVAE: latent variables meet approximate inference\nA latent-variable model can express the observed distribution as:\np\n(\nx\n)\n=\n∫\np\n(\nz\n)\np\n(\nx\n∣\nz\n)\nd\nz\np(x)=\\int p(z)p(x\\mid z)\\,dz\np\n(\nx\n)\n=\n∫\np\n(\nz\n)\np\n(\nx\n∣\nz\n)\nd\nz\nThis provides a latent space for representing hidden structure, but it also introduces the posterior problem\np\n(\nz\n∣\nx\n)\np(z\\mid x)\np\n(\nz\n∣\nx\n)\n.\nA VAE connects the pieces this way:\nobserved x\n   ↓\nEncoder / Recognition Network\n   ↓\nvariational approximation to posterior over z\n   ↓\nlatent z\n   ↓\nDecoder / Generative Network\n   ↓\ngenerated or reconstructed x\nEnter fullscreen mode\nExit fullscreen mode\nTraining connects this architecture to Variational Inference through maximizing the ELBO:\nlatent-variable representation\n        ↓\nintractable posterior\n        ↓\nvariational approximation\n        ↓\nEncoder\n        ↓\nELBO-based learning\nEnter fullscreen mode\nExit fullscreen mode\nThis is why a VAE is more than an Encoder followed by a Decoder. Its structure turns posterior intractability and variational approximation into a trainable generative model.\nFlow-based models: use invertibility to preserve tractability\nFlow-based models start from a simple distribution and apply a sequence of invertible transformations to reach a more complex target distribution.\nInvertibility is the critical structural constraint. Because the transformations can be reversed, probability density can be tracked through them, allowing the model to train with NLL.\narchitectural restriction\n        ↓\ninvertible transformation\n        ↓\ndensity remains computable\n        ↓\nlikelihood-based training becomes possible\nEnter fullscreen mode\nExit fullscreen mode\nThe constraint is part of the solution to the tractability problem: it introduces a structural restriction while keeping density evaluation possible.\nGAN: learn the generation process instead of explicit density\nGANs make a different choice. Instead of directly computing an explicit density function or normalizing constant, they learn the generation process itself.\nThe Generator tries to produce samples resembling real data, while the Discriminator tries to distinguish generated samples from real ones. The two networks train with opposing objectives in a minimax problem.\nlatent input\n    ↓\nGenerator\n    ↓\ngenerated sample ──┐\n                   ├──> Discriminator\nreal sample ───────┘\nEnter fullscreen mode\nExit fullscreen mode\nGANs use this adversarial minimax process to construct an\nimplicit generative model\nrather than directly evaluating an explicit model density.\nDiffusion: connect noise and data through many steps\nDiffusion models take another route. Rather than directly handling the transformation between a simple distribution and a complex data distribution in one step, they connect the two through a sequence of noise levels.\nThe forward process gradually adds Gaussian noise to real data:\nx\n0\n∼\nq\n(\nx\n)\n,\nx\nT\n→\nN\n(\n0\n,\nI\n)\nas\nT\n→\n∞\nx_0\\sim q(x),\\qquad x_T\\rightarrow\\mathcal{N}(0,I)\\quad\\text{as}\\quad T\\rightarrow\\infty\nx\n0\n​\n∼\nq\n(\nx\n)\n,\nx\nT\n​\n→\nN\n(\n0\n,\nI\n)\nas\nT\n→\n∞\nAs the process continues, the original data structure gradually disappears and approaches a simple isotropic Gaussian distribution.\nGeneration runs in the opposite direction:\ndata\n  ↓\nadd noise\n  ↓\nadd more noise\n  ↓\n...\n  ↓\nGaussian-like noise\n\ngeneration:\n\nGaussian noise\n  ↓\nlearned reverse step\n  ↓\nlearned reverse step\n  ↓\n...\n  ↓\ndata-like sample\nEnter fullscreen mode\nExit fullscreen mode\nInstead of using one direct transformation, diffusion models learn a reverse process that progressively reconstructs data structure from noise.\nThe score view of diffusion\nScore-based generative models can describe this process using the score function:\ns\n(\nx\n)\n=\n∇\nx\nlog\n⁡\np\n(\nx\n)\ns(x)=\\nabla_x\\log p(x)\ns\n(\nx\n)\n=\n∇\nx\n​\nlo\ng\np\n(\nx\n)\nThe score indicates the direction in which the log probability increases.\nTwo representative approaches are SMLD and DDPM.\nSMLD\n, or Score Matching with Langevin Dynamics, estimates the score at multiple noise scales and uses Langevin Dynamics to sample while the noise scale decreases.\nDDPM\n, or Denoising Diffusion Probabilistic Model, learns a probabilistic reverse model for the steps of the forward noise-corruption process.\nTheir emphasis can be summarized as:\nSMLD:\nscore estimation\n      +\nLangevin Dynamics\n\nDDPM:\nforward corruption steps\n      +\nlearned reverse probability model\nEnter fullscreen mode\nExit fullscreen mode\nThe details differ, but both approaches connect a simple noise distribution to a complex data distribution through multiple noise levels or steps.\nThat iterative structure also creates a practical tradeoff. Because generation requires multiple diffusion steps, sampling speed can become an important limitation.\nOne probability problem, different structural answers\nThe major generative model families are easier to compare when viewed as different computational responses to the same high-dimensional distribution problem:\nAutoregressive models\nfactorize a joint distribution into sequential conditional distributions.\nVAEs\nintroduce latent variables and use Variational Inference to approximate a difficult posterior while training through the ELBO.\nFlow-based models\nimpose invertibility so density evaluation and NLL-based learning remain possible.\nGANs\navoid direct explicit-density evaluation and learn the generation process through adversarial minimax training.\nDiffusion models\ntransform generation into a sequence of noise-corruption and reverse-process steps.\nThe normalizing constant fits into the same picture. Energy-Based Models work with energy-based probability distributions in which the normalizing constant must be handled or approximated. Autoregressive models, flow-based models, and VAEs use computationally manageable structural constraints or model constructions. GANs avoid direct computation of explicit density and its normalizing constant by learning the generation process, while score-based diffusion uses the score rather than directly computing the normalizing constant.\nDifferent architectures make different choices, but the underlying problem is the same: preserve enough flexibility to represent complex data while keeping generative modeling computationally feasible.\nA developer mental model for generative architectures\nWhen you encounter a generative architecture, start with three questions rather than its layer diagram.\nRepresentation:\nWhat distribution or latent structure is the model trying to represent?\nLearning:\nWhat objective reduces the difference between the model and the observed data distribution?\nInference:\nWhat hidden variables or generating processes must be inferred from observations, and can those quantities be computed directly?\nThen look at the structural choice the model uses to keep the relevant computations manageable:\nhigh-dimensional data distribution\n          ↓\nrepresentation must be expressive\n          ↓\nprobability or posterior computation becomes difficult\n          ↓\nchoose a computational strategy\n          ↓\nfactorize\napproximate\nrestrict\navoid explicit density\nor learn a multi-step reverse process\nEnter fullscreen mode\nExit fullscreen mode\nNo single family removes every tradeoff. In the comparison considered here, VAEs and flow-based models can show weaknesses in generation quality, GANs can face difficulties with generation diversity, and diffusion models can pay for their iterative generation process with slower sampling.\nSo the useful comparison is not simply \"\"Which model is better?\"\"\nIt is:\nWhich computational problem does the model solve through its structural choice, and what does that choice cost in quality, diversity, or speed?\nTakeaway\nGenerative modeling is not fundamentally about producing realistic-looking samples. It is about learning an unknown high-dimensional data distribution while keeping\nRepresentation, Learning, and Inference\ncomputationally manageable.\nAutoregressive models, VAEs, flow-based models, GANs, and diffusion models look different because they make different structural choices around the same underlying problem. Once you identify whether an architecture factorizes a distribution, approximates an intractable quantity, imposes a structural constraint, avoids explicit density evaluation, or learns a multi-step reverse process, the landscape of deep generative models becomes much easier to reason about.\nOriginally published at zeromathai.com.\nOriginal article:\nhttps://zeromathai.com/en/generative-model-overview-course-en/",
  "metadata": {
    "title": "Generative Modeling: From Data Distributions to Deep Generative Models - DEV Community",
    "description": "If you approach generative models as \"\"networks that create images,\"\" the field quickly turns into a... Tagged with generativemodeling, deeplearning, probabilisticmodels, diffusion.",
    "keywords": "generativemodeling, deeplearning, probabilisticmodels, diffusion, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/zeromathai/generative-modeling-from-data-distributions-to-deep-generative-models-5h6e",
    "og:title": "Generative Modeling: From Data Distributions to Deep Generative Models",
    "og:description": "If you approach generative models as \"\"networks that create images,\"\" the field quickly turns into a...",
    "og:site_name": "DEV Community",
    "og:image": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faksydjkzo5tceiobhy2t.png",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "Generative Modeling: From Data Distributions to Deep Generative Models",
    "twitter:description": "If you approach generative models as \"\"networks that create images,\"\" the field quickly turns into a...",
    "twitter:card": "summary_large_image",
    "twitter:widgets:new-embed-design": "on",
    "twitter:image:src": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faksydjkzo5tceiobhy2t.png"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/10079cdd2633/code/body-000.txt",
      "chars": 170,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-001.txt",
      "chars": 153,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-002.txt",
      "chars": 137,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-003.txt",
      "chars": 124,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-004.txt",
      "chars": 166,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-005.txt",
      "chars": 99,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-006.txt",
      "chars": 179,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-007.txt",
      "chars": 147,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-008.txt",
      "chars": 152,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-009.txt",
      "chars": 115,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-010.txt",
      "chars": 178,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-011.txt",
      "chars": 123,
      "language": "text"
    },
    {
      "file": "attachments/10079cdd2633/code/body-012.txt",
      "chars": 296,
      "language": "text"
    }
  ],
  "images": [],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://zeromathai.com/en/generative-model-overview-course-en/",
      "label": "https://zeromathai.com/en/generative-model-overview-course-en/",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:48:16Z",
  "source_url": "https://dev.to/zeromathai/generative-modeling-from-data-distributions-to-deep-generative-models-5h6e",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 20276,
  "expected_body_images": 0,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/10079cdd2633/pages/source.html",
  "local_html": "attachments/10079cdd2633/pages/article.html",
  "body_base_path": "attachments/10079cdd2633/pages/",
  "body_markdown_path": "attachments/10079cdd2633/pages/article.md"
}