تنظیم دقیق Wav2Vec2 با سر LM

مشاهده در TensorFlow.org در Google Colab اجرا شود در GitHub مشاهده کنید دانلود دفترچه یادداشت مدل TF Hub را ببینید

در این نوت بوک، ما را به مدل wav2vec2 از قبل آموزش دیده از بار TFHub و آن را بر روی ریز لحن LibriSpeech مجموعه داده با اضافه سر زبان مدل سازی (LM) بیش از بالای مدل پیش آموزش دیده ما. وظیفه اساسی است که برای ساخت یک مدل برای تشخیص گفتار خودکار برخی گفتار، مدل باید قادر به آن را رونویسی به متن باشد با توجه به اینترنت اکسپلورر.

راه اندازی

قبل از اجرای این نوت بوک، لطفا اطمینان حاصل شود که شما را در زمان اجرا GPU (هستند Runtime > Change runtime type > GPU ). سلول زیر نصب خواهد شد gsoc-wav2vec2 بسته و وابستگی آن است.

pip3 install -q git+https://github.com/vasudevgupta7/gsoc-wav2vec2@main
sudo apt-get install -y libsndfile1-dev
pip3 install -q SoundFile
The following packages were automatically installed and are no longer required:
  linux-gcp-5.4-headers-5.4.0-1040 linux-gcp-5.4-headers-5.4.0-1043
  linux-gcp-5.4-headers-5.4.0-1044 linux-gcp-5.4-headers-5.4.0-1049
  linux-headers-5.4.0-1049-gcp linux-image-5.4.0-1049-gcp
  linux-modules-5.4.0-1049-gcp linux-modules-extra-5.4.0-1049-gcp
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  libflac-dev libogg-dev libvorbis-dev libvorbisfile3
The following NEW packages will be installed:
  libflac-dev libogg-dev libsndfile1-dev libvorbis-dev libvorbisfile3
0 upgraded, 5 newly installed, 0 to remove and 143 not upgraded.
Need to get 1040 kB of archives.
After this operation, 4481 kB of additional disk space will be used.
Get:1 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic/main amd64 libogg-dev amd64 1.3.2-1 [156 kB]
Get:2 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic/main amd64 libflac-dev amd64 1.3.2-1 [260 kB]
Get:3 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic/main amd64 libvorbisfile3 amd64 1.3.5-4.2 [16.0 kB]
Get:4 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic/main amd64 libvorbis-dev amd64 1.3.5-4.2 [321 kB]
Get:5 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsndfile1-dev amd64 1.0.28-4ubuntu0.18.04.2 [287 kB]
Fetched 1040 kB in 1s (1041 kB/s)
Selecting previously unselected package libogg-dev:amd64.
(Reading database ... 282211 files and directories currently installed.)
Preparing to unpack .../libogg-dev_1.3.2-1_amd64.deb ...
Unpacking libogg-dev:amd64 (1.3.2-1) ...
Selecting previously unselected package libflac-dev:amd64.
Preparing to unpack .../libflac-dev_1.3.2-1_amd64.deb ...
Unpacking libflac-dev:amd64 (1.3.2-1) ...
Selecting previously unselected package libvorbisfile3:amd64.
Preparing to unpack .../libvorbisfile3_1.3.5-4.2_amd64.deb ...
Unpacking libvorbisfile3:amd64 (1.3.5-4.2) ...
Selecting previously unselected package libvorbis-dev:amd64.
Preparing to unpack .../libvorbis-dev_1.3.5-4.2_amd64.deb ...
Unpacking libvorbis-dev:amd64 (1.3.5-4.2) ...
Selecting previously unselected package libsndfile1-dev.
Preparing to unpack .../libsndfile1-dev_1.0.28-4ubuntu0.18.04.2_amd64.deb ...
Unpacking libsndfile1-dev (1.0.28-4ubuntu0.18.04.2) ...
Setting up libvorbisfile3:amd64 (1.3.5-4.2) ...
Setting up libogg-dev:amd64 (1.3.2-1) ...
Setting up libvorbis-dev:amd64 (1.3.5-4.2) ...
Setting up libflac-dev:amd64 (1.3.2-1) ...
Setting up libsndfile1-dev (1.0.28-4ubuntu0.18.04.2) ...
Processing triggers for libc-bin (2.27-3ubuntu1.2) ...

راه اندازی مدل با استفاده از TFHub

ما با وارد کردن چند کتابخانه/ماژول شروع خواهیم کرد.

import os

import tensorflow as tf
import tensorflow_hub as hub
from wav2vec2 import Wav2Vec2Config

config = Wav2Vec2Config()

print("TF version:", tf.__version__)
TF version: 2.7.0

اول، ما مدل ما از TFHub دانلود و امضای مدل ما با بسته بندی hub.KerasLayer قادر به استفاده از این مدل مانند هر لایه دیگر Keras. خوشبختانه، hub.KerasLayer می تواند هم در فقط 1 خط است.

pretrained_layer = hub.KerasLayer("https://tfhub.dev/vasudevgupta7/wav2vec2/1", trainable=True)

شما می توانید اشاره به این اسکریپت در مورد شما در مدل صادرات اسکریپت علاقه مند است. شی pretrained_layer نسخه منجمد است Wav2Vec2Model . این وزن از پیش آموزش دیده از HuggingFace PyTorch تبدیل شد قبل از آموزش دیده وزن با استفاده از این اسکریپت .

در اصل، wav2vec2 با رویکرد مدل‌سازی زبان ماسک‌دار با هدف شناسایی نمایش گفتار پنهان کوانتیزه شده واقعی برای یک مرحله زمانی ماسک‌دار، از قبل آموزش داده شد. شما می توانید اطلاعات بیشتر در مورد هدف های آموزشی در کاغذ به عنوان خوانده شده چارچوبی برای یادگیری خود نظارت گفتار نمایندگی: wav2vec 2.0 .

اکنون، چند ثابت و فراپارامتر تعریف خواهیم کرد که در چند سلول بعدی مفید خواهند بود. AUDIO_MAXLEN عمدا به مجموعه ای از 246000 عنوان امضای مدل تنها طول توالی استاتیک می پذیرد 246000 .

AUDIO_MAXLEN = 246000
LABEL_MAXLEN = 256
BATCH_SIZE = 2

در سلول زیر، ما را بسته بندی pretrained_layer و یک لایه متراکم (سر LM) با API کاربردی Keras است .

inputs = tf.keras.Input(shape=(AUDIO_MAXLEN,))
hidden_states = pretrained_layer(inputs)
outputs = tf.keras.layers.Dense(config.vocab_size)(hidden_states)

model = tf.keras.Model(inputs=inputs, outputs=outputs)

لایه متراکم (تعریف بالا) است که با داشتن یک بعد خروجی vocab_size که ما می خواهیم برای پیش بینی احتمال هر نشانه در واژگان در هر مرحله زمان.

راه اندازی وضعیت آموزشی

در TensorFlow، وزن مدل تنها ساخته شده است که model.call یا model.build است برای اولین بار به نام، به طوری که سلول زیر وزن مدل برای ما ساخت. علاوه بر این، ما خواهد شد در حال اجرا model.summary() برای بررسی تعداد پارامترها تربیت شدنی

model(tf.random.uniform(shape=(BATCH_SIZE, AUDIO_MAXLEN)))
model.summary()
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 246000)]          0         
                                                                 
 keras_layer (KerasLayer)    (None, 768, 768)          94371712  
                                                                 
 dense (Dense)               (None, 768, 32)           24608     
                                                                 
=================================================================
Total params: 94,396,320
Trainable params: 94,396,320
Non-trainable params: 0
_________________________________________________________________

حال حاضر، ما نیاز به تعریف loss_fn و بهینه ساز قادر به آموزش مدل. سلول زیر این کار را برای ما انجام خواهد داد. ما خواهد بود با استفاده از Adam بهینه ساز برای سادگی. CTCLoss یک نوع از دست دادن مشترک است که برای انجام وظایف استفاده می شود (مانند است ASR ) که در آن ورودی فرعی قطعات نمی توان به راحتی با خروجی زیر قطعات تراز وسط قرار دارد. شما می توانید اطلاعات بیشتر در مورد CTC-از دست دادن از این شگفت انگیز به عنوان خوانده شده پست وبلاگ .

CTCLoss (از gsoc-wav2vec2 : بسته بندی) 3 پارامتر را config ، model_input_shape و division_factor . اگر division_factor=1 ، پس از آن از دست دادن سادگی خلاصه خواهد شد، بنابراین عبور division_factor بر این اساس به میانگین دسته ای بیش از.

from wav2vec2 import CTCLoss

LEARNING_RATE = 5e-5

loss_fn = CTCLoss(config, (BATCH_SIZE, AUDIO_MAXLEN), division_factor=BATCH_SIZE)
optimizer = tf.keras.optimizers.Adam(LEARNING_RATE)

بارگیری و پیش پردازش داده ها

اکنون بیایید مجموعه داده LibriSpeech از دانلود وب سایت رسمی و تنظیم آن را.

wget https://www.openslr.org/resources/12/dev-clean.tar.gz -P ./data/train/
tar -xf ./data/train/dev-clean.tar.gz -C ./data/train/
--2021-11-05 11:43:09--  https://www.openslr.org/resources/12/dev-clean.tar.gz
Resolving www.openslr.org (www.openslr.org)... 46.101.158.64
Connecting to www.openslr.org (www.openslr.org)|46.101.158.64|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 337926286 (322M) [application/x-gzip]
Saving to: ‘./data/train/dev-clean.tar.gz’

dev-clean.tar.gz    100%[===================>] 322.27M  11.6MB/s    in 31s     

2021-11-05 11:43:42 (10.3 MB/s) - ‘./data/train/dev-clean.tar.gz’ saved [337926286/337926286]
ls ./data/train/
LibriSpeech/  dev-clean.tar.gz

مجموعه داده ما در فهرست راهنمای LibriSpeech قرار دارد. بیایید این فایل ها را بررسی کنیم.

data_dir = "./data/train/LibriSpeech/dev-clean/2428/83705/"
all_files = os.listdir(data_dir)

flac_files = [f for f in all_files if f.endswith(".flac")]
txt_files = [f for f in all_files if f.endswith(".txt")]

print("Transcription files:", txt_files, "\nSound files:", flac_files)
Transcription files: ['2428-83705.trans.txt'] 
Sound files: ['2428-83705-0015.flac', '2428-83705-0004.flac', '2428-83705-0006.flac', '2428-83705-0026.flac', '2428-83705-0023.flac', '2428-83705-0001.flac', '2428-83705-0005.flac', '2428-83705-0040.flac', '2428-83705-0038.flac', '2428-83705-0042.flac', '2428-83705-0008.flac', '2428-83705-0019.flac', '2428-83705-0021.flac', '2428-83705-0002.flac', '2428-83705-0039.flac', '2428-83705-0034.flac', '2428-83705-0028.flac', '2428-83705-0000.flac', '2428-83705-0029.flac', '2428-83705-0041.flac', '2428-83705-0035.flac', '2428-83705-0032.flac', '2428-83705-0020.flac', '2428-83705-0025.flac', '2428-83705-0010.flac', '2428-83705-0014.flac', '2428-83705-0003.flac', '2428-83705-0031.flac', '2428-83705-0017.flac', '2428-83705-0027.flac', '2428-83705-0012.flac', '2428-83705-0043.flac', '2428-83705-0030.flac', '2428-83705-0022.flac', '2428-83705-0016.flac', '2428-83705-0037.flac', '2428-83705-0011.flac', '2428-83705-0036.flac', '2428-83705-0009.flac', '2428-83705-0013.flac', '2428-83705-0007.flac', '2428-83705-0018.flac', '2428-83705-0024.flac', '2428-83705-0033.flac']

خیلی خوب، پس هر یک از زیر دایرکتوری است بسیاری از .flac فایل و یک .txt فایل. .txt فایل شامل رونوشت متن را برای همه نمونه گفتار در (به عنوان مثال .flac فایل) ی موجود در زیر دایرکتوری.

ما می توانیم این داده های متنی را به صورت زیر بارگذاری کنیم:

def read_txt_file(f):
  with open(f, "r") as f:
    samples = f.read().split("\n")
    samples = {s.split()[0]: " ".join(s.split()[1:]) for s in samples if len(s.split()) > 2}
  return samples

به طور مشابه، ما یک تابع را برای بارگذاری نمونه گفتار از تعریف .flac فایل.

REQUIRED_SAMPLE_RATE تنظیم شده است 16000 به عنوان wav2vec2 قبل آموزش دیده با شد 16K فرکانس و آن را به آن ریز لحن بدون هیچ تغییر عمده ای در توزیع داده ها به دلیل فرکانس توصیه می شود.

import soundfile as sf

REQUIRED_SAMPLE_RATE = 16000

def read_flac_file(file_path):
  with open(file_path, "rb") as f:
      audio, sample_rate = sf.read(f)
  if sample_rate != REQUIRED_SAMPLE_RATE:
      raise ValueError(
          f"sample rate (={sample_rate}) of your files must be {REQUIRED_SAMPLE_RATE}"
      )
  file_id = os.path.split(file_path)[-1][:-len(".flac")]
  return {file_id: audio}

اکنون، چند نمونه تصادفی انتخاب می کنیم و سعی می کنیم آنها را تجسم کنیم.

from IPython.display import Audio
import random

file_id = random.choice([f[:-len(".flac")] for f in flac_files])
flac_file_path, txt_file_path = os.path.join(data_dir, f"{file_id}.flac"), os.path.join(data_dir, "2428-83705.trans.txt")

print("Text Transcription:", read_txt_file(txt_file_path)[file_id], "\nAudio:")
Audio(filename=flac_file_path)
Text Transcription: HE HAS GIVEN US FREE PASSES ALL THE WAY TO THE END OF OUR JOURNEY AND ALL THE WAY BACK AGAIN AND COUPONS FOR FREE BOARD AND LODGING AT THE HOTEL IT'S A WEDDING PRESENT 
Audio:

اکنون، تمام نمونه‌های گفتار و متن را ترکیب می‌کنیم و تابع (در سلول بعدی) را برای این منظور تعریف می‌کنیم.

def fetch_sound_text_mapping(data_dir):
  all_files = os.listdir(data_dir)

  flac_files = [os.path.join(data_dir, f) for f in all_files if f.endswith(".flac")]
  txt_files = [os.path.join(data_dir, f) for f in all_files if f.endswith(".txt")]

  txt_samples = {}
  for f in txt_files:
    txt_samples.update(read_txt_file(f))

  speech_samples = {}
  for f in flac_files:
    speech_samples.update(read_flac_file(f))

  assert len(txt_samples) == len(speech_samples)

  samples = [(speech_samples[file_id], txt_samples[file_id]) for file_id in speech_samples.keys() if len(speech_samples[file_id]) < AUDIO_MAXLEN]
  return samples

وقت آن رسیده که نگاهی به چند نمونه بیندازیم...

samples = fetch_sound_text_mapping(data_dir)
samples[:5]
[(array([ 6.10351562e-05,  9.15527344e-05,  9.15527344e-05, ...,
         -3.05175781e-04, -5.79833984e-04, -8.23974609e-04]),
  'WHEN SHE HEARD OF MY ENGAGEMENT WITH MARY ANN SHE WROTE AND SUGGESTED THAT WE SHOULD SPEND OUR HONEYMOON IN HER COTTAGE OR PIGSTYE AND THAT I SHOULD PAY HER RENT FOR IT'),
 (array([-0.00112915, -0.00131226, -0.00158691, ...,  0.00067139,
          0.00091553,  0.00100708]),
  "IT MIGHT JUST AS WELL BE SOME ONE ELSE'S WEDDING SO UNIMPORTANT IS THE PART WHICH I AM SET TO PLAY IN IT"),
 (array([ 3.05175781e-05, -6.10351562e-05,  2.13623047e-04, ...,
         -5.18798828e-04, -2.13623047e-04, -2.74658203e-04]),
  'THE ACCIDENT IN QUESTION OCCURRED UPON THE SUNDAY EVENING'),
 (array([ 3.05175781e-04,  3.05175781e-05, -1.83105469e-04, ...,
          7.62939453e-04,  6.10351562e-04,  5.79833984e-04]),
  "OF COURSE THERE ARE SOME PEOPLE WITH WHOM YOU CAN'T BE PERFECTLY PLAIN BUT I SHALL BE AS PLAIN AS I CAN THERE'S A WAY AND A MANNER OF DOING THAT KIND OF THING"),
 (array([ 6.10351562e-05, -3.05175781e-05,  0.00000000e+00, ...,
         -3.66210938e-04, -7.93457031e-04, -1.19018555e-03]),
  'I KNOW WHAT MAMMA CAN AFFORD TO GIVE AND I WILL SEE SHE GIVES IT')]

بیایید اکنون داده ها را از قبل پردازش کنیم !!!

ما برای اولین بار خواهد tokenizer و پردازنده با استفاده از تعریف gsoc-wav2vec2 بسته. سپس، ما یک پیش پردازش بسیار ساده را انجام خواهیم داد. processor گفتار خام عادی wrto فریم محور و tokenizer خواهد خروجی مدل ما به رشته تبدیل (با استفاده از واژگان تعریف شده) و مراقبت از حذف نشانه های ویژه (بسته به پیکربندی tokenizer خود را) را.

from wav2vec2 import Wav2Vec2Processor
tokenizer = Wav2Vec2Processor(is_tokenizer=True)
processor = Wav2Vec2Processor(is_tokenizer=False)

def preprocess_text(text):
  label = tokenizer(text)
  return tf.constant(label, dtype=tf.int32)

def preprocess_speech(audio):
  audio = tf.constant(audio, dtype=tf.float32)
  return processor(tf.transpose(audio))
Downloading `vocab.json` from https://github.com/vasudevgupta7/gsoc-wav2vec2/raw/main/data/vocab.json ... DONE

اکنون، مولد پایتون را برای فراخوانی توابع پیش پردازشی که در سلول های بالا تعریف کردیم، تعریف می کنیم.

def inputs_generator():
  for speech, text in samples:
    yield preprocess_speech(speech), preprocess_text(text)

راه اندازی tf.data.Dataset

زیر راه اندازی خواهد شد سلول tf.data.Dataset شی با استفاده از آن .from_generator(...) روش. ما خواهد بود با استفاده از generator جسم، ما در سلول بالا تعریف شده است.

شما می توانید برای اشاره این اسکریپت برای جزئیات بیشتر در مورد چگونگی تبدیل داده LibriSpeech به tfrecords.

output_signature = (
    tf.TensorSpec(shape=(None),  dtype=tf.float32),
    tf.TensorSpec(shape=(None), dtype=tf.int32),
)

dataset = tf.data.Dataset.from_generator(inputs_generator, output_signature=output_signature)
BUFFER_SIZE = len(flac_files)
SEED = 42

dataset = dataset.shuffle(BUFFER_SIZE, seed=SEED)

ما مجموعه داده را به چند دسته منتقل می کنیم، بنابراین اجازه دهید دسته ها را در سلول زیر آماده کنیم. اکنون، تمام دنباله‌های یک دسته باید به طول ثابت اضافه شوند. ما در بر استفاده خواهد کرد .padded_batch(...) روش برای این منظور.

dataset = dataset.padded_batch(BATCH_SIZE, padded_shapes=(AUDIO_MAXLEN, LABEL_MAXLEN), padding_values=(0.0, 0))

شتاب دهنده ها (مانند GPU/TPU) بسیار سریع هستند و اغلب بارگذاری داده (و پیش پردازش) در طول آموزش به گلوگاه تبدیل می شود زیرا قسمت بارگذاری داده در CPU ها اتفاق می افتد. این می تواند زمان آموزش را به طور قابل توجهی افزایش دهد، به خصوص زمانی که پیش پردازش آنلاین زیادی وجود دارد یا داده ها به صورت آنلاین از سطل های GCS پخش می شوند. که مسئولیت رسیدگی به این مسائل، tf.data.Dataset ارائه می دهد .prefetch(...) روش. این روش به آماده سازی چند دسته بعدی به صورت موازی (روی CPU) کمک می کند، در حالی که مدل در حال پیش بینی (روی GPU/TPU) روی دسته فعلی است.

dataset = dataset.prefetch(tf.data.AUTOTUNE)

از آنجا که این نوت بوک است برای اهداف نمایشی ساخته شده، ما خواهد شد در نظر گرفتن اولین num_train_batches و انجام آموزش بیش از تنها که. با این حال، شما تشویق می‌شوید که کل مجموعه داده را آموزش دهید. به طور مشابه، ما فقط ارزیابی num_val_batches .

num_train_batches = 10
num_val_batches = 4

train_dataset = dataset.take(num_train_batches)
val_dataset = dataset.skip(num_train_batches).take(num_val_batches)

آموزش مدل

برای آموزش مدل ما، ما به طور مستقیم خواهد بود خواستار .fit(...) روش بعد از کامپایل مدل ما با .compile(...) .

model.compile(optimizer, loss=loss_fn)

سلول فوق وضعیت آموزشی ما را راه اندازی می کند. حالا ما می توانیم با آموزش آغاز .fit(...) روش.

history = model.fit(train_dataset, validation_data=val_dataset, epochs=3)
history.history
Epoch 1/3
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ctc_ops.py:1447: alias_inplace_add (from tensorflow.python.ops.inplace_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Prefer tf.tensor_scatter_nd_add, which offers the same functionality with well-defined read-write semantics.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ctc_ops.py:1447: alias_inplace_add (from tensorflow.python.ops.inplace_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Prefer tf.tensor_scatter_nd_add, which offers the same functionality with well-defined read-write semantics.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ctc_ops.py:1430: alias_inplace_update (from tensorflow.python.ops.inplace_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Prefer tf.tensor_scatter_nd_update, which offers the same functionality with well-defined read-write semantics.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ctc_ops.py:1430: alias_inplace_update (from tensorflow.python.ops.inplace_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Prefer tf.tensor_scatter_nd_update, which offers the same functionality with well-defined read-write semantics.
WARNING:tensorflow:Gradients do not exist for variables ['wav2vec2/masked_spec_embed:0'] when minimizing the loss. If you're using `model.compile()`, did you forget to provide a `loss`argument?
WARNING:tensorflow:Gradients do not exist for variables ['wav2vec2/masked_spec_embed:0'] when minimizing the loss. If you're using `model.compile()`, did you forget to provide a `loss`argument?
WARNING:tensorflow:Gradients do not exist for variables ['wav2vec2/masked_spec_embed:0'] when minimizing the loss. If you're using `model.compile()`, did you forget to provide a `loss`argument?
WARNING:tensorflow:Gradients do not exist for variables ['wav2vec2/masked_spec_embed:0'] when minimizing the loss. If you're using `model.compile()`, did you forget to provide a `loss`argument?
10/10 [==============================] - 32s 2s/step - loss: 649.3215 - val_loss: 315.0721
Epoch 2/3
10/10 [==============================] - 17s 2s/step - loss: 242.1202 - val_loss: 336.5721
Epoch 3/3
10/10 [==============================] - 17s 2s/step - loss: 222.1239 - val_loss: 253.0467
{'loss': [649.321533203125, 242.1201629638672, 222.1239013671875],
 'val_loss': [315.0721435546875, 336.5721130371094, 253.0466766357422]}

بیایید صرفه جویی مدل ما با .save(...) روش قادر به انجام استنتاج بعد. شما همچنین می توانید این SavedModel به TFHub با پیروی از صادرات مستندات TFHub .

save_dir = "finetuned-wav2vec2"
model.save(save_dir, include_optimizer=False)
2021-11-05 11:44:54.280793: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:absl:Found untraced functions such as restored_function_body, restored_function_body, restored_function_body, restored_function_body, restored_function_body while saving (showing 5 of 855). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: finetuned-wav2vec2/assets
INFO:tensorflow:Assets written to: finetuned-wav2vec2/assets

ارزیابی

اکنون نرخ خطای Word را بر روی مجموعه داده اعتبارسنجی محاسبه خواهیم کرد

ورد میزان خطا (WER) متریک معمول برای اندازه گیری عملکرد یک سیستم تشخیص گفتار خودکار است. WER از فاصله Levenshtein گرفته شده است که در سطح کلمه کار می کند. سپس می‌توان میزان خطای کلمه را به صورت زیر محاسبه کرد: WER = (S + D + I) / N = (S + D + I) / (S + D + C) که در آن S تعداد جایگزین‌ها، D تعداد حذف‌ها است. ، I تعداد درج ها، C تعداد کلمات صحیح، N تعداد کلمات مرجع (N=S+D+C) است. این مقدار نشان دهنده درصد کلماتی است که به اشتباه پیش بینی شده اند.

شما می توانید برای اشاره این مقاله برای کسب اطلاعات بیشتر در مورد WER.

ما استفاده خواهد کرد load_metric(...) تابع از HuggingFace مجموعه داده کتابخانه. بیایید برای اولین بار نصب datasets کتابخانه با استفاده از pip و سپس تعیین metric شی.

!pip3 install -q datasets

from datasets import load_metric
metric = load_metric("wer")
Downloading:   0%|          | 0.00/1.95k [00:00<?, ?B/s]
@tf.function(jit_compile=True)
def eval_fwd(batch):
  logits = model(batch, training=False)
  return tf.argmax(logits, axis=-1)

اکنون زمان اجرای ارزیابی روی داده های اعتبار سنجی فرا رسیده است.

from tqdm.auto import tqdm

for speech, labels in tqdm(val_dataset, total=num_val_batches):
    predictions  = eval_fwd(speech)
    predictions = [tokenizer.decode(pred) for pred in predictions.numpy().tolist()]
    references = [tokenizer.decode(label, group_tokens=False) for label in labels.numpy().tolist()]
    metric.add_batch(references=references, predictions=predictions)
0%|          | 0/4 [00:00<?, ?it/s]
2021-11-05 11:45:11.575128: W tensorflow/compiler/tf2xla/kernels/random_ops.cc:57] Warning: Using tf.random.uniform with XLA compilation will ignore seeds; consider using tf.random.stateless_uniform instead if reproducible behavior is desired. model/keras_layer/StatefulPartitionedCall/StatefulPartitionedCall/wav2vec2/encoder/layers/0/stochastic_depth/random_uniform/RandomUniform

ما با استفاده از tokenizer.decode(...) روش برای رمزگشایی پیش بینی ها و برچسب های ما به متن پشت و آنها را به متریک برای اضافه WER محاسبات بعد.

حال، بیایید مقدار متریک را در سلول زیر محاسبه کنیم:

metric.compute()
1.0

استنتاج

حالا که ما با روند آموزش راضی و مدل در نجات داد save_dir ، خواهیم دید که چگونه این مدل می تواند برای استنتاج استفاده می شود.

اول، ما مدل ما با استفاده از بار tf.keras.models.load_model(...) .

finetuned_model = tf.keras.models.load_model(save_dir)
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.

بیایید چند نمونه گفتار را برای انجام استنتاج دانلود کنیم. می توانید نمونه زیر را با نمونه گفتار خود نیز جایگزین کنید.

wget https://github.com/vasudevgupta7/gsoc-wav2vec2/raw/main/data/SA2.wav
--2021-11-05 11:45:28--  https://github.com/vasudevgupta7/gsoc-wav2vec2/raw/main/data/SA2.wav
Resolving github.com (github.com)... 13.114.40.48
Connecting to github.com (github.com)|13.114.40.48|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/vasudevgupta7/gsoc-wav2vec2/main/data/SA2.wav [following]
--2021-11-05 11:45:28--  https://raw.githubusercontent.com/vasudevgupta7/gsoc-wav2vec2/main/data/SA2.wav
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 94252 (92K) [audio/wav]
Saving to: ‘SA2.wav’

SA2.wav             100%[===================>]  92.04K  --.-KB/s    in 0.02s   

2021-11-05 11:45:29 (5.38 MB/s) - ‘SA2.wav’ saved [94252/94252]

حال حاضر، ما نمونه گفتار با استفاده از به عنوان خوانده شده soundfile.read(...) و پد آن را به AUDIO_MAXLEN برای برآوردن امضای مدل. سپس ما که نمونه گفتار با استفاده از عادی Wav2Vec2Processor مثال و آن را به مدل غذا خواهد شد.

import numpy as np

speech, _ = sf.read("SA2.wav")
speech = np.pad(speech, (0, AUDIO_MAXLEN - len(speech)))
speech = tf.expand_dims(processor(tf.constant(speech)), 0)

outputs = finetuned_model(speech)
outputs
<tf.Tensor: shape=(1, 768, 32), dtype=float32, numpy=
array([[[ 5.5087714 , -1.0872856 , -1.0728477 , ..., -1.3125695 ,
         -0.7992846 , -0.94512135],
        [ 5.508977  , -1.0873723 , -1.0727195 , ..., -1.3125291 ,
         -0.79928476, -0.9449429 ],
        [ 5.5091047 , -1.0871643 , -1.0728203 , ..., -1.312533  ,
         -0.7992611 , -0.94483167],
        ...,
        [ 5.5094743 , -1.0874028 , -1.0729864 , ..., -1.3126655 ,
         -0.7994431 , -0.9449925 ],
        [ 5.509465  , -1.0873648 , -1.072943  , ..., -1.3126557 ,
         -0.79943836, -0.94500387],
        [ 5.509408  , -1.0872416 , -1.0728781 , ..., -1.3125473 ,
         -0.7993649 , -0.9449776 ]]], dtype=float32)>

تعداد رمزگشایی بیایید به دنباله متن با استفاده از پشت Wav2Vec2tokenizer به عنوان مثال، ما در بالا تعریف شده است.

predictions = tf.argmax(outputs, axis=-1)
predictions = [tokenizer.decode(pred) for pred in predictions.numpy().tolist()]
predictions
['']

این پیش‌بینی کاملاً تصادفی است زیرا مدل هرگز در این نوت‌بوک روی داده‌های بزرگ آموزش داده نشده است (زیرا این نوت بوک برای انجام آموزش کامل در نظر گرفته نشده است). اگر این مدل را بر روی مجموعه داده کامل LibriSpeech آموزش دهید، پیش بینی های خوبی خواهید داشت.

بالاخره به پایان این دفترچه رسیدیم. اما این پایان TensorFlow برای انجام وظایف مربوط به سخنرانی یادگیری نیست، این مخزن شامل برخی از آموزش های بیشتر شگفت انگیز. در صورتی که شما هر گونه اشکال در این نوت بوک مواجه می شوند، لطفا مشکل را در ایجاد اینجا .