音声認識 AI、OpneAI の Whisper を Fine Tuning する方法を Hugging Face のブログで公開した記事の解説で使うデータセットの作り方


https://tensorflow.classcat.com/2022/06/27/keras-2-examples-audio-transformer-asr/

のページの transformer による音声認識を、アルファベット予測ではなく、日本語の単語予測に改修して学習をさせていますが、精度があがりません。そんな中、

https://dev.classmethod.jp/articles/whisper-fine-tuning-by-huggingface/

などでのページで、OpneAI の Whisper がかなり精度が良くて Fine Tuning できるとのこと、このページの通り Common Voice のデータで train 100件、validation 100件、 test 100件で、batch_size 16 で 40steps 学習させてみたところ、test split の WER が25 から 23 になりました。次に、jsut_ver1.1 の BASIC 4500件、300件, 200件を 1epoch 学習させたところ、test データセットの WER が 25 から 19 に改善されました。
　現在は、特定の人が朝礼で喋った音声と字幕から、学習用データセットを作り、55件、5件、4件を 40 epoch 学習させて、test データセットで、wer が 35 から 21 に改善されました。この fine tuning は、特定の人の音声認識について役に立つと判断し、情報を共有するために、2番目の URL で使える学習用データセットの作り方を報告します。


　必要なファイルは、metadata.csv と wav の音声ファイルです。ディレクトリ構成は

-my_dataset 
　　　　|---- metadata.csv
　　　　|----data （ディレクトリ）
　　　　　　　　|----  onsei0001.wav
　　　　　　　　|----  onsei0002.wav
　　　　　　　　・・・
      
のような構成です。metadata.csv の中身は、

```
onsei0001,皆さんおはようございます。
onsei0002,今日は、データセットの作り方についてです。
・・・
```

のようなファイルになります。これらを jupyter notebook で

```python
from datasets import load_dataset, DatasetDict

data = DatasetDict()

data = load_dataset("audiofolder", data_dir=r".\my_dataset\data")

print( data['train']['audio'] )
```
のように、Hugging Face の load_datasets を使って、読み込みます。実行は、2番目の URL を実行した環境で行いました。これだけだと読み込んだデータに

```
[{'path': 'D:\\python-study\\transformer-tf-asr\\P\\data\\p0001.wav', 
'array': array([0., 0., 0., ..., 0., 0., 0.], dtype=float32), 
'sampling_rate': 48000}, 
{'path': 'D:\\python-study\\transformer-tf-asr\\P\\data\\p0002.wav', 
'array': array([ 0.0000000e+00, -6.1035156e-05, -6.1035156e-05, ..., 0.0000000e+00,  0.0000000e+00,  0.0000000e+00], dtype=float32), 
'sampling_rate': 48000},
 以下省略
```

 のように、sentence が読み込まれていませんので、data['train']['sentence'] を加えます。そのプログラムが

```python
from datasets import Dataset, DatasetDict

num_train = 280
num_val = 20
num_val2 = num_train + num_val

fr = open('./my_dataset/metadata.csv', "r", encoding='UTF-8')

datalist = fr.readlines()
sentence = []
for i, line1 in enumerate(datalist):
    if i != 0:
        line2 = line1.split( ',' )[1]
        sentence.append( line2 )

data1['train'] = Dataset.from_dict({"audio": data['train']['audio'][:num_train], "sentence":sentence[:num_train]})
DatasetDict( {"train":data1['train']})
data1['validation'] = Dataset.from_dict({"audio": data['train']['audio'][num_train:num_val2], "sentence":sentence[num_train:num_val2]})
DatasetDict( {"validation":data1['validation']})
data1['test'] = Dataset.from_dict({"audio": data['train']['audio'][num_val2:], "sentence":sentence[num_val2:]})
DatasetDict( {"test":data1['test']}) 


data1['train'][0]
```

です。このプログラムを実行すると、データが

```
{'audio': {'array': [0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   0.0,
   -3.0517578125e-05,
   -3.0517578125e-05,
   -3.0517578125e-05,
   -3.0517578125e-05,
   -3.0517578125e-05,
   0.0,
   0.0,
   0.0,
   0.0,
   ...],
  'path': '/paty/to/my_dataset/data/onsei0001.wav',
  'sampling_rate': 48000},
 'sentence': '皆さん、おはようございます。\n'}
```

のようになります。このデータですと、sampling rate が 48000KHz なので 16000 KHz にしなければなりませんが、そのやり方は、2番目の URL に書かれていて、これで、学習用データができたことになります。また、data1 を使えば良いので、data はメモリーから消します。

```
import gc

del data
gc.collect()
```

あとは、2番目の URL の common_voice のところを data1 に置き換えて実行してください。そうすれば、trainer の common_voice を data1 に修正して、

```python
from transformers import Seq2SeqTrainer

trainer = Seq2SeqTrainer(
    args=training_args,
    model=model,
    train_dataset=data1["train"],
    eval_dataset=data1["validation"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
    tokenizer=processor.feature_extractor,
)
```

カスタムデータセットで学習できます。この model インスタンスの使用形態として、10分程度の wav ファイルの文字起こしを考えています。model インスタンスに transcribe メソッドがないので困っています。