以下和论文中一样,只考虑只用右手、只有单音(没有和弦)的情况。
t=[0, 1]时的概率,就表示弹奏前两个音符所用的各种指法的概率。图中的网状图就是一个Trellis graph,每条边对应一次HMM状态转换同时也对应着(在t>0时的)弹出一个音符的动作;每个结点对应着一个手指,也就是能够用以弹奏某个音的某个手指。每条有颜色的路径就表示某个片段中的指法安排。Viterbi算法是一种动态规划,所以它在每一步时都需要把“对于每个手指,从开始到这一步时,这一步必用这个手指的最高的概率和对应的指法”存在动态规划表里,以供下一步的计算使用。
从这个图所反映的动态规划表中可以看出,用右手小拇指弹第一个音E5,然后再用右手食指弹第二个音B4的概率是所有25种可能中概率最高的,其概率高达10^(-2.31009)。这个概率并没有什么实际意义,只在对所有指法间进行比较有意义。相比起来,用右手大拇指弹奏第一个音E5再用右手小拇指弹奏第二个音B4的概率就低多了,只有10^(-13.0603),这是个穿指的动作,而穿指从大拇指穿到小拇指也比从食指、中指和无名指穿到小指要简单,所以指向t=1时的5的箭头是从1指向5的。这是Viterbi算法在构建动态规划表中的规则。 这个表的内容会用到t=[0,1,2]的情况,如下:
指的就是此图在t=[0,1]中的箭头都是在上一张中出现过的箭头的意思。
再继续一步:
将这个过程重复到最后,就得到了这一段谱子的指法:
在这张动态规划表中,概率最大的是[5231421]这个指法,也就是图中所示的。 以上就是这篇论文中所描述的“用HMM来计算给定的一段乐谱的最佳指法”的方法。
最后,就是Training阶段——如何通过训练HMM参数的方法来“学到”测试用例呢?
在实现此论文的过程中我对于具体计算输出概率的方法是用了一些猜测的,所以与原文可能有所不符,所以将论文中所出现的7个乐谱片段输入后,有3、4个音符的指法与文中提及的结果不同。所以我想通过调整参数的方法让我的HMM的输出结果能与论文中相符。
说是Bonus阶段是,因为论文中没有明示这一阶段是如何做的,但是有提及根据常理是可以把这个训练过程做成的。
这回用于训练用的是随机梯度下降法(Stochastic gradient descent),这种方法可以用于参数都是连续变量、目标函数也是连续变量的模型。其最基本的更新规则是
,
其中w是参数,alpha是学习速率,p是Viterbi算法算出的最佳指法与训练用例指法的分数之
差,当梯度下降完成时,训练用例中的指法就会变成所有指法中最优的并被Viterbi找到,也就
是p会等于0 。
训练过程中给HMM模型不停地出示正确的指法就像是不停背诵英语单词强化记忆一样。以下示出用论文中出现的7个片段用作训练的样子。训练中能修正的HMM参数有以下这些: ?转换概率(25个)
?五个手指与黑/白键的接触点的Y轴坐标(10个) 一共是35个可以调整的参数。
在训练前,我们猜测出来的参数做成的HMM输出的指法能够符合这7个训练用例中的5个(以下为论文中的谱子的截图,黑色的圈是在论文中用作指法合理性的讨论的,和此回需要进行的重现算法的任务没有关系):
可以看到图中有两处红字是我们当前的HMM输出的指法与训练用例的指法不同之处。现在将这七个片段放入Stochastic Descent过程中,随着其进行,可以将参数的变化和目标函数的变化画在下图中:
三栏中,最上栏是分数之差,也就是对每个训练用例,给定的训练指法与当前最好的指法的分数之差,为0表示给定的训练指法就是最佳指法。中间栏是转换概率。最下栏是10个接触点的Y轴坐标。
可以看到分数之差随着训练的进行总体上的趋势是在接近0。当训练完成后,这个HMM就能复制出图中所示的7个片段中的指法啦! \^O^/
如果再展开还有许多问题:对于Stochastic Descent还可以通过自动调整学习速率的方法来加快计算;训练过程不一定是Consistent的,意即总会到某个时候不可能完全复制出训练用例中的指法;和弦和双手两个声部的处理,但是这些就是不同于此问题的另一问题了,而且我也不是非常理解,所以就不在这里写啦。
[1]:在重现这篇论文的结果时我们认为尽管原论文并没有说,但是y_{i-1}还是有必要出现在竖线的右边的。按我们的理解,原文并非是完全没有说,而是隐含地用了y_{i-1}来得到计算输出概率时高斯分布的中心点的位置。
(手机码字,继续欠修改)WARNING:这篇文章是给零基础人士看的。目标是让普通初中生以及只有初中基础人士无障碍理解HMM框架。追求数学严谨性人士、追求用简洁符号表达模型的同学以及数理基础良好的大神请自行移步参阅文献。讲这种东西就得先搞清HMM到底干了… 显示全部
(手机码字,继续欠修改)
WARNING:这篇文章是给零基础人士看的。目标是让普通初中生以及只有初中基础人士无障碍理解HMM框架。追求数学严谨性人士、追求用简洁符号表达模型的同学以及数理基础良好
的大神请自行移步参阅文献。
讲这种东西就得先搞清HMM到底干了什么,初学者很容易对“模型在干嘛”这个问题上犯晕。我个人特别讨厌跟初学者上来就讲state space/transition matrix/emission probability云云的讲法(注:比如《统计学习方法》李航博士那种讲法。虽然用来准备面试很方便,但初学者肯定会被符号和几个概念绕晕了;另外,私以为他换掉符号和前人文献不保持一致的做法又会让初学者又多了一道坎去翻。总之,不太厚道)。因为初学时,对大多非理科出身的人而言,用抽象的名词与符号描述的“语言系统”还没固化在脑袋里。用抽象符号在那儿讲就好比“一群人还没学会走,就逼着他们快点跑”。这是不太现实的。
综上,用复杂抽象的语言描述不合适的,这个学习曲线过于陡峭,别人需要时间消化。基于此原因,我发现,对零基础小伙伴们用游戏的例子去类比地解释往往比较容易降低学习难度,比如这样讲:
我是一战士,修炼出了三种战斗形态,分别为暴怒态,正常状态和防御态。同时我也会三个被动技能,分别是普通平A,爆击(攻击伤害翻倍),吸血(生命汲取)。 我在暴怒状态下打出暴击的概率是80%,打出吸血概率为5%; 在平衡形态下,打出暴击的比率为30%,打出吸血的概率是20%; 在防御形态下,暴击成功概率为5%,吸血概率为60%。 总结一下,战士在不同状态下能打出技能的概率不一样。
本来,战士这个职业在暴怒态时,身边会有一圈红光环;防御态时,会有一圈蓝光环。但是,现
在我正在玩游戏,游戏突然出了个bug:有个傻x程序员改了游戏的代码,他给写崩了,从此战士身边光环都看不见了。那我没法通过看脚下的光环知道战士在爆什么状态了。
话说,现在问题来了:由于看不到脚下光环,我只能估计“战士”在爆什么状态;但我现在打一boss,砍10次,发现8次都是暴击,血哗哗地翻倍在掉,你觉得我这战士最可能是爆了什么状态?
(每次用这个不规范的例子和新手讲,他们立刻就懂了;而且他们接下来还会问:\’暴怒状态’不能总持续吧?这不科学,应该限定个一段时间后,暴怒状态消失的概率为50%....\你瞧瞧连状态转换的transition prob自己都能假设出来了,都会抢答了都lol...“HMM的在干什么”的问题很容易地让他们就理解了)
综上,一个战士的状态会不断随时间变化;然后他的被动技能发动概率会因为所处不同状态而不同。这就是HMM想表达的东西。并且我们还可以通过它回答一些有趣的问题:通过战士发动的技能来推测战士所出的状态。
这个例子只是个感性认识,它其实只是告诉了我们hmm比较“像什么东西”。显然,我们还需要更规范更严谨地去介绍什么是HMM,去规范化这个模型。这个例子里的“战士”可以换成其它答案里的天气,换成硬币等等。但无论用什么说法,我们已经能通过这个例子抓住核心问题了:HMM模型就是这样一个系统——它有一个能不断改变的隐藏的状态(在这个例子里就是战士爆的状态。它会变,而且由于一个码农的缘故,状态变得不可见)在持续地影响它的外在表现(在这个例子里就是战士打出的技能是暴击、平a、还是吸血的概率)。再重复一遍:HMM