Xem trên TensorFlow.org | Chạy trong Google Colab | Xem trên GitHub | Tải xuống sổ ghi chép | Xem mô hình TF Hub |
Trong máy tính xách tay này, chúng tôi sẽ được tải mô hình wav2vec2 pre-đào tạo từ TFHub và sẽ tinh chỉnh nó trên LibriSpeech bộ dữ liệu bằng cách thêm ngôn ngữ mô hình hóa đầu (LM) trên đầu của mô hình pre-đào tạo của chúng tôi. Nhiệm vụ cơ bản là xây dựng một mô hình cho Automatic Speech Recognition tức là đưa ra một số bài phát biểu, mô hình sẽ có thể ghi lại nó vào văn bản.
Đang cài đặt
Trước khi chạy máy tính xách tay này, hãy đảm bảo rằng bạn đang trên thời gian chạy GPU ( Runtime
> Change runtime type
> GPU
). Các tế bào sau sẽ cài đặt gsoc-wav2vec2
gói & phụ thuộc của nó.
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) ...
Thiết lập mô hình sử dụng TFHub
Chúng tôi sẽ bắt đầu bằng cách nhập một số thư viện / mô-đun.
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
Đầu tiên, chúng ta sẽ tải về mô hình của chúng tôi từ TFHub & sẽ quấn chữ ký mẫu của chúng tôi với hub.KerasLayer
để có thể sử dụng mô hình này giống như bất kỳ lớp Keras khác. May mắn thay, hub.KerasLayer
thể làm cả hai chỉ trong 1 dòng.
pretrained_layer = hub.KerasLayer("https://tfhub.dev/vasudevgupta7/wav2vec2/1", trainable=True)
Bạn có thể tham khảo này kịch bản trong trường hợp bạn đang quan tâm trong mô hình xuất khẩu kịch bản. Object pretrained_layer
là phiên bản đóng băng của Wav2Vec2Model
. Những trọng lượng trước-đào tạo đã được chuyển đổi từ HuggingFace PyTorch trọng Pre-đào tạo sử dụng kịch bản này .
Ban đầu, wav2vec2 được đào tạo trước với phương pháp tiếp cận mô hình ngôn ngữ bị che với mục tiêu xác định biểu diễn giọng nói tiềm ẩn được lượng tử hóa thực sự cho một bước thời gian bị che. Bạn có thể đọc thêm về mục tiêu đào tạo trong paper- wav2vec 2.0: Một khuôn khổ cho Học Tự giám sát của Cơ quan đại diện Speech .
Bây giờ, chúng ta sẽ xác định một vài hằng số và siêu tham số sẽ hữu ích trong một vài ô tiếp theo. AUDIO_MAXLEN
được cố ý thiết lập để 246000
như chữ ký mẫu chỉ chấp nhận chiều dài chuỗi tĩnh của 246000
.
AUDIO_MAXLEN = 246000
LABEL_MAXLEN = 256
BATCH_SIZE = 2
Trong các tế bào sau đây, chúng tôi sẽ quấn pretrained_layer
& một lớp dày đặc (LM đầu) với API chức năng của 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)
Các lớp dày đặc (được định nghĩa ở trên) là có một chiều đầu ra của vocab_size
như chúng ta muốn dự đoán xác suất của mỗi thẻ trong vốn từ vựng ở mỗi bước thời gian.
Thiết lập trạng thái đào tạo
Trong TensorFlow, trọng số mô hình được xây dựng chỉ khi model.call
hoặc model.build
được gọi là lần đầu tiên, vì vậy các tế bào sau đây sẽ xây dựng các mô hình trọng đối với chúng tôi. Hơn nữa, chúng tôi sẽ được chạy model.summary()
để kiểm tra tổng số các thông số khả năng huấn luyện.
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 _________________________________________________________________
Bây giờ, chúng ta cần phải xác định loss_fn
và tối ưu hóa để có thể đào tạo mô hình. Ô sau sẽ làm điều đó cho chúng ta. Chúng tôi sẽ sử dụng Adam
ưu cho đơn giản. CTCLoss
là một loại tổn thất chung được sử dụng cho các nhiệm vụ (như ASR
), nơi đầu vào tiểu phần không thể dễ dàng phù hợp với sản lượng tiểu phần. Bạn có thể đọc thêm về CTC-lỗ từ kinh ngạc này bài đăng blog .
CTCLoss
(từ gsoc-wav2vec2
gói) chấp nhận 3 đối số: config
, model_input_shape
& division_factor
. Nếu division_factor=1
, sau đó mất sẽ chỉ đơn giản là được tóm tắt, vì vậy thông qua division_factor
phù hợp để có được trung bình hàng loạt trên.
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)
Đang tải và xử lý trước dữ liệu
Hãy tải tại các tập dữ liệu LibriSpeech từ trang web chính thức và thiết lập nó.
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
Bộ dữ liệu của chúng tôi nằm trong thư mục LibriSpeech. Hãy cùng khám phá những tập tin này.
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']
Được rồi, vì vậy mỗi thư mục con có nhiều .flac
tập tin và một .txt
file. Các .txt
tập tin chứa phiên âm văn bản cho tất cả các mẫu giọng nói (tức là .flac
files) hiện diện trong đó thư mục con.
Chúng tôi có thể tải dữ liệu văn bản này như sau:
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
Tương tự như vậy, chúng ta sẽ định nghĩa một hàm cho tải một mẫu bài phát biểu từ một .flac
tập tin.
REQUIRED_SAMPLE_RATE
được thiết lập để 16000
như wav2vec2 được pre-đào tạo với 16K
tần số và nó được đề nghị để tinh chỉnh nó mà không có bất kỳ sự thay đổi lớn trong phân phối dữ liệu do tần số.
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}
Bây giờ, chúng tôi sẽ chọn một số mẫu ngẫu nhiên và sẽ cố gắng hình dung chúng.
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:
Bây giờ, chúng tôi sẽ kết hợp tất cả các mẫu lời nói & văn bản và sẽ xác định hàm (trong ô tiếp theo) cho mục đích đó.
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
Đã đến lúc xem một vài mẫu ...
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')]
Hãy xử lý trước dữ liệu ngay bây giờ !!!
Đầu tiên chúng ta sẽ xác định tokenizer & xử lý sử dụng gsoc-wav2vec2
gói. Sau đó, chúng tôi sẽ thực hiện sơ chế rất đơn giản. processor
sẽ bình thường hóa ngôn luận thô wrto khung trục và tokenizer
sẽ chuyển đổi kết quả đầu ra mô hình của chúng tôi vào chuỗi (bằng cách sử dụng từ vựng được định nghĩa) & sẽ chăm sóc của việc loại bỏ các thẻ đặc biệt (tùy thuộc vào cấu hình tokenizer của bạn).
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
Bây giờ, chúng ta sẽ xác định trình tạo python để gọi các hàm tiền xử lý mà chúng ta đã xác định trong các ô ở trên.
def inputs_generator():
for speech, text in samples:
yield preprocess_speech(speech), preprocess_text(text)
Thiết lập tf.data.Dataset
Sau di động sẽ thiết lập tf.data.Dataset
đối tượng sử dụng của nó .from_generator(...)
phương pháp. Chúng tôi sẽ sử dụng generator
đối tượng, chúng tôi xác định trong các tế bào trên.
Bạn có thể tham khảo kịch bản này để biết thêm chi tiết về làm thế nào để chuyển đổi dữ liệu LibriSpeech vào 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)
Chúng tôi sẽ chuyển tập dữ liệu thành nhiều lô, vì vậy hãy chuẩn bị các lô trong ô sau. Bây giờ, tất cả các trình tự trong một lô sẽ được đệm vào một độ dài không đổi. Chúng tôi sẽ sử dụng .padded_batch(...)
phương pháp cho mục đích đó.
dataset = dataset.padded_batch(BATCH_SIZE, padded_shapes=(AUDIO_MAXLEN, LABEL_MAXLEN), padding_values=(0.0, 0))
Các bộ tăng tốc (như GPU / TPU) rất nhanh và thường quá trình tải dữ liệu (& tiền xử lý) trở thành nút thắt cổ chai trong quá trình đào tạo vì phần tải dữ liệu xảy ra trên CPU. Điều này có thể làm tăng đáng kể thời gian đào tạo, đặc biệt khi có nhiều quá trình xử lý trước trực tuyến liên quan hoặc dữ liệu được truyền trực tuyến từ nhóm GCS. Để xử lý những vấn đề này, tf.data.Dataset
cung cấp .prefetch(...)
phương pháp. Phương pháp này giúp chuẩn bị song song một số lô tiếp theo (trên CPU) trong khi mô hình đang đưa ra dự đoán (trên GPU / TPU) trên lô hiện tại.
dataset = dataset.prefetch(tf.data.AUTOTUNE)
Kể từ khi máy tính xách tay này được thực hiện với mục đích trình diễn, chúng tôi sẽ được tham gia đầu tiên num_train_batches
và sẽ thực hiện đào tạo theo chỉ đó. Tuy nhiên, bạn được khuyến khích đào tạo trên toàn bộ tập dữ liệu. Tương tự như vậy, chúng tôi sẽ đánh giá chỉ 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)
Đào tạo người mẫu
Đối với đào tạo mô hình của chúng tôi, chúng tôi sẽ trực tiếp gọi .fit(...)
Phương pháp sau khi biên dịch mô hình của chúng tôi với .compile(...)
.
model.compile(optimizer, loss=loss_fn)
Ô trên sẽ thiết lập trạng thái đào tạo của chúng ta. Bây giờ chúng ta có thể bắt đầu tập luyện với các .fit(...)
phương pháp.
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]}
Hãy tiết kiệm mô hình của chúng tôi với .save(...)
phương pháp để có thể thực hiện kết luận sau. Bạn cũng có thể xuất SavedModel này để TFHub bằng cách làm theo tài liệu hướng dẫn 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
Đánh giá
Bây giờ chúng ta sẽ tính toán Tỷ lệ lỗi Word qua tập dữ liệu xác thực
Lời tỷ lệ lỗi (WER) là một thước đo chung để đo lường hiệu suất của một hệ thống nhận dạng giọng nói tự động. WER có nguồn gốc từ khoảng cách Levenshtein, hoạt động ở cấp độ từ. Tỷ lệ lỗi Word sau đó có thể được tính như sau: WER = (S + D + I) / N = (S + D + I) / (S + D + C) trong đó S là số lần thay thế, D là số lần xóa , I là số lần chèn, C là số từ đúng, N là số từ trong tham chiếu (N = S + D + C). Giá trị này cho biết phần trăm các từ được dự đoán không chính xác.
Bạn có thể tham khảo bài viết này để tìm hiểu thêm về WER.
Chúng tôi sẽ sử dụng load_metric(...)
chức năng từ HuggingFace bộ dữ liệu thư viện. Trước tiên hãy cài đặt các datasets
thư viện sử dụng pip
và sau đó xác định metric
đối tượng.
!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)
Đã đến lúc chạy đánh giá trên dữ liệu xác thực ngay bây giờ.
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
Chúng tôi đang sử dụng tokenizer.decode(...)
phương pháp để giải mã những dự đoán và nhãn của chúng tôi trở lại thành văn bản và sẽ thêm chúng vào các số liệu cho WER
tính toán sau này.
Bây giờ, hãy tính toán giá trị số liệu trong ô sau:
metric.compute()
1.0
Sự suy luận
Bây giờ chúng ta đang hài lòng với quá trình đào tạo & đã lưu mô hình trong save_dir
, chúng tôi sẽ xem làm thế nào mô hình này có thể được sử dụng để suy luận.
Đầu tiên, chúng ta sẽ được tải mô hình của chúng tôi sử dụng 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.
Hãy tải xuống một số mẫu bài phát biểu để thực hiện suy luận. Bạn cũng có thể thay thế mẫu sau bằng mẫu bài phát biểu của mình.
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]
Bây giờ, chúng ta sẽ đọc bài phát biểu mẫu sử dụng soundfile.read(...)
và pad nó để AUDIO_MAXLEN
để đáp ứng các chữ ký mẫu. Sau đó chúng tôi sẽ bình thường hóa mà mẫu bài phát biểu bằng cách sử dụng Wav2Vec2Processor
dụ & sẽ ăn nó vào mô hình.
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)>
Hãy số decode sao vào chuỗi văn bản bằng cách sử dụng Wav2Vec2tokenizer
dụ, chúng ta định nghĩa ở trên.
predictions = tf.argmax(outputs, axis=-1)
predictions = [tokenizer.decode(pred) for pred in predictions.numpy().tolist()]
predictions
['']
Dự đoán này khá ngẫu nhiên vì mô hình chưa bao giờ được đào tạo về dữ liệu lớn trong sổ ghi chép này (vì sổ ghi chép này không dành cho việc đào tạo hoàn chỉnh). Bạn sẽ nhận được những dự đoán tốt nếu đào tạo mô hình này trên tập dữ liệu LibriSpeech hoàn chỉnh.
Cuối cùng, chúng ta đã hoàn thành xong cuốn sổ này. Nhưng nó không phải là dấu chấm hết của việc học TensorFlow cho các nhiệm vụ bài phát biểu liên quan đến, điều này kho chứa một số hướng dẫn tuyệt vời hơn. Trong trường hợp bạn gặp phải bất kỳ lỗi trong máy tính xách tay này, hãy tạo ra một vấn đề ở đây .