因为RBN,学习了一会儿MCMC,理解不太深,但在接触Bayesian GAN时碰到HMC又很晕,好在看了两篇博客,重新梳理了MCMC,对HMC有了点初步理解,整理如下。
两篇博客一篇是CSDN,一篇是WordPress上的。CSDN应该是翻译WordPress上的。
- theclevermachine博客
https://theclevermachine.wordpress.com/2012/11/18/mcmc-hamiltonian-monte-carlo-a-k-a-hybrid-monte-carlo/- CSDN翻译博客,http://blog.csdn.net/qy20115549/article/details/54561643
上述博客对细致平稳条件没有多加解释,因此理解有点困难。
这个总是容易忘记,Monte Carlo算法就是随机过程的模拟算法,模拟的输出就是随机过程的样本。通过对模拟得到的样本进行统计,我们就可以求积分,求最优解,当然求出来的都是可以实际应用的近似值(Approximation)。
如果需要求积分 ∫baf(x)dx ,可以模拟一个概率分布为 q(x) 过程,采样得到N个样本,从而该积分可以用下式进行近似:
如果需要求 q(x) 的最大值,可以将 q(x) 归一化为概率分布,模拟q(x)过程,采样得到N个样本,统计样本分布最密的区间就是最优值所在的区间。
对于任意的概率分布 p(z) 计算机很难直接模拟,计算机能够模拟的是均匀分布、正态分布等一些简单分布。接受拒绝采样算法就是从容易模拟的概率分布中得到样本,在根据一定的接受拒绝规则来再次选择样本。如下图:
第一步:红色p(z)难以直接采样,蓝色q(z)可以直接采样,先根据q(z)采样得到 z0 ;注意要合理选择k使得 kq(z)≥p(z)
第二步:再在[0 kq( z0 )]采样一个 u0 ,如果 u0 >p( z0 ),则拒绝 z0 。
因此, z0 被接受概率为 q(z0)(p(z0)/kq(z0)=p(z0)/k ,所以在所有采样样本空间中被接受的样本分布为p(x)/k,在被接受样本空间中样本分布为p(x),样本的接受概率为1/k,因此,如果k太大,则样本拒绝率太高。
马尔科夫链随机模拟的原理是基于马尔科夫链的平稳特性,对于满足一定条件的状态转移概率矩阵 P=[pij] 总对应一个马尔科夫平稳状态 π 。平稳状态和状态转移概率矩阵之间满足细致平稳条件,即两个状态相互转移的概率相等:
下面为Metropolis算法,其中 α(i,j) , α(j,i) 为接受拒绝概率, q(i,j) 为状态i到状态j的初始转移概率。如果, α(i,j)=p(j)q(j,i)α(j,i)=p(i)q(i,j) ,则下面细致平稳条件满足:
对于多维状态的情况任意两状态 A=(X1,X2)B=(X1,X3) ,由条件概率公式可得到细致平稳条件的状态转移概率矩阵:
HMC算法应该也算是一种Metropolis-Hasting算法,通过Hamiltonian偏微分方程来实现初始状态转移,通过接受拒绝算法来满足细致平稳条件。与普通的Metropolis-Hasting算法的区别在于其初始状态转移是确定的,即概率为1(相比普通的 q(i,j)≤1 随机游走的方式提高了接受概率,从而提高了收敛速度)。只是由于Hamiltonian偏微分方程离散化计算误差导致产生了状态偏移,从而需要对偏移状态进行接受拒绝选择来达到细致平稳条件的满足。
系统方程:
1)对于任一q的初始状态 q0 ,按照分布 1Zpexp(−K(p)) 采样得到 p0
2) 从 p0,q0 根据Hamiltonian方程得到 p1,q1 ,将 q1 赋给 q0 ,回到第一步继续计算 q1 。
3)重复1,2步骤,得到q的采样序列。则q稳态的概率分布为 1Zqexp(−U(q))
证明:
假设q的稳态分布为, 1Zqexp(−f(q)) ,
所以Hamiltonian系统Markov链的状态转移概率等式为:
HMC的目标是模拟实现 1Z1exp(−U(q)) !
实现思路是:
1)首先构造一个容易模拟的正态分布 1Zpexp(−K(p))
2)模拟Hamiltionian系统的Markov链实现对q的采样
3)根据前面Hamiltonian系统Markov链性质,q的稳态分布为 1Zqexp(−U(q))
算法步骤:
任意取一个q的初始状态 q1
重复如下计算:
1)依据正态分布采样得到 p1 和 q1
2)以 p1 和 q1 为初值,根据Hamiltonian方程计算L步,得到 (q2,p2)
3)计算 (q2,p2) 的接受拒绝概率:
仿照theclevermachine博客中的matlab代码,用python实现HMC模拟采样双正态分布,代码在csdn资源上:http://download.csdn.net/download/tkyjqh/10176310
发现matlab实现中有两个细节差异:
1)U函数没有除2
2)Hamiltonian计算并没有全部采用Leap-Frog算法。
在python实现时,试图改进。结果如下:
1)采用Leap-Frog算法,U函数不除2,接受概率1
2)采用Leap-Frog算法,U函数除2,接受概率1
3)采用Euller算法,U函数不除2,接受概率0.73
4)采用Euller算法,U函数除2,接受概率0.98
统计接受概率可以发现Leap-Frog算法基本上全接受,采用Euller算法,接受概率将降低,而且U是否除2将影响接受概率。