机器学习 —— 概率图模型(Homework: Exact Inference)

  在前三周的作业中,我构造了概率图模型并调用第三方的求解器对器进行了求解,最终获得了每个随机变量的分布(有向图),最大后验分布(双向图)。本周作业的主要内容就是自行编写概率图模型的求解器。实际上,从根本上来说求解器并不是必要的。其作用只是求取边缘分布或者MAP,在得到联合CPD后,寻找联合CPD的最大值即可获得MAP,对每个变量进行边缘分布求取即可获得边缘分布。但是,这种简单粗暴的方法效率极其低下,对于MAP求取而言,每次得到新的evidance时都要重新搜索CPD,对于单个变量分布而言,更是对每个变量都要反复进行整体边缘化。以一个长度为6字母的单词为例,联合CPD有着多达26^6个数据,反复操作会浪费大量的计算资源。

1、团树算法初始化

  团树算法背后的思路是分而治之。对于一组随机变量ABCDEFG,如果A和其他变量之间是独立的,那么无论是求边缘分布还是MAP都可以将A单独考虑。如果ABC联系比较紧密,CDE联系比较紧密,那么如果两个团关于C的边缘分布是相同的,则我们没有必要将ABCDE全部乘在一起再来分别求各个变量的边缘分布。因为反过来想,乘的时候也只是把对应的C乘起来,如果C的边缘分布相同,在相乘的时候其实两个团之间并没有引入其他信息,此时乘法不会对ABDE的边缘分布产生影响。团树算法的数学过程和Variable Elimination是相同的。

  PGM在计算机中的表达是factorLists,factor的var(i),var表示节点连接关系。val描述了factor中var的关系。cliqueTree其实是一种特殊的factorLists,它的var是clique,表示一堆聚类的var。它的val表示的还是var之间的关系。只不过此时var之间的连接不复存在了。所以clique由两个变量组成:1、cliqueTree 2、edges.

  团树算法的初始化可以分为两个过程:1、将变量抱团;2、获取团的初始势;

  变量抱团是一个玄学过程,因为有很多不同的抱法,而且还都是对的。比较常见的是最小边,最小割等...其实如果是人来判断很容易就能得到结果,但是使用计算机算法则要费一些功夫了。不过这不涉及我们对团树算法的理解,所以Koller教授代劳了。

  团的初始势表示团里变量之间的关系。其算法如下,需要注意的是不能重复使用factor.因为一个factor表达了一种关系,如果两个团里都有同一个factor,那么就是...这个事情。。。你帮他重复一遍。。。等于你也有责任的,晓得吧?

  

 1 %COMPUTEINITIALPOTENTIALS Sets up the cliques in the clique tree that is
 2 %passed in as a parameter.
 3 %
 4 %   P = COMPUTEINITIALPOTENTIALS(C) Takes the clique tree skeleton C which is a
 5 %   struct with three fields:
 6 %   - nodes: cell array representing the cliques in the tree.
 7 %   - edges: represents the adjacency matrix of the tree.
 8 %   - factorList: represents the list of factors that were used to build
 9 %   the tree.
10 %
11 %   It returns the standard form of a clique tree P that we will use through
12 %   the rest of the assigment. P is struct with two fields:
13 %   - cliqueList: represents an array of cliques with appropriate factors
14 %   from factorList assigned to each clique. Where the .val of each clique
15 %   is initialized to the initial potential of that clique.
16 %   - edges: represents the adjacency matrix of the tree.
17 %
18 % Copyright (C) Daphne Koller, Stanford University, 2012
19
20
21
22 function P = ComputeInitialPotentials(C)
23 Input = C;
24 % number of cliques
25 N = length(Input.nodes);
26
27 % initialize cluster potentials
28 P.cliqueList = repmat(struct(‘var‘, [], ‘card‘, [], ‘val‘, []), N, 1);
29 P.edges = zeros(N);
30
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 % YOUR CODE HERE
33 %
34 % First, compute an assignment of factors from factorList to cliques.
35 % Then use that assignment to initialize the cliques in cliqueList to
36 % their initial potentials.
37
38 % C.nodes is a list of cliques.
39 % So in your code, you should start with: P.cliqueList(i).var = C.nodes{i};
40 % Print out C to get a better understanding of its structure.
41 %
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 % N_factors = length(C.factorList);
44 for i = 1:N
45     k = 1;
46     clear clique_
47      N_factors = length(Input.factorList);
48     for j = 1:N_factors
49         if min(ismember(Input.factorList(j).var,Input.nodes{i}))
50             clique_(k) = Input.factorList(j);
51             k = k+1;
52             Input.factorList(j) =struct(‘var‘, [], ‘card‘, [], ‘val‘, []);
53         end
54     end
55     Joint_Dis_cliq = ComputeJointDistribution(clique_);
56     Joint_Dis_cliq_std = StandardizeFactors(Joint_Dis_cliq);
57     P.cliqueList(i) = Joint_Dis_cliq_std;
58 end
59 P.edges = Input.edges;
60 end

2、团树的校准

  继续之前的例子,ABC联系比较紧密,CDE联系比较紧密,所以抱成了两个团。如果其关于C的边缘分布相同,那么我们则可以在直接对两个团求ABDE的边缘分布,而不用乘起来了。然而令人悲伤的是现实中往往C的边缘分布是不同的。这时就需要对团树进行校准,希望经过“校准”这个操作后,两边关于C达成了一致意见。显然,一棵校准后的团树求任意一个变量的边缘分布都是方便的,只要对很小规模的联合分布进行边际化就行。

  要使得两边关于C的意见达成一致,最简单的方法就是把C在“A团”中的边缘分布乘以"E团”的势。反过来再把A在“E团”中的边缘分布乘以A团的势。那么此时C在两个团中的边缘分布就完全一样了 all = margin(C,A)*margin(C,E)。此即为团树校准的朴素想法。在数学上,团树的校准依然来自VE算法。让AB领盒饭后,C继续参加下一轮的VE。AB领盒饭剩下的C就是C在A团中的边缘分布。

  团树校准的关键是知道消息传播的顺序。消息一般先由叶向根传递,再由根向叶传递。并且,一个团在得到其所有邻团的消息之前,不能向下一个团传递消息。消息传递顺序获取算法如下:

  

 1 %COMPUTEINITIALPOTENTIALS Sets up the cliques in the clique tree that is
 2 %passed in as a parameter.
 3 %
 4 %   P = COMPUTEINITIALPOTENTIALS(C) Takes the clique tree skeleton C which is a
 5 %   struct with three fields:
 6 %   - nodes: cell array representing the cliques in the tree.
 7 %   - edges: represents the adjacency matrix of the tree.
 8 %   - factorList: represents the list of factors that were used to build
 9 %   the tree.
10 %
11 %   It returns the standard form of a clique tree P that we will use through
12 %   the rest of the assigment. P is struct with two fields:
13 %   - cliqueList: represents an array of cliques with appropriate factors
14 %   from factorList assigned to each clique. Where the .val of each clique
15 %   is initialized to the initial potential of that clique.
16 %   - edges: represents the adjacency matrix of the tree.
17 %
18 % Copyright (C) Daphne Koller, Stanford University, 2012
19
20
21
22 function P = ComputeInitialPotentials(C)
23 Input = C;
24 % number of cliques
25 N = length(Input.nodes);
26
27 % initialize cluster potentials
28 P.cliqueList = repmat(struct(‘var‘, [], ‘card‘, [], ‘val‘, []), N, 1);
29 P.edges = zeros(N);
30
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 % YOUR CODE HERE
33 %
34 % First, compute an assignment of factors from factorList to cliques.
35 % Then use that assignment to initialize the cliques in cliqueList to
36 % their initial potentials.
37
38 % C.nodes is a list of cliques.
39 % So in your code, you should start with: P.cliqueList(i).var = C.nodes{i};
40 % Print out C to get a better understanding of its structure.
41 %
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 % N_factors = length(C.factorList);
44 for i = 1:N
45     k = 1;
46     clear clique_
47      N_factors = length(Input.factorList);
48     for j = 1:N_factors
49         if min(ismember(Input.factorList(j).var,Input.nodes{i}))
50             clique_(k) = Input.factorList(j);
51             k = k+1;
52             Input.factorList(j) =struct(‘var‘, [], ‘card‘, [], ‘val‘, []);
53         end
54     end
55     Joint_Dis_cliq = ComputeJointDistribution(clique_);
56     Joint_Dis_cliq_std = StandardizeFactors(Joint_Dis_cliq);
57     P.cliqueList(i) = Joint_Dis_cliq_std;
58 end
59 P.edges = Input.edges;
60 end

  

  在获取消息传递顺序之后,则可进一步对被传递的消息进行计算。被传递的消息应为某个团对被传播变量的“所有认知”,所有认知则包括该团本身对该消息的认知,以及该团收到的“情报”。需要注意的是,向下家报告情报的时候要对所有信息进行总结,但是不能将下家告诉你的事情重复一遍。因为。。。重复一遍你也有责任的,知道吧。。。。

  

 1     while (1)
 2
 3       [i,j]=GetNextCliques(P,MESSAGES);
 4
 5       if i == 0
 6         break
 7       end
 8
 9       to_be_summed =  setdiff(P.cliqueList(i).var,P.cliqueList(j).var);
10       to_be_propogan  =  setdiff(P.cliqueList(i).var,to_be_summed);
11
12       tmp_ = 1;
13       clear factorList
14       for k = 1:N
15           if P.edges(i,k)==1&&k~=j&&~isempty(MESSAGES(k,i).var)
16               factorList(tmp_) = MESSAGES(k,i);
17               tmp_ = tmp_+1;
18           end
19       end
20       factorList(tmp_) = P.cliqueList(i);
21       MESSAGES(i,j) = ComputeMarginal(to_be_propogan,ComputeJointDistribution(factorList),[]);
22     end

  在消息完成从顶向下以及从下到上的传播后,每个团需要根据周边传来的消息进行总结。也就是把消息与本身的势相乘(消息是一种边缘分布)

 1 N = length(P.cliqueList);
 2     for i = 1:N
 3         tmp_ = 1;
 4         for k = 1:N
 5           if P.edges(i,k)==1
 6               factorList(tmp_) = MESSAGES(k,i);
 7               tmp_ = tmp_+1;
 8           end
 9         end
10         factorList(tmp_) = P.cliqueList(i);
11         belief(i) = ComputeJointDistribution(factorList);
12         clear factorList
13     end

  此时,团树称为已经校准。对各个团的中的变量进行marginal就可以得到每个变量的边缘分布了。

3、基于团树的MAP估计

  在很多时候,我们可能对单个变量的分布并不感兴趣,而是对[ABCDE]这个组合取哪个值概率最大感兴趣。这个思想可以用于信号解码,OCR,图像处理等领域。很多时候我们不关心单个像素的label是啥,只关心分割出来的像素块label是啥。这类问题称为最大后验估计(MAP)。

            argmaxP(AB)  = argmaxP(A)P(B|A) = argmax_a{P(A){argmax_bP(B|A)}

  显然,从上述过程中,很容易联想到之前提到的边际。只不过这里把边际换成了argmax。P(A){argmax_bP(B|A)}的结果依旧是分布,只不过这个分布的前提是无论A取哪个值,其assignment to val都对应着argmax_b。也就是说,此时如果选择最大的val,那么assignment则对应的是argmax_ab。这种操作的意义就在于可以对一组变量的MAP分而治之,最终单个变量的MAP就是全局MAP的一部分。此时的MESSAGE计算如下:

  

 1 for i = 1:N
 2     P.cliqueList(i).val = log(P.cliqueList(i).val);
 3 end
 4
 5     while (1)
 6
 7       [i,j]=GetNextCliques(P,MESSAGES);
 8
 9       if i == 0
10         break
11       end
12
13       to_be_summed =  setdiff(P.cliqueList(i).var,P.cliqueList(j).var);
14       to_be_propogan  =  setdiff(P.cliqueList(i).var,to_be_summed);
15
16       tmp_ = 1;
17       clear factorList
18       for k = 1:N
19           if P.edges(i,k)==1&&k~=j&&~isempty(MESSAGES(k,i).var)
20               factorList(tmp_) = MESSAGES(k,i);
21               tmp_ = tmp_+1;
22           end
23       end
24       factorList(tmp_) = P.cliqueList(i);
25       F = factorList;
26       Joint = F(1);
27         for l = 2:length(F)
28             % Iterate through factors and incorporate them into the joint distribution
29             Joint = FactorSum(Joint, F(l));
30         end
31       MESSAGES(i,j) = FactorMaxMarginalization(Joint,to_be_summed);
32     end

此处对val取对数是因为在map估计时,card一般都比较大。对应的val太小不便于作乘法(OCR的card是26!!!)

   消息的综合如下:

 1
 2     for i = 1:N
 3         tmp_ = 1;
 4         for k = 1:N
 5           if P.edges(i,k)==1
 6               factorList(tmp_) = MESSAGES(k,i);
 7               tmp_ = tmp_+1;
 8           end
 9         end
10      factorList(tmp_) = P.cliqueList(i);
11      F = factorList;
12      belief = F(1);
13         for l = 2:length(F)
14             % Iterate through factors and incorporate them into the joint distribution
15             belief = FactorSum(belief, F(l));
16         end
17
18      clear factorList
19      Belief(i) = belief;
20     end

  

4、总结

  团树算法作为一种精确推理算法在VE算法的基础上大幅减小了计算量和搜索空间。但其作为一种精确推理方法,依旧有着较大局限性。下周的Homework会以实现MCMC算法为目标~就是Alpha狗用的哪个蒙特卡罗哦~敬请期待。

所有代码请点这里

  

时间: 2024-10-17 15:33:24

机器学习 —— 概率图模型(Homework: Exact Inference)的相关文章

机器学习 —— 概率图模型(Homework: Week3)

前两周的作业主要是关于Factor以及有向图的构造,但是概率图模型中还有一种更强大的武器——双向图(无向图.Markov Network).与有向图不同,双向图可以描述两个var之间相互作用以及联系.描述的方式依旧是factor.本周的作业非常有实际意义——基于马尔科夫模型的图像文字识别系统(OCR) 图像文字识别系统(OCR)在人工智能中有着非常重要的应用.但是受到图像噪声,手写体变形,连笔等影响基于图像的文字识别系统比较复杂.PGM的重要作用就是解决那些测量过程复杂,测量结果不一定对,连续测

机器学习 —— 概率图模型(完结)

经过了一段时间的学习,我终于完成了PGM的所有视频课程,但是编程作业并没有结束.最大的体验是手里有了武器和手段,碰见问题不再束手无策或者需要根据自己的直觉经验来设计解决方法.其实按照目前的科技树而言,三种手段在手基本上就不需要担心任何综合型问题了:1.优化理论及方法; 2.深度学习理论:3.概率图模型.有这三种方法则可以对大部分学术问题进行建模,无论什么层面或是类别的问题,总能往这三种框架里塞.简直水文章之神器. 1.What is PGM PGM 是统计学与机器学习的混合题.其借鉴了统计学的概

机器学习 —— 概率图模型(学习:综述)

今天Google的机器人AlphaGo获得了围棋对阵李世石的第二场胜利,我也进入到概率图模型学习模块的阶段.Machine Learning 令人着迷也令人畏惧. ——题记 1.基于PGM的学习 ANN网络的拓扑结构往往是类似的.同一套模型以不同的样本进行训练,可以获得不同的结果.PGM可以人为的向网络中添加先验知识,在设计以及分析时有更好的可读性.此外,概率图模型在序列变量的学习上,要优于常规机器学习算法.本质上,基于PGM的学习是在给定Dataset的基础上,对随机变量的分布进行估计. 2.

机器学习 —— 概率图模型

概率图模型(PGM)是一种对现实情况进行描述的模型.其核心是条件概率,本质上是利用先验知识,确立一个随机变量之间的关联约束关系,最终达成方便求取条件概率的目的. 1.从现象出发---这个世界都是随机变量 这个世界都是随机变量. 第一,世界是未知的,是有多种可能性的. 第二,世界上一切都是相互联系的. 第三,随机变量是一种映射,把观测到的样本映射成数值的过程叫做随机变量. 上述三条原则给了我们以量化描述世界的手段,我们可以借此把一个抽象的问题变成一个数学问题.并且借助数学手段,发现问题,解决问题.

机器学习 —— 概率图模型(推理:连续时间模型)

有一种很重要的概率图模型用于SLAM,视觉追踪,识别,传感融合等领域,称为为Template Model. 其特征是每个状态具有多个随机变量,下个状态随机变量的取值受到上个状态的影响.并且随机变量之间的交互属于复制关系.如下图所示: 显然,普通的概率图模型的图是确定的,并不会图的结构不会改变,而这种Template Model的图结构会随着时间的改变自行增殖,故此模型的推理算法需要单独讨论. 1.变未知为已知,图的截断 一种简单的思路是在某个时间点对图模型进行截断,将增殖的PGM变为固定的PGM

机器学习——概率图模型(CPD)

CPD是conditional probability distribution的缩写,翻译成中文叫做 条件概率分布.在概率图中,条件概率分布是一个非常重要的概念.因为概率图研究的是随机变量之间的练习,练习就是条件,条件就要求条件概率. 对于简单的条件概率而言,我们可以用一个条件概率表来表达.如图1所示.图1 中表达的是p(g|i,d).幸运的是id都只有两个取值,是一个伯努利分布的函数.但是如果i d 有六个取值呢?比如骰子.那么这张表就会猛然增加到6^2那么长.这是不科学的.并且,常规情况下

机器学习 —— 概率图模型(推理:变量消除)

概率图的一个重要作用是进行推理,针对某个随机变量,告诉我们它到底有没有可能,有多大可能发生.之前在representation相关的内容中,我们更多的关心如何利用概率图减少联合分布的计算量.inference相关的章节就是要介绍如何从联合概率中获得单个随机变量的概率. 1.链状变量消除 对于给定的联合分布函数P(A,B,C,D,E),如果想要知道P(E),只需要将A,B,C,D边际掉.假设P(E)可以有两种取值P(e1),P(e2),P(e1) = P(a1,b1,c1,d1,e1)+P(a2,

机器学习 —— 概率图模型(学习:非完整数据)

1.综述 PGM的学习问题实际上是对参数进行推断.对于给定的数据,需要求出系统参数,从而完善系统的CPD.但是某些情况下,PGM的数据集可能是不完整的.数据集不完整可以分为两种情况:1.数据采集受到了影响:2.使用了隐变量.数据采集受到影响可能出于两种情况,第一种是影响与被采集数据是无关的,例如投硬币,结果硬币找不到了.第二种是和被采集数据有关的,例如在收发数据时,高电平总是踩空.故在使用不完整的数据对模型进行训练之前,需要对造成不完整的原因进行判断.如果对上述两种情况进行建模,则有以下图模型:

概率图模型基础

一.概念引入 很多事情是具有不确定性的.人们往往希望从不确定的东西里尽可能多的得到确定的知识.信息.为了达到这一目的,人们创建了概率理论来描述事物的不确定性.在这一基础上,人们希望能够通过已经知道的知识来推测出未知的事情,无论是现在.过去.还是将来.在这一过程中,模型往往是必须的,什么样的模型才是相对正确的?这又是我们需要解决的问题.这些问题出现在很多领域,包括模式识别.差错控制编码等. 概率图模型是解决这些问题的工具之一.从名字上可以看出,这是一种或是一类模型,同时运用了概率和图这两种数学工具