Variational Autoencoders 3: Training, Inference and comparison with other models

Variational Autoencoders 1: Overview
Variational Autoencoders 2: Maths
Variational Autoencoders 3: Training, Inference and comparison with other models

Recalling that the backbone of VAEs is the following equation:

\log P\left(X\right) - \mathcal{D}\left[Q\left(z\vert X\right)\vert\vert P\left(z\vert X\right)\right] = E_{z\sim Q}\left[\log P\left(X\vert z\right)\right] - \mathcal{D}\left[Q\left(z\vert X\right) \vert\vert P\left(z\right)\right]

In order to use gradient descent for the right hand side, we need a tractable way to compute it:

  • The first part E_{z\sim Q}\left[\log P\left(X\vert z\right)\right] is tricky, because that requires passing multiple samples of z through f in order to have a good approximation for the expectation (and this is expensive). However, we can just take one sample of z, then pass it through f and use it as an estimation for E_{z\sim Q}\left[\log P\left(X\vert z\right)\right] . Eventually we are doing stochastic gradient descent over different sample X in the training set anyway.
  • The second part \mathcal{D}\left[Q\left(z\vert X\right) \vert\vert P\left(z\right)\right] is even more tricky. By design, we fix P\left(z\right) to be the standard normal distribution \mathcal{N}\left(0,I\right) (read part 1 to know why). Therefore, we need a way to parameterize Q\left(z\vert X\right) so that the KL divergence is tractable.

Here comes perhaps the most important approximation of VAEs. Since P\left(z\right) is standard Gaussian, it is convenient to have Q\left(z\vert X\right) also Gaussian. One popular way to parameterize Q is to make it also Gaussian with mean \mu\left(X\right) and diagonal covariance \sigma\left(X\right)I, i.e. Q\left(z\vert X\right) = \mathcal{N}\left(z;\mu\left(X\right), \sigma\left(X\right)I\right), where \mu\left(X\right) and \sigma\left(X\right) are two vectors computed by a neural network. This is the original formulation of VAEs in section 3 of this paper.

This parameterization is preferred because the KL divergence now becomes closed-form:

\displaystyle \mathcal{D}\left[\mathcal{N}\left(\mu\left(X\right), \sigma\left(X\right)I\right)\vert\vert P\left(z\right)\right] = \frac{1}{2}\left[\left(\sigma\left(X\right)\right)^T\left(\sigma\left(X\right)\right) +\left(\mu\left(X\right)\right)^T\left(\mu\left(X\right)\right) - k - \log \det \left(\sigma\left(X\right)I\right) \right]

Although this looks like magic, but it is quite natural if you apply the definition of KL divergence on two normal distributions. Doing so will teach you a bit of calculus.

So we have all the ingredients. We use a feedforward net to predict \mu\left(X\right) and \sigma\left(X\right) given an input sample X draw from the training set. With those vectors, we can compute the KL divergence and \log P\left(X\vert z\right), which, in term of optimization, will translate into something similar to \Vert X - f\left(z\right)\Vert^2.

It is worth to pause here for a moment and see what we just did. Basically we used a constrained Gaussian (with diagonal covariance matrix) to parameterize Q. Moreover, by using \Vert X - f\left(z\right)\Vert^2 for one of the training criteria, we implicitly assume P\left(X\vert z\right) to be also Gaussian. So although the maths that lead to VAEs are generic and beautiful, at the end of the day, to make things tractable, we ended up using those severe approximations. Whether those approximations are good enough totally depend on practical applications.

There is an important detail though. Once we have \mu\left(X\right) and \sigma\left(X\right) from the encoder, we will need to sample z from a Gaussian distribution parameterized by those vectors. z is needed for the decoder to reconstruct \hat{X}, which will then be optimized to be as close to X as possible via gradient descent. Unfortunately, the “sample” step is not differentiable, therefore we will need a trick call reparameterization, where we don’t sample z directly from \mathcal{N}\left(\mu\left(X\right), \sigma\left(X\right)\right), but first sample z' from \mathcal{N}\left(0, I\right), and then compute z = \mu\left(X\right) + \mu\left(X\right)Iz'. This will make the whole computation differentiable and we can apply gradient descent as usual.

The cool thing is during inference, you won’t need the encoder to compute \mu\left(X\right) and \sigma\left(X\right) at all! Remember that during training, we try to pull Q to be close to P\left(z\right) (which is standard normal), so during inference, we can just inject \epsilon \sim \mathcal{N}\left(0, I\right) directly into the decoder and get a sample of X. This is how we can leverage the power of “generation” from VAEs.

There are various extensions to VAEs like Conditional VAEs and so on, but once you understand the basic, everything else is just nuts and bolts.

To sum up the series, this is the conceptual graph of VAEs during training, compared to some other models. Of course there are many details in those graphs that are left out, but you should get a rough idea about how they work.


In the case of VAEs, I added the additional cost term in blue to highlight it. The cost term for other models, except GANs, are the usual L2 norm \Vert X - \hat{X}\Vert^2.

GSN is an extension to Denoising Autoencoder with explicit hidden variables, however that requires to form a fairly complicated Markov Chain. We may have another post  for it.

With this diagram, hopefully you will see how lame GAN is. It is even simpler than the humble RBM. However, the simplicity of GANs makes it so powerful, while the complexity of VAE makes it quite an effort just to understand. Moreover, VAEs make quite a few severe approximation, which might explain why samples generated from VAEs are far less realistic than those from GANs.

That’s quite enough for now. Next time we will switch to another topic I’ve been looking into recently.

Variational Autoencoders 2: Maths

Variational Autoencoders 1: Overview
Variational Autoencoders 2: Maths
Variational Autoencoders 3: Training, Inference and comparison with other models

Last time we saw the probability distribution of X with a latent variable z as follows:

\displaystyle P(X) = \int P\left(X\vert z; \theta\right)P(z)dz  (1)

and we said the key idea behind VAEs is to not sample z from the whole distribution P\left(z\right), but actually from a simpler distribution Q\left(z\vert X\right). The reason is because most of z will likely to give P\left(X\vert z\right) close to zero, and therefore making little contribution to the estimation of P\left(X\right). Now if we sample z \sim Q\left(z\vert X\right), those values of z will more likely to generate X in the training set. Moreover, we hope that Q will has less modes than P\left(z\right), and therefore easier to sample from. The intuition of this is the locations of the modes of Q\left(z\vert X\right) depends on X, and this flexibility will compensate the limitation of the fact that Q\left(z\vert X\right) is simpler than P\left(z\right).

But how Q\left(z\vert X\right) can help with modelling P\left(X\right)? If z is sampled from Q, then using f we will get E_{z \sim Q}P\left(X\vert z\right). We will then need to show the relationship of this quantity with P\left(X\right), which is the actual quantity we want to estimate. The relationship between E_{z \sim Q}P\left(X\vert z\right) and P\left(X\right) is the backbone of VAEs.

We start with the KL divergence of Q\left(z\vert X\right) and P\left(z\vert X\right):

\mathcal{D}\left[Q\left(z\vert X\right) \vert\vert P\left(z\vert X\right)\right] = E_{z\sim Q}\left[\log Q\left(z\vert X\right) - log P\left(z\vert X\right)\right]

The unknown quantity in this equation is P\left(z\vert X\right), but at least we can use Bayes rule for it:

\mathcal{D}\left[Q\left(z\vert X\right) \vert\vert P\left(z\vert X\right)\right] = E_{z\sim Q}\left[\log Q\left(z\vert X\right) - log P\left(X\vert z\right) - \log P\left(z\right)\right] + \log P\left(X\right)

Rearrange things a bit, and apply the definition of KL divergence between Q\left(z\vert X\right) and P\left(z\right), we have:

\log P\left(X\right) - \mathcal{D}\left[Q\left(z\vert X\right)\vert\vert P\left(z\vert X\right)\right] = E_{z\sim Q}\left[\log P\left(X\vert z\right)\right] - \mathcal{D}\left[Q\left(z\vert X\right) \vert\vert P\left(z\right)\right]    (2)

If you forget everything, this formula is the thing you should remember. It is therefore important to understand what it means:

  • The left-hand-side is exactly what we want to optimize, plus an error term. The smaller this error term is, the better we are in mazimizing P\left(X\right). In other words, the left-hand-side is a lower-bound of what we want to optimize, hence the name variational (Bayesian).
  • If Q happens to be a differentiable function, the right-hand-side is something we can optimize with gradient descent (we will see how to do it later). Note that the right-hand-side happens to take the form of encoder and decoder, where Q encodes X into z, and then P decodes z to reconstruct X, hence the name “Autoencoder”. However, VAEs don’t really belong to the family of Denoising and Sparse Autoencoders, although there are indeed some connections.
  • Note that P\left(z\vert X\right) on the left hand side is something intractable. However, by maximizing the left hand side, we simultaneously minimize \mathcal{D}\left[Q\left(z\vert X\right)\vert\vert P\left(z\vert X\right)\right], and therefore pull Q\left(z\vert X\right) closer to P\left(z\vert X\right). If we use a flexible model for Q, then we can use Q as an approximation for P\left(z\vert X\right). This is a nice side effect of the whole framework.

Actually the above maths existed way before VAEs. However the trick was to use a feedforward network for Q, which gave rise to VAEs several years ago.

Next time, we will see how to do that, and hopefully conclude this series. Then we can move on with something more interesting.

[RL3b] Temporal Difference Learning – intuition

[RL1] Markov Decision process – Introduction
[RL2a] Markov Decision Process – Discounted Reward
[RL2b] Markov Decision Process – Bellman equation
[RL2c] Markov Decision Process – Solving Bellman equation
[RL2d] Bellman Equations revisited
[RL3a] Reinforcement Learning context
[RL3b] Temporal Difference Learning – intuition

Như đã nói trong bài trước, ta sẽ tập trung vào Model-free RL, trong đó ta muốn học trực tiếp giá trị của các trạng thái V(s) từ tập huấn luyện <s, a, r>^*.

Cụ thể, tập huấn luyện sẽ gồm nhiều episodes, mỗi episode là một chuỗi s_1 \overset{r_1}{\longrightarrow} s_2 \overset{r_2}{\longrightarrow} s_3 \longrightarrow ... \longrightarrow s_F mà agent thực hiện cho đến khi kết thúc cuộc đời của nó. Chẳng hạn nếu là chơi cờ thì tập huấn luyện sẽ gồm nhiều trận đấu, mỗi trận là một chuỗi các nước đi. Từ tập huấn luyện này, ta tìm cách ước lượng V(s).

Tại sao lại ước lượng V(s), khi trong bài trước ta nói rằng Model-free RL tìm cách ước lượng giá trị Q(s, a)? Nhắc lại rằng ta có thể tính Q(s, a) từ V(s), R(s, a)T(s, a, s'), như đã nói trong bài này, mà R(s, a)T(s, a, s') có thể ước lượng một cách đơn giản từ tập huấn luyện (chẳng hạn dùng maximum likelihood), nên một khi có V(s) ta hoàn toàn có thể tính Q(s, a) nếu muốn. Tuy nhiên mục tiêu cuối cùng của RL vẫn là tìm ra policy tối ưu, chứ không phải tìm V(s) hay Q(s,a), mà từ V(s) vẫn có thể dùng \arg\max để tìm policy tối ưu, thành ra V(s) hay Q(s, a) cũng không còn quan trọng nữa.

Mọi chuyện sẽ dễ dàng hơn khi ta xem ví dụ sau. Cho một MDP với mô hình chuyển trạng thái T và hàm reward R như sau:


Mô hình này có 6 trạng thái. Khi chuyển từ s_1 sang s_3 thì reward nhận được là +1, nghĩa là R(s_1, a) = +1. Tương tự như vậy cho các trạng thái khác. s_F là trạng thái cuối cùng, trò chơi kết thúc khi agent đi đến trạng thái này.


[RL3a] Reinforcement Learning context

[RL1] Markov Decision process – Introduction
[RL2a] Markov Decision Process – Discounted Reward
[RL2b] Markov Decision Process – Bellman equation
[RL2c] Markov Decision Process – Solving Bellman equation
[RL2d] Bellman Equations revisited
[RL3a] Reinforcement Learning context

Lại nói tiếp chuyện Học củng cố. Trong các bài trước, ta đã xem xét mô hình Markov Decision Process (MDP) và các phương pháp giải MDP. Ta cũng đã nói qua về hàm Q-function, hàm quan trọng nhất trong MDP, có thể dùng để biểu diễn trạng thái của agent. Vì hàm này quan trọng nên viết lại ra đây:

\displaystyle Q\left(s, a\right) = R\left(s, a\right) + \gamma\sum_{s'}T\left(s,a,s'\right)\max_{a'}Q\left(s',a'\right)

Đương nhiên nếu ta biết trước mô hình (ma trận chuyển trạng thái T và hàm reward R), thì mọi chuyện không còn gì để bàn. Tưởng tượng là một agent, được thả vào trong môi trường lạ, agent này sẽ thực hiện một loạt các hành động a, rơi vào các trạng thái s và nhận được reward r. Nói cách khác, agent sẽ chỉ nhận được chuỗi <s_1, a_1, r_1>, <s_2, a_2, r_2>, ... và nhiệm vụ của nó là phải tìm ra policy \pi sao cho tối đa hoá expected reward. Reinforcement Learning, do đó, là thuật toán giúp agent tìm ra policy tối ưu, khi nó quan sát được chuỗi <s,a,r>*.

Có nhiều cách để làm việc này , nhưng nhìn chung có 3 cách sau:


  1. Model-based RL: trong cách này, trước tiên ta phải học được mô hình của MDP từ chuỗi <s,a,r>*, chẳng hạn T có thể là maximum likelihood estimation của các trạng thái, R là expected reward của mỗi trạng thái trong training set. Sau đó dùng các thuật toán trong phần trước để giải MDP và tìm ra policy tối ưu.
    Lưu ý là trong cách làm này, ta phải tìm cách ước lượng MDP.
  2. Value-function-based RL: ta tìm cách học trực tiếp hàm Q-function (nôm na là expected reward của agent khi ở trạng thái s và thực hiện hành động a), sau đó tìm policy tối ưu.
  3. Policy Search: trong cách này, ta trực tiếp tìm policy tối ưu từ training set, thay vì phải mô hình hoá Q-function.

Rõ ràng đi từ 1 đến 3 thì yêu cầu của thuật toán càng ngày càng “khó”, vì rõ ràng trong Policy Search thì rất khó để ước lượng trực tiếp policy tối ưu từ training set. Ta nói rằng Model-based RL thì more “supervised”.

Trong thực tế người ta chủ yếu tập trung vào Model-free RL. Chẳng hạn ta sẽ bàn về TD(\lambda) trong phần sau.

Bayesian Optimization part 1: Gaussians and Gaussian Process

SigOpt, công ty làm về Bayesian Optimization  mà có lần mình làm chung vài thứ linh tinh, có hẳn một booth trong KDD năm nay. Nói như Nando de Freitas: “Bayesian Optimization is a thing“, thành ra mình nghĩ nên viết vài bài nghiêm túc về món này.

Hai bài đầu tiên sẽ điểm qua vài công thức cơ bản của Gaussian và Gaussian Process. Bài cuối cùng sẽ nói về lí thuyết Bayesian Optimization và một số chi tiết khác hay gặp trong thực tế.

1. Sample a Gaussian

Cái này phù hợp để làm một câu hỏi phỏng vấn được (cho vị trí nào thì chưa biết): cho 1 hàm lấy số ngẫu nhiên theo phân phối đều trong khoảng [0, 1). Định nghĩa (hoặc viết thuật toán cho) hàm lấy số ngẫu nhiên trong các trường hợp sau:

  1. x \sim \mathcal{N}\left(0, 1\right), với x là scalar value.
  2. x \sim \mathcal{N}\left(\mu, \sigma^2\right), với x là scalar value.
  3. \mathbf{x} \sim \mathcal{N}\left(0,\mathbf{I}\right), với \mathbf{x} \in \mathbb{R}^d
  4. \mathbf{x} \sim \mathcal{N}\left(\mathbf{\mu},\mathbf{\Sigma}\right), với \mathbf{x} \in \mathbb{R}^d

Câu 1 rất đơn giản. Kĩ thuật chuẩn mực để làm việc này gọi là Inverse Transform Sampling. Ý tưởng chính là dùng phân phối cummulative của phân phối Gaussian, như hình sau:

Screen Shot 2016-08-18 at 15.22.45

Do hàm cummulative của phân phối Gaussian có miền giá trị là [0, 1] nên ta sẽ lấy mẫu từ phân phối đều (t_1t_2 trong hình), sau đó dùng hàm ngược của hàm cummulative để tìm giá trị tương ứng x_1x_2.

Lưu ý rằng ta chỉ làm được việc này do hàm cummulative là hàm đơn ánh, và ta tính được chính xác hàm ngược của nó. Trong trường hợp hàm ngược không tính được, ta cần tới các phương pháp phức tạp hơn như Rejection sampling hoặc Gibbs sampling.

Gọi x \sim \mathcal{N}\left(0, 1\right) là kết quả của câu 1, thì ta có thể dễ dàng có kết quả của câu hỏi 2 bằng cách tính z = \mu + \sigma x.

Với câu hỏi 3, để ý rằng ma trận covariance là ma trận đơn vị, nên các thành phần x_i trong vector \mathbf{x} là uncorrelated. Thành ra ta có thể lấy mẫu từng phần tử x_i \sim \mathcal{N}\left(0, 1\right) như trong câu 1, và ghép chúng lại thành vector \mathbf{x}.

Với câu hỏi 4, để thực hiện lại trick mà ta đã dùng trong câu 2, ta cần cách nào đó để tính “căn bậc 2” của ma trận covariance \mathbf{\Sigma}. Ta biết rằng phân tích Cholesky có thể biến đổi \mathbf{\Sigma} = \mathbf{LL^T}, nên trick này có thể được dùng lại:

\mathbf{z} = \mathbf{\mu} + \mathbf{Lx},
với \mathbf{x} \sim\mathcal{N}\left(0,\mathbf{I}\right) được lấy mẫu như trong câu 3.

2. Multivariate Gaussian Theorem

Giả sử ta có một phân phối Gaussian trong không gian 2 chiều, và hàm phân phối của nó được vẽ như sau:

Screen Shot 2016-08-18 at 15.23.08

Hai đường màu xanh thể hiện hàm phân phối xác suất đang nói. Phân phối này sẽ có dạng hình nón, với đỉnh nón khá tròn. Tưởng tượng ta dùng 1 con dao để bổ dọc cái nón này theo một đường song song với trục x_2, tại vị trí mà x_1 = C (mặt phẳng màu đen trong hình), thì mặt cắt của cái nón trên mặt phẳng vẫn sẽ là một phân phối Gaussian một chiều.

Đây là intuition quan trọng để hiểu một trong những định lí quan trọng nhất của phân phối Gaussian (cho đến khi mình biết định lí khác quan trọng hơn). Định lí này nói rằng nếu vector (x_1, x_2) tuân theo phân phối Gaussian 2 chiều thì phân phối có điều kiện của x_2 cho trước x_1 cũng là một Gaussian. Một cách tổng quát, định lí phát biểu như sau:

Giả sử \mathbf{x} = \left(\mathbf{x_1, x_2}\right) tuân theo phân phối Gaussian với tham số:

\boldmath{\mu} = \left(\begin{array}{c} \boldmath{\mu}_1 \\ \boldmath{\mu}_2\end{array}\right) \;,\quad \boldmath{\Sigma} = \left(\begin{array}{cc}\boldmath{\Sigma}_{11} &\boldmath{\Sigma}_{12} \\  \boldmath{\Sigma}_{21} & \boldmath{\Sigma}_{22} \end{array}\right)\;,\quad \boldmath{\Lambda} = \boldmath{\Sigma}^{-1} = \left(\begin{array}{cc}\boldmath{\Lambda}_{11} &\boldmath{\Lambda}_{12} \\  \boldmath{\Lambda}_{21} & \boldmath{\Lambda}_{22} \end{array}\right)

thì các phân phối lề (marginals) là Gaussian:

\displaystyle \begin{array}{rl} p\left(\mathbf{x}_1\right) = & \mathcal{N}\left(\mathbf{x}_1; \boldmath{\mu}_1, \boldmath{\Sigma}_1\right) \\ p\left(\mathbf{x}_2\right) = & \mathcal{N}\left(\mathbf{x}_2; \boldmath{\mu}_2, \boldmath{\Sigma}_2\right)\end{array}

và phân phối có điều kiện cũng là Gaussian:

\displaystyle \begin{array}{rl} p\left(\mathbf{x}_1 \vert \mathbf{x}_2\right) = & \mathcal{N}\left(\mathbf{x}_1; \boldmath{\mu}_{1|2}, \boldmath{\Sigma}_{1|2}\right) \\ \boldmath{\mu}_{1|2} = &  \boldmath{\mu}_{1} + \boldmath{\Sigma}_{12}\boldmath{\Sigma}_{22}^{-1}\left(\mathbf{x}_2 - \boldmath{\mu}_2\right) \\ = & \boldmath{\mu}_{1} - \boldmath{\Lambda}_{11}^{-1}\boldmath{\Lambda}_{12}\left(\mathbf{x}_2 - \boldmath{\mu}_2\right) \\ = & \boldmath{\Sigma}_{1|2}\left(\boldmath{\Lambda}_{11}\boldmath{\mu}_1 - \boldmath{\Lambda}_{12}\left(\mathbf{x}_2 - \boldmath{\mu}_2\right)\right) \\ \boldmath{\Sigma}_{1|2} = & \boldmath{\Sigma}_{11} - \boldmath{\Sigma}_{12}\boldmath{\Sigma}_{22}^{-1}\boldmath{\Sigma}_{21} = \boldmath{\Lambda}_{11}^{-1}\end{array}

Nói chung toàn là Gaussian cả.

Định lí này được chứng minh trong các sách ML kinh điển, chẳng hạn quyển này. Đây cũng là nền tảng của Gaussian process, mà ta sẽ xem trong phần sau.

Deep Generative models : Recent advances – part 1

Một cách khá “mỉa mai”, thành công của Deep Learning gần đây chủ yếu tập trung trong các bài toán supervised, trong đó các mô hình Deep Learning chủ yếu học phân phối xác suất có điều kiện của label cho truớc input data. Một trong những ưu điểm đuợc quảng cáo nhiều nhất của Deep Learning là khả năng học feature từ dữ liệu, cuối cùng quy về thành việc học một chuỗi các hàm đơn giản, nhưng lồng với nhau để xấp xỉ phân phối xác suất cần học. “Nghệ thuật” Deep Learning, cuối cùng chẳng qua chỉ là nghệ thuật xấp xỉ một hàm số phức tạp (phân phối xác suất nào đó) bằng một chuỗi các hàm đơn giản. Ngay cả khi đó, nguời ta vẫn cần phải cung cấp nhãn thì các feature mới tốt đuợc. Học các feature từ dữ liệu không có nhãn (Unsupervised Feature Learning) vẫn là một bài toán khó.

Unsupervised Feature Learning không chỉ có mỗi K-means hay PCA (và họ hàng của nó). Sau thời của các phương pháp tuyến tính (PCA, SVD,…) thì đến thời của kernel methods và hằng hà sa số các phương pháp non-linear khác, gọi chung là manifold learning. Mặc dù các phương pháp này là non-linear, thông thường chúng cũng chỉ là một mapping từ không gian ban đầu sang không gian feature mới.

Một cách tổng quát, mapping từ không gian này sang không gian khác có thể biểu diễn bằng 1 hàm f: X \rightarrow D, biến mỗi phần tử x \in X thành f\left(x\right) \in D. Tùy vào f là hàm tuyến tính hay phi tuyến mà ta gọi thuật toán tuơng ứng. Các phuơng pháp feature learning khác nhau ở chỗ mỗi phương pháp sử dụng một vài giả sử a priori nào đó về dạng của hàm f, chẳng hạn với PCA thì f là hàm tuyến tính f(x) = Ax, với auto-encoder thì f(x) = \sigma(Ax +b), với mục tiêu là reconstruct đuợc dữ liệu ban đầu, v.v…


Review sách: The Master Algorithm


Dạo gần đây rảnh nên đọc được nhiều hơn, tạm thời sẽ review sách trước khi quay lại với series về Học củng cố (a.k.a. Reinforcement Learning).

Mình biết tới Pedro Domingos cách đây vài năm, khi đang làm vài thứ liên quan tới Sum-Product Networks. Lúc đó khá ấn tượng với paper SPN, vì cách tiếp cận thật sự rất fresh và original. Mặc dù vậy SPN có những hạn chế cố hữu (có thể sẽ viết 1 bài riêng về cái này) nên ứng dụng thực tế không nhiều. Tiếp theo “truyền thống” đó, sách này của Domingos cũng trình bày 1 góc nhìn tươi mới và hệ thống về Machine Learning nói chung.

Đọc sách này, người đọc rất dễ liên tưởng tới A Brief History of Time của Stephen Hawking. Cả 2 đều là sách nhập môn dành cho người không chuyên, một quyển cho Vật lí hiện đại và quyển kia cho Máy học. Cả 2 quyển sách đều làm việc đó bằng cách kể một câu chuyện, đều bắt đầu và diễn tiến bằng mục tiêu đi tìm một lí thuyết chung nhất cho lĩnh vực của nó: trong sách của Hawking là sự hợp nhất Thuyết tương đối rộng của Einstein với Quantum physics, trong sách của Domigos là universal learner: thuật toán “trùm cuối” của cả ngành Machine Learning. Mỗi quyển sách đều chỉ chứa đúng 1 công thức: sách của Hawking là E = mC^2, của Domingos là công thức của Markov Logic Networks. Thậm chí không biết vô tình hay cố ý, Domigos còn sử dụng chính xác định nghĩa của Hawking về scientific theory.