import numpy as np
import librosa
import librosa.display
import os
import matplotlib.pyplot as plt
from sklearn import svm
#音声データをすべて読み込む + 音声波形を描画
#すべての声をループで読み込むコード
dir_name ='voiceset'
for file_name in sorted(os.listdir(path=dir_name)):
print("read:{}".format(file_name))
a,sr =librosa.load(os.path.join(dir_name,file_name))
print(a.shape)
librosa.display.waveplot(a,sr)
plt.show()
#グラフでは一言ずつが固まりになっているのが分かります
#前のセルをコピー&ペースト。教師用データとテスト用データとして使えるように修正
#引数のdir ネームのフォルダをすべて読み込む 特徴点と分類ラベルを返す getdata関数を作っていく
#特徴量と分類のラベル済みのラベルの組を返す
def get_data(dir_name):
#最初の2行もインデントする
#dir_name ='voiceset'(消す)
for file_name in sorted(os.listdir(path=dir_name)):
print("read:{}".format(file_name))
a,sr =librosa.load(os.path.join(dir_name,file_name))
print(a.shape)
# librosa.display.waveplot(a,sr) (消す)
# plt.show() (消す)
#get data関数を一度だけ呼び出す
get_data('voiceset')
#一度実行しコードエラーがないか確認する
#声の主の名前と数値ラベルを対応付ける辞書を作る
speakers={'kirishima':0,'suzutsuki':1,'belevskaya':2}
⑤#特徴量を取得するロジックを別の関数に切り出してコードを整理する 特徴量を返すget feat 関数を追加する
def get_feat(file_name):
a,sr =librosa.load(file_name)
return a[0,5000]
#特徴量と分類のラベル済みのラベルの組を返す
def get_data(dir):
①#特徴量としてデータX データXに対応する分類ラベルのデータYを返すように関数を修正する getdataを呼び出した際にデータXとデータYを受け取るように修正
data_X=
data_y=
for file_name in sorted(os.listdir(path=dir_name)):
print("read:{}".format(file_name))
a,sr =librosa.load(os.path.join(dir_name,file_name))
print(a.shape)
③#データXとデータyに具体的な値を追加していく
speaker=file_name[0:file_name.index('_')]
④#これらをSVMに与えて学習させるには同じ数になるように揃えなければいけない 先頭から5000個の数を特徴量として引き出す
data_X.append(a[0:5000])
data_y.append*1
②#getdataの中ではデータXとYを組みにして返すように記述する
return(np.array(data_X),np.array(data_y))
data_X,data_y = get_data('voiceset')
#各ファイルの音声の要素数が出力 各再生時間が違うのでaの要素数も異なっている これらをSVMに与えて学習させるには同じ数になるように揃えなければいけない 先頭から5000個の数を特徴量として引き出す
#消したりしたのでコピーペーストしてここに別に記載 しかし動画中では上記の同じセルで消して実行していた
speakers={'kirishima':0,'suzutsuki':1,'belevskaya':2}
⑤#特徴量を取得するロジックを別の関数に切り出してコードを整理する 特徴量を返すget feat 関数を追加する
def get_feat(file_name):
a,sr =librosa.load(file_name)
return a[0,5000]
#特徴量と分類のラベル済みのラベルの組を返す
def get_data(dir):
①#特徴量としてデータX データXに対応する分類ラベルのデータYを返すように関数を修正する getdataを呼び出した際にデータXとデータYを受け取るように修正
data_X=
data_y=
for file_name in sorted(os.listdir(path=dir_name)):
print("read:{}".format(file_name))
speaker=file_name[0:file_name.index('_')]
data_X.append(get_feat(os.path.join(dir_name,file_name)))
data_y.append*2
return(np.array(data_X),np.array(data_y))
data_X,data_y = get_data('voiceset')
print("===== data_X =====")
print(data_X.shape)
print(data_X)
print("===== data_y =====")
print(data_y.shape)
print(data_y)
#data_x には48個の音声の特徴量。
#data_yには分類ラベルとファイル名のペアが48個入っている
#教師データとテストデータに分ける
train_X,test_X,train_y,test_y =train_test_split(data_X,data_y,random_state=11813)
print("{}->{},{}".format(len(data_X),(len(train_X).len(test_X)))
#36個の教師データと12個のテストデータに分けれた
#教師データをSVMに与え学習させる
clf= svm.SVC(gamma=0.0001,C=1)
clf.fit(train_X,train_y.T[0])
#T[0] train_yの情報だけをsvmに与えている
#学習が終わったので1つ分類する
clf.predict(np.array([test_X[0]]))
#test_X の0番目の要素について 分類結果が2になった
#すべてのテストデータの分類も行う
ok_count=0
for X,y in zip(test_X,test_y):
actual = clf.predict(np.array([X]))[0]
expected =y[0]
file_name =y[1]
ok_count += 1 if actual == expected else 0
reseult= 'o' if actual == expected else 'x'
print("{ }file :{ }, actual:{ }, expected:{ }".format(result,file_name,actual,expected))
print("{}/{}".format(ok_count,len(test_X)))
#正答率が 12個中5つだけなので性能が悪い 予測結果がすべて2になっているのでほとんどまともに予測できていない
#ganmma値を0.01に変更
#2ばかりだったのが0が少し増えている 1に分類されるものはなかった
#なぜ上手く分類できないのか
#今回使用した特徴量は 時系列順の音声の振幅の並び 同じ順番の振幅同士を比較してしまうためタイミングが少しずれるだけでも結果が変わる
#音声は音波を時系列と振動幅をサンプリングしデータ化したものになる 様々な周波数が混ざっている
#音声認識ではそれぞれ特徴があるので音声の特徴をそれぞれ認識させる必要がある
今回のチャプターも内容が濃いかったです 演習内容は相変わらず簡単です
コードをブログに記載しながら学習しているのでいい勉強になっているなとは思います
知らない単語等まだ調べていないので後日コツコツ調べていきたいと思います