عرض على TensorFlow.org | تشغيل في Google Colab | عرض على جيثب | تحميل دفتر | انظر نموذج 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 مسبقًا باستخدام نهج نمذجة اللغة المقنعة بهدف تحديد تمثيل الكلام الكامن الكمي الحقيقي لخطوة زمنية مقنعة. يمكنك قراءة المزيد عن هدف التدريب في paper- 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
الآن ، سنقوم بتعريف مولد python لاستدعاء وظائف المعالجة المسبقة التي حددناها في الخلايا أعلاه.
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))
المسرعات (مثل GPUs / TPU) سريعة جدًا وغالبًا ما يصبح تحميل البيانات (والمعالجة المسبقة) عنق الزجاجة أثناء التدريب حيث يحدث جزء تحميل البيانات على وحدات المعالجة المركزية. يمكن أن يؤدي ذلك إلى زيادة وقت التدريب بشكل كبير خاصةً عندما يكون هناك الكثير من المعالجة المسبقة عبر الإنترنت المتضمنة أو يتم دفق البيانات عبر الإنترنت من دلاء GCS. للتعامل مع هذه القضايا، tf.data.Dataset
يقدم .prefetch(...)
الأسلوب. تساعد هذه الطريقة في إعداد الدُفعات القليلة التالية بالتوازي (على وحدات المعالجة المركزية) أثناء قيام النموذج بعمل تنبؤات (على وحدات معالجة الرسومات / وحدات المعالجة المركزية) على الدُفعة الحالية.
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
تقييم
سنقوم الآن بحساب معدل خطأ الكلمات على مجموعة بيانات التحقق
معدل خطأ كلمة (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 للمهام المتعلقة الكلام، هذا المستودع يحتوي على بعض الدروس أكثر مذهلة. في حال واجهتك أي خلل في هذه المفكرة، يرجى إنشاء قضية هنا .