第四讲 隐马尔可夫模型 (HMM)学习笔记

1. 隐马尔可夫模型的基本概念

 首先来看一个例子,天气和冰淇淋问题。

在这里插入图片描述

定义

在这里插入图片描述

组成

在这里插入图片描述

基本假设

在这里插入图片描述

分类

在这里插入图片描述

生成过程

在这里插入图片描述

2. 隐马尔可夫模型的三个基本问题

概率计算问题

在这里插入图片描述

(1)直接计算法

在这里插入图片描述
 因为直接计算法的时间复杂度太高了,因此我们通常不使用这种算法。

(2)前向算法

在这里插入图片描述

在这里插入图片描述

通过使用前向算法,我们便可以轻松求得观测序列的概率。但后面学习问题中的Baum-Welch学习算法涉及到后向算法的使用,因此下面我们来介绍第三种概率计算算法:后向算法。

(3)后向算法

在这里插入图片描述

预测问题

在这里插入图片描述

Viterbi算法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

学习问题

在这里插入图片描述

(1)Viterbi学习算法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(2)Baum-Welch学习算法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. 总结

 本节课内容重要,讲述了HMM的基本概念和三个基本问题,理论知识很多。尤其是学习算法中的Viterbi学习算法和Baum-Welch学习算法,课下需反复温习。

4. 作业代码

# Author: Kaituo Xu, Fan Yu
import numpy as np


# 前向算法
def forward_algorithm(O, HMM_model):
    """HMM Forward Algorithm.
    Args:
        O: (o1, o2, ..., oT), observations
        HMM_model: (pi, A, B), (init state prob, transition prob, emitting prob)
    Return:
        prob: the probability of HMM_model generating O.
    """
    pi, A, B = HMM_model
    # 观测序列的长度记为T
    T = len(O)
    # 状态共有N种
    N = len(pi)
    prob = 0.0
    # Begin Assignment

    # Put Your Code Here

    # 第一步,初始化alpha并计算其初值
    alpha = np.zeros((T, N))
    for i in range(N):
        alpha[0][i] = pi[i] * B[i][O[0]]
    # 第二步,开始递推,直到达到终止条件,复杂度为O(T*N^2)
    for t in range(1, T):
        for i in range(N):
            temp = 0.0
            for j in range(N):
                temp += alpha[t - 1][j] * A[j][i]
            alpha[t][i] = temp * B[i][O[t]]
    # 求和
    for i in range(N):
        prob += alpha[T - 1][i]
    # End Assignment
    return prob


# 后向算法
def backward_algorithm(O, HMM_model):
    """HMM Backward Algorithm.
    Args:
        O: (o1, o2, ..., oT), observations
        HMM_model: (pi, A, B), (init state prob, transition prob, emitting prob)
    Return:
        prob: the probability of HMM_model generating O.
    """
    pi, A, B = HMM_model
    T = len(O)
    N = len(pi)
    prob = 0.0
    # Begin Assignment

    # Put Your Code Here
    # 第一步,初始化beta并计算其初值
    beta = np.zeros((T, N))
    for i in range(N):
        beta[T - 1][i] = 1
    # 第二步,开始递推,直到达到终止条件,复杂度也为O(T*N^2)
    for t in range(T - 2, -1, -1):
        for i in range(N):
            temp = 0.0
            for j in range(N):
                temp += A[i][j] * B[j][O[t + 1]] * beta[t + 1][j]
            beta[t][i] = temp
    # 求和
    for i in range(N):
        prob += pi[i] * B[i][O[0]] * beta[0][i]
    # End Assignment
    return prob


# 维特比算法
def Viterbi_algorithm(O, HMM_model):
    """Viterbi decoding.
    Args:
        O: (o1, o2, ..., oT), observations
        HMM_model: (pi, A, B), (init state prob, transition prob, emitting prob)
    Returns:
        best_prob: the probability of the best state sequence
        best_path: the best state sequence
    """
    pi, A, B = HMM_model
    T = len(O)
    N = len(pi)
    best_prob, best_path = 0.0, []
    # Begin Assignment

    # Put Your Code Here
    # 第一步初始化
    A_max = np.zeros((T, N))
    Path = np.zeros((T, N), dtype=np.int32)
    for i in range(N):
        A_max[0][i] = pi[i] * B[i][O[0]]
        Path[0][i] = -1

    # 第二步,开始递推,直到达到终止条件
    for t in range(1, T):
        for i in range(N):
            temp = np.zeros(N)
            for j in range(N):
                temp[j] = A_max[t - 1][j] * A[j][i]
            A_max[t][i] = temp.max() * B[i][O[t]]
            Path[t][i] = temp.argmax()
    # 对数组进行数值填充,从而可以通过索引改变值
    for t in range(T):
        best_path.append(-1)
    # 筛选出最大的概率
    best_prob = A_max[T - 1].max()
    # 筛选出对应的It*
    best_path[T - 1] = A_max[T - 1].argmax()
    # 最优路径回溯
    for t in range(T - 2, -1, -1):
        best_path[t] = Path[t + 1][best_path[t + 1]]

    # 最优回溯完成后,要将best_path存储的状态下标加1转换成状态。
    for t in range(T):
        best_path[t] += 1
        # 转换为(时刻,状态)进行输出
        best_path[t] = tuple((t+1, best_path[t]))
    # End Assignment

    return best_prob, best_path


if __name__ == "__main__":
    # 状态集合= {1, 2, 3} ,观测集合= {红,白} N=3,M=2
    color2id = {"RED": 0, "WHITE": 1}
    # model parameters
    # 初始状态概率向量
    pi = [0.2, 0.4, 0.4]
    # 状态转移概率矩阵(N,N)
    A = [[0.5, 0.2, 0.3],
         [0.3, 0.5, 0.2],
         [0.2, 0.3, 0.5]]
    # 观测概率矩阵 (N,M)
    B = [[0.5, 0.5],
         [0.4, 0.6],
         [0.7, 0.3]]
    # input
    observations = (0, 1, 0)
    HMM_model = (pi, A, B)
    # process
    observ_prob_forward = forward_algorithm(observations, HMM_model)
    print(observ_prob_forward)

    observ_prob_backward = backward_algorithm(observations, HMM_model)
    print(observ_prob_backward)

    best_prob, best_path = Viterbi_algorithm(observations, HMM_model)
    print(best_prob, best_path)

作业链接:https://github.com/nwpuaslp/ASR_Course/tree/master/04-HMM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值