[音声認識] JuliusでError: adin_oss: failed to open /dev/dsp

vagrant ec2にjuliusをダウンロードしてmacのマイクから音声認識をしようとしたところ、

$ ../julius/julius/julius -C mic.jconf -dnnconf dnn.jconf
### read waveform input
Stat: adin_oss: device name = /dev/dsp (application default)
Error: adin_oss: failed to open /dev/dsp
failed to begin input stream

どうやらsnd-pcm-ossで回避できるらしい。
$ sudo yum install osspd-alsa
329 packages excluded due to repository priority protections
????? osspd-alsa ?????????
エラー: 何もしません

別の方法を考えるか。

[音声認識] Juliusの認識アルゴリズム

### 入力音声の認識アルゴリズム
特徴量系列に対して、音響モデルと言語モデルの元で、確率が最大となる単語列を見つけ出す
ツリートレスト探索方式を基礎とするアルゴリズム
第一パスと第二パスの段階によって絞り込む
 L 単語履歴の 1-best近似, N-gram における 1-gram factoring, 部分線形化辞書, 単語間トライフォン近似を用いる
L 単語候補集合の算出

探索アルゴリズムによる調節可能なパラメータ
認識処理インスタンスごとに設定して精度を調整する
  解探索を行う際の仮説の足切り幅,すなわちビーム幅を設定できる

### 認識結果の出力
N-bestリスト
L 指定された数の文仮説数が見付かるまで探索を行う
単語ラティス形式
L 認識結果の上位仮説集合を,単語グラフ(ラティス)形式で出力できる
Confusion network
L 認識結果を confusion network の形で出力

### 複数モデルを用いた認識
入力に対して並列に認識を行い, 複数の結果を一度に得ることが可能
– 音響モデルインスタンの宣言(-AM)
– 言語モデルインスタンス(-LM)
– 認識処理インスタンス(-SR)
各指定のオプションをjconfファイルに記載する

### モジュールモード
Juliusをモジュールモードで起動することで、音声認識サーバとして動かすことができる。
起動後、クライアントからのTCP/IP接続待ちとなる
ADDGRAM, CHANGEGRAM では,クライアントから Julius へ文法を送信

### プラグイン
– 音声入力、音声後処理、特徴量入力、特徴量後処理、ガウス分布計算、結果取得、初期化・処理開始など

全体像については何となく理解できました。

[音声認識] Juliusの音響モデルと言語モデル

### 音響モデル
音響モデルとしてHMM(Hidden Markov Model)を用いることが出る。
コンテキスト非依存モデル、コンテキスト依存モデルまで扱える
出力確率モデルはガウス混合分布を基本として、tied-mixtureやphonetic tied-mixtureモデルを扱える

### 音響モデルのファイル形式
– HTK ascii形式
 L ASCII形式のHMM定義ファイルを読み込む
– Julius用バイナリ形式
L Julius用バイナリ形式へ変換しておくことで、読み込み時間を短縮できる
  L 特徴量抽出の条件パラメータを埋め込むこともできる
– HMMListファイル
L 単語辞書の音素表記、トライフォンの論理音素名、実際の音響モデル上の物理音素名との対応を与えることができる

### 音素コンテキスト依存モデル
与えられた音韻モデルが音素環境依存モデルであるかどうかをHMMの名称パターンから判定する(logical phoneとphysical phone)
単語間トライフォン近似とは、単語の前後に接続する読みの影響を受けて変化すること

状態遷移とマルチパスモード
L 音響モデル内の状態遷移のパターンを調べ、そのパターンに対応する効率的な計算処理を選択する

### 言語モデル
単語N-gram、記述文法、単語リストなどの言語モデルをサポートしている

– 単語辞書
L 認識対象とする単語とその読みを定義する
L ファイル形式はHTKの辞書フォーマットを拡張したもので第一フィールは言語制約の対応エントリ
  L 第二フィールはエントリ内確率、第三フィールドは出力文字列、以降は音素列
  L 情報が少ない場合は透過単語として指定する、無音用単語の追加もできる

– N-gram
  L N-gramファイルおよび各単語の読みを記述した単語辞書の2つをJuliusに与えて認識する
  L ARPA標準形式とJuliusバイナリ形式をサポートしている
  L SRIMでは、文開式記号について特殊な処理が行われる

デフォルトの語彙数は65534語である
与えられた文法上で可能な文のパターンから、入力に最もマッチする文候補が選ばれ、認識結果として出力される
  L grammarファイルとvocaファイルがある
L grammarファイルでは単語のカテゴリ間の構文制約をBNF風に記述する
  L vocaファイルはgrammarファイルで記述した終端記号ごとに単語を登録する ”%”で始まる行はカテゴリ定義

grammarファイルとvocaファイルをmkdfa.plを用いてdfaファイルとdictファイルに変換する

文法における文中の短時間無音の指定
 L 息継ぎによる発声休止を指定することができる

DFAファイルはオートマトン定義ファイルであり、文法制約を有限状態のオートマントンに変換している

– 単語リスト
音声コマンドや音声リモコンのような単純で簡単な音声認識を手軽に実現できるよう孤立単語認識を行える

—-
なるほど、grammarファイルとvocaファイルを作成してコンパイルするのね。
発音音素列の記述は英字で書くのか。
音声から文章にする場合は、形態素分析のように品詞の指定は行ってないのね。
ARPA標準フォーマットがどういう形式なのか気になるな。

[音声認識] Juliusの音声データ入力

### 基本フォーマット
– 量子化ビット数は16ビット固定
– チャンネル数は1チャンネル
– 入力のサンプリングレート(Hz)は、オプションで指定。デフォルトは16,000Hz
– .wavファイル、ヘッダ無しRAWファイルを読み込む
– 録音デバイス(16bit)からの直接入力
– ネットワーク・ソケット経由や特徴量ファイルの入力もできる

### フロントエンド処理
– 音声特徴量は、短時間ごとに切り出された音声信号から抽出される特徴ベクトルの時系列で、特徴抽出後、認識処理(解探索)を行う
– 特徴抽出の前処理にフロントエンド処理が実装されている
– 入力音声波形に対する信号処理

■直流成分除去
直流成分であるオフセット値の推定方法
 L 短時間音声区間ごとに行う方法と、長時間平均が用意されている

■スペクトルサブトラクション
雑音のスペクトルを推定して音声信号から減算することで雑音の影響を抑圧する(ファン音など定常雑音の除去)

### 特徴量抽出
メル周波数ケプストラム係数(MFCC)および派生パラメータを抽出できる
L 対数ケプストラムの低次成分に対して、ヒトの周波数知覚特性を考慮した重み付けをした特徴量を、メル周波数ケプストラム係数(MFCC)と呼ぶ

### 正規化処理
環境や話者の影響を軽減するため、算出後の特徴量に対して正規化処理を行うことができる
– CMN、CVN、周波数ワーピング

### 音声区間検出・入力棄却
音声が発話された区間を検出する音声区間検出(Voice activity detection)
短時間ごとに音声区間の開始終了を検出し、それを元に認識単位の切り出しおよび発話単位の区切りを行う
L 零交差数が一定数を超えた時に、音声始端として認識処理を行う
  L ガウス混合分布モデルによって、音声と非音声のGMMを定義し、開始終了を判別する方法もある
入力処理の終了後に、事後的に入力を棄却することもできる

音声の区間を検出して、MFCCで特徴量を抽出してるのね。なるほど、仕組みがわかるとちょっと考え方が変わるね。

[音声認識] What is Julius?

### Julius
Juliusとは?
L オープンソースの高性能な汎用大語彙連続音声認識エンジン
L 数万語彙の連続認識を実時間で実行できる
L 単語N-gram、記述文法、単語辞書を用いることができる
  L 音響モデルとしてトライフォンのGMM-HMM、DNN-HMMを用いたリアルタイム認識を行うことができる
  L 単語辞書や言語モデル、音響モデルなど、音声認識の各モジュールを組み替えることで、様々な用途に応用できる

※N-gramとは、連続するn個の単語や文字のまとまり
※GMM-HMMとは隠れマルコフモデルで、モデルを固定すると(与えられると)、そのモデルからどのような時系列データが生成されやすいのか、の確率を与える
※DNN-HMMとは、GMMを使ってガウス分布の確率値として求めるのではなく, DNNの事後確率を使って、間接的に(遠回りして)求める。

### Juliusを使うには
– 音響モデル(音素HMM) … 音声波形パターン
– 単語辞書 … 単語の読みを定義
– 言語モデル(単語N-gram) … どのような単語列が出しやすいか、単語間の接続制約を決定
– 動作環境: linux, mac, windows

### 処理フロー
– 音声入力部、特徴抽出部、認識処理部
 L リアルタイム認識の場合は並列処理される
– 第二パスでは、単語トレリスと呼ばれる仮説集合を参照しながら、入力全体に対して再認識を行う

mecabのmecab-ipadic-NEologdが、単語辞書に当たるのか。
単語辞書や単語N-gramを独自開発するのは難しいから、既存のものを使用して開発するのか。。これもC言語で書かれているのだろうか?
特徴を抽出して再認識か googleのspeech recognitionも同じかわからんが、凄いね

[Python3 音声認識] juliasを使ってみる

### juliusとは
– 京大や名古屋工業大が開発しているオープンソース音声認識ライブラリ
– C言語で書かれている
– 独自の辞書モデルを定義することが可能
– 単体では動作せず、言語認識をするモデルを読み込んで動かす
– Juliux GitHub: https://github.com/julius-speech/julius

### julius install
$ sudo yum install build-essential zlib1g-dev libsdl2-dev libasound2-dev
$ git clone https://github.com/julius-speech/julius.git
$ cd julius
$ ./configure –enable-words-int
$ make -j4
$ ls -l julius/julius
-rwxrwxr-x 1 vagrant vagrant 700208 Jul 31 16:39 julius/julius

### julius model
https://sourceforge.net/projects/juliusmodels/
「ENVR-v5.4.Dnn.Bin.zip」をDownloadします。
$ unzip ENVR-v5.4.Dnn.Bin.zip
$ cd ENVR-v5.4.Dnn.Bin
$ ls
ENVR-v5.3.am ENVR-v5.3.layer5_weight.npy ENVR-v5.3.prior
ENVR-v5.3.dct ENVR-v5.3.layer6_bias.npy README.md
ENVR-v5.3.layer2_bias.npy ENVR-v5.3.layer6_weight.npy dnn.jconf
ENVR-v5.3.layer2_weight.npy ENVR-v5.3.layerout_bias.npy julius-dnn-output.txt
ENVR-v5.3.layer3_bias.npy ENVR-v5.3.layerout_weight.npy julius-dnn.exe
ENVR-v5.3.layer3_weight.npy ENVR-v5.3.lm julius.jconf
ENVR-v5.3.layer4_bias.npy ENVR-v5.3.mfc mozilla.wav
ENVR-v5.3.layer4_weight.npy ENVR-v5.3.norm test.dbl
ENVR-v5.3.layer5_bias.npy ENVR-v5.3.phn wav_config

$ sudo vi dnn.jconf

feature_options -htkconf wav_config -cvn -cmnload ENVR-v5.3.norm -cvnstatic
// 省略
state_prior_log10nize false // 追加

### Recognize Audio File
$ ../julius/julius/julius -C julius.jconf -dnnconf dnn.jconf
————-pass1_best: the shower
pass1_best_wordseq: the shower
pass1_best_phonemeseq: sil | dh iy | sh aw ax r
pass1_best_score: 130.578949
### Recognition: 2nd pass (RL heuristic best-first)
STAT: 00 _default: 21497 generated, 4114 pushed, 332 nodes popped in 109
ALIGN: === word alignment begin ===
sentence1: the shower
wseq1: the shower
phseq1: sil | dh iy | sh aw ax r | sil
cmscore1: 0.552 0.698 0.453 1.000
score1: 88.964218
=== begin forced alignment ===
— word alignment —
id: from to n_score unit
—————————————-
[ 0 11] 0.558529 []
[ 12 30] 2.023606 the [the]
[ 31 106] 2.249496 shower [shower]
[ 107 108] -2.753532
[
]
re-computed AM score: 207.983871
=== end forced alignment ===

——
### read waveform input
1 files processed

音声認識をやってるっぽいのはわかるけど、Google-cloud-speechとは大分違うな

$ sudo vi mic.jconf

-input mic
-htkconf wav_config
-h ENVR-v5.3.am
-hlist ENVR-v5.3.phn
-d ENVR-v5.3.lm
-v ENVR-v5.3.dct
-b 4000
-lmp 12 -6
-lmp2 12 -6
-fallback1pass
-multipath
-iwsp
-iwcd1 max
-spmodel sp
-no_ccd
-sepnum 150
-b2 360
-n 40
-s 2000
-m 8000
-lookuprange 5
-sb 80
-forcedict

$ ../julius/julius/julius -C mic.jconf -dnnconf dnn.jconf
Notice for feature extraction (01),
*************************************************************
* Cepstral mean and variance norm. for real-time decoding: *
* initial mean loaded from file, updating per utterance. *
* static variance loaded from file, apply it constantly. *
* NOTICE: The first input may not be recognized, since *
* cepstral mean is unstable on startup. *
*************************************************************
Notice for energy computation (01),
*************************************************************
* NOTICE: Energy normalization is activated on live input: *
* maximum energy of LAST INPUT will be used for it. *
* So, the first input will not be recognized. *
*************************************************************

——
### read waveform input
Stat: adin_oss: device name = /dev/dsp (application default)
Error: adin_oss: failed to open /dev/dsp
failed to begin input stream

使い方がイマイチよくわからん
全部コマンドラインでアウトプットが出てくるんかいな

[GCP] Python3 x google-cloud-speechで音声認識を実装する

GCPでCloud Speech-to-Text APIを有効化します。

GCPユーザの認証データの*.jsonを取得します。

audio.rawはこちらからお借りします。
https://github.com/googleapis/java-speech/tree/master/samples/install-without-bom/resources

$ pip3 install google-cloud-speech

main.py

import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "hpscript.json"
from google.cloud import speech
import io

def transcribe_file(speech_file):
	
    client = speech.SpeechClient()

    with io.open(speech_file, "rb") as audio_file:
        content = audio_file.read()

    audio = speech.RecognitionAudio(content=content)
    config = speech.RecognitionConfig(
        encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        language_code="en-US",
    )
    response = client.recognize(config=config, audio=audio)

    for result in response.results:
        print(u"Transcript: {}".format(result.alternatives[0].transcript))

if __name__ == '__main__':
	transcribe_file('audio.raw')

$ python3 main.py
Transcript: how old is the Brooklyn Bridge

うーむ、なんだこれは