Viterbi 原理及简单实现

Viterbi 原理及简单实现

维特比算法:

维特比算法由安德鲁·维特比(Andrew Viterbi) 于1967年提出,用于在数字通信链路中解卷积以消除噪音。 此算法被广泛应用于 CDMA 和 GSM 数字蜂窝网络、拨号调制解调器、卫星、深空通信和 802.11 无线网络中解卷积码。维特比算法是一个特殊但应用最广的动态规划算法。利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图—篱笆网络(Lattice)的有向图最短路径问题而提出的。它之所以重要,是因为凡是使用隐含马尔可夫模型描述的问题都可以用它来解码,包括今天的数字通信、语音识别、机器翻译、拼音转汉字、分词等。

算法原理

维特比算法就是所有观测序列中的最优,如下图所示,我们要求从S到E的最优序列,中间有3个时刻,每个时刻都有对应的不同观察的概率。(其实过程类似于求解最短路径)

ca6fd480-40cf-4d76-8fac-f3eba49036ca

我们可以想到用暴力算法求解出所有的路径概率,然后找出最优的。但是当观察序列过长或者中间状态过多时会有很高的时间复杂度。这个时候就该viterbi算法出场了。

viterbi算法是每次记录到当前时刻,每个观察标签的最优序列。也就是我们可以将上图中的9个隐含状态看作是A、B、C三个group。以B组中的B1为例,B1只需要记录A几到B1是最优的而不用记录所有的An到B1的路径。如下图使用viterbi算法我们只需要记录其中黄色路径,其它部分的路径都可以不用储存。

在这里插入图片描述

image-20220921150239428

Python实现

import numpy as np

def viterbi_decoder(nodes , trans):
  """
    ## ViterBi 算法求解最优路径
  """
  seq_len, num_labels = len(nodes), len(trans)
  scores = nodes[0].reshape((-1, 1))

  paths = []
  for i in range(1, seq_len):
    observe = nodes[i].reshape((-1, 1))
    M = scores + trans + observe
    scores = np.max(M, axis=0).reshape((-1, 1))
    idxs = np.max(M, axis=0)
    paths.append(idxs.tolist())
  
  best_path = [0] * seq_len
  best_path[-1] = np.argmax(scores)
  for i in range(seq_len - 2, -1, -1):
    idx = best_path[i+1]
    best_path[i] = paths[i][idx]

  return best_path 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值