玄同 765

大语言模型 (LLM) 开发工程师 | 中国传媒大学 · 数字媒体技术(智能交互与游戏设计)

CSDN · 个人主页 | GitHub · Follow


关于作者

  • 深耕领域:大语言模型开发 / RAG 知识库 / AI Agent 落地 / 模型微调
  • 技术栈:Python | RAG (LangChain / Dify + Milvus) | FastAPI + Docker
  • 工程能力:专注模型工程化部署、知识库构建与优化,擅长全流程解决方案

「让 AI 交互更智能,让技术落地更高效」
欢迎技术探讨与项目合作,解锁大模型与智能交互的无限可能!


【论文解读】隐马尔可夫模型:语音识别领域的奠基之作

论文:A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition
作者:Lawrence R. Rabiner
发表期刊:Proceedings of the IEEE (1989)
引用次数:40000+

摘要:隐马尔可夫模型(Hidden Markov Model, HMM)是统计建模的经典方法,被誉为"HMM圣经"。该论文系统阐述了HMM的三大核心问题——评估、解码、学习,以及对应的三大算法——前向-后向算法、Viterbi算法、Baum-Welch算法。本文深入解析HMM的数学原理、算法实现及其在语音识别中的经典应用。


一、为什么需要隐马尔可夫模型?

在许多实际问题中,我们观察到的只是现象,而非本质。以语音识别为例,我们听到的是声学信号,但真正关心的是背后的词语序列。声学信号是可观测的,词语序列是隐藏的。如何从可观测序列推断隐藏状态?这正是HMM要解决的问题。

HMM的核心思想是:系统存在一组隐藏状态,状态之间按马尔可夫性质转移,每个状态以一定概率产生可观测的输出。这种建模方式优雅地捕捉了"隐藏-观测"的层次结构。

观测层

隐藏状态层

a₁₁

a₁₂

a₂₁

a₂₂

b₁(o)

b₁(o)

b₁(o)

b₂(o)

b₂(o)

b₂(o)

状态1

状态2

观测1

观测2

观测3


二、HMM的数学定义

一个HMM由五元组λ = (S, V, π, A, B)定义:

  • S:隐藏状态集合,N个状态
  • V:观测符号集合,M个符号
  • π:初始状态分布
  • A:状态转移概率矩阵,A = [aᵢⱼ],aᵢⱼ = P(qₜ₊₁ = j | qₜ = i)
  • B:观测概率矩阵,B = [bⱼ(k)],bⱼ(k) = P(oₜ = vₖ | qₜ = j)

HMM基于两个基本假设:

  1. 马尔可夫假设:当前状态只依赖于前一状态
  2. 输出独立假设:观测只依赖于当前状态

三、三大核心问题与算法

HMM的精髓在于三个基本问题及其解决方案。

3.1 评估问题:前向-后向算法

问题:给定模型λ和观测序列O,计算P(O|λ)

解决方案:前向算法

定义前向变量αₜ(i) = P(o₁, o₂, …, oₜ, qₜ = i | λ)

import numpy as np
from typing import List, Tuple


class HMM:
    """
    隐马尔可夫模型
    
    实现HMM的三大核心算法:
    前向-后向算法、Viterbi算法、Baum-Welch算法。
    
    Attributes:
        n_states: 状态数量
        n_observations: 观测符号数量
        pi: 初始状态分布
        A: 状态转移矩阵
        B: 观测概率矩阵
    """
    
    def __init__(
        self,
        n_states: int,
        n_observations: int
    ):
        self.n_states = n_states
        self.n_observations = n_observations
        
        self.pi = np.random.rand(n_states)
        self.pi /= self.pi.sum()
        
        self.A = np.random.rand(n_states, n_states)
        self.A /= self.A.sum(axis=1, keepdims=True)
        
        self.B = np.random.rand(n_states, n_observations)
        self.B /= self.B.sum(axis=1, keepdims=True)
    
    def forward(self, observations: List[int]) -> Tuple[np.ndarray, float]:
        """
        前向算法
        
        计算观测序列的概率P(O|λ)。
        
        Args:
            observations: 观测序列
            
        Returns:
            alpha: 前向变量矩阵 [T, N]
            prob: 观测序列概率
        """
        T = len(observations)
        alpha = np.zeros((T, self.n_states))
        
        alpha[0] = self.pi * self.B[:, observations[0]]
        
        for t in range(1, T):
            for j in range(self.n_states):
                alpha[t, j] = alpha[t-1] @ self.A[:, j] * self.B[j, observations[t]]
        
        prob = alpha[-1].sum()
        
        return alpha, prob
    
    def backward(self, observations: List[int]) -> np.ndarray:
        """
        后向算法
        
        计算后向变量β。
        
        Args:
            observations: 观测序列
            
        Returns:
            beta: 后向变量矩阵 [T, N]
        """
        T = len(observations)
        beta = np.zeros((T, self.n_states))
        
        beta[-1] = 1.0
        
        for t in range(T - 2, -1, -1):
            for i in range(self.n_states):
                beta[t, i] = np.sum(
                    self.A[i, :] * 
                    self.B[:, observations[t+1]] * 
                    beta[t+1]
                )
        
        return beta

3.2 解码问题:Viterbi算法

问题:给定模型λ和观测序列O,找出最可能的状态序列Q*

解决方案:Viterbi算法

定义δₜ(i) = max P(q₁, q₂, …, qₜ₋₁, qₜ = i, o₁, …, oₜ | λ)

def viterbi(self, observations: List[int]) -> Tuple[List[int], float]:
    """
    Viterbi算法
    
    找出最可能的状态序列。
    
    Args:
        observations: 观测序列
        
    Returns:
        path: 最优状态序列
        prob: 最优路径概率
    """
    T = len(observations)
    delta = np.zeros((T, self.n_states))
    psi = np.zeros((T, self.n_states), dtype=int)
    
    delta[0] = self.pi * self.B[:, observations[0]]
    
    for t in range(1, T):
        for j in range(self.n_states):
            probs = delta[t-1] * self.A[:, j]
            psi[t, j] = np.argmax(probs)
            delta[t, j] = probs[psi[t, j]] * self.B[j, observations[t]]
    
    prob = delta[-1].max()
    last_state = delta[-1].argmax()
    
    path = [last_state]
    for t in range(T - 1, 0, -1):
        last_state = psi[t, last_state]
        path.append(last_state)
    
    path.reverse()
    
    return path, prob

3.3 学习问题:Baum-Welch算法

问题:给定观测序列O,估计模型参数λ

解决方案:Baum-Welch算法(EM算法的特例)

def baum_welch(
    self,
    observations: List[int],
    n_iterations: int = 10
) -> None:
    """
    Baum-Welch算法
    
    使用EM算法估计HMM参数。
    
    Args:
        observations: 观测序列
        n_iterations: 迭代次数
    """
    T = len(observations)
    
    for _ in range(n_iterations):
        alpha, prob = self.forward(observations)
        beta = self.backward(observations)
        
        gamma = alpha * beta / prob
        
        xi = np.zeros((T - 1, self.n_states, self.n_states))
        for t in range(T - 1):
            for i in range(self.n_states):
                for j in range(self.n_states):
                    xi[t, i, j] = (
                        alpha[t, i] * 
                        self.A[i, j] * 
                        self.B[j, observations[t+1]] * 
                        beta[t+1, j]
                    )
            xi[t] /= prob
        
        self.pi = gamma[0]
        
        self.A = xi.sum(axis=0) / gamma[:-1].sum(axis=0)[:, np.newaxis]
        
        for k in range(self.n_observations):
            mask = np.array(observations) == k
            self.B[:, k] = gamma[mask].sum(axis=0)
        self.B /= gamma.sum(axis=0)[:, np.newaxis]

四、HMM在语音识别中的应用

在语音识别中,HMM的隐藏状态对应音素或音节,观测对应声学特征。每个音素用一个HMM建模,通过Viterbi解码找到最可能的词序列。

HMM的优势在于:能够处理变长序列、训练数据需求相对较小、计算效率高。这些特点使其在语音识别领域统治了二十多年,直到深度学习兴起。


五、总结

隐马尔可夫模型是统计建模的经典之作。它的核心贡献可以概括为三点:优雅的数学框架,捕捉隐藏-观测的层次结构;三大算法,解决评估、解码、学习问题;广泛应用,成为语音识别、自然语言处理的基础工具。

HMM的启示在于:好的模型应该反映问题的本质结构。通过将隐藏状态与可观测输出分离,HMM为序列建模提供了一个强大而优雅的框架。


参考链接

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐