Рубрики
Без рубрики

Распознавание голоса с Tensorflow

Хотя я обычно человек JavaScript, есть много вещей, которые Python облегчает. Обращение с распознаванием голоса с помощью машинного обучения является одним из тех вещей. Теги с Python, Tensorflow, MachineLearning.

Голосовое распознавание – сложная проблема по ряду отраслей. Зная некоторые основы вокруг обработки аудиоданных и о том, как классифицировать образцы звука – это хорошо, чтобы в вашем набор инструментов для данных науки.

Мы собираемся пройти пример классификации некоторых звуковых клипов, используя Tensorflow Отказ К тому времени, когда вы проходите через это, вы найдете достаточно, чтобы иметь возможность создать собственные модели распознавания голоса. С дополнительными исследованиями вы можете взять эти концепции и применить их на более крупные, более сложные аудиофайлы.

Вы можете найти полный код в этом Github repo Отказ

Получать данные

Сбор данных является одной из сложных проблем в науке о данных. Есть так много данных, но не все легко использовать в проблемах обучения машин. Вы должны убедиться, что данные чистые, помечены и завершены.

Чтобы сделать наш пример, мы собираемся использовать некоторые Аудио файлы, выпущенные Google Отказ

Во-первых, мы создадим новый Проводной трубопровод Отказ Именно здесь вы сможете построить, поезжать и проверить свою модель и поделиться ссылкой с кем-либо заинтересованным.

###
# Main Pipeline
###
def main() -> co.Serial:
    path = "/conducto/data/pipeline"
    root = co.Serial(image = get_image())

    # Get data from keras for testing and training
    root["Get Data"] = co.Exec(run_whole_thing, f"{path}/raw")

    return root

Тогда нам нужно начать писать run_whole_thing функция.

def run_whole_thing(out_dir):
    os.makedirs(out_dir, exist_ok=True)
    # Set seed for experiment reproducibility
    seed = 55
    tf.random.set_seed(seed)
    np.random.seed(seed)
    data_dir = pathlib.Path("data/mini_speech_commands")

Далее нам нужно настроить каталог для удержания аудиофайлов. Это все еще внутри run_whole_thing функция.

if not data_dir.exists():
    # Get the files from external source and put them in an accessible directory
    tf.keras.utils.get_file(
        'mini_speech_commands.zip', 
 origin="http://storage.googleapis.com/download.tensorflow.org/data/mini_speech_commands.zip",
        extract=True)

Предварительная обработка данных

Теперь, когда у нас есть наши данные в правильном каталоге, мы можем разделить его на наборы набора обучения, тестирования и валидации.

Во-первых, нам нужно написать несколько функций, чтобы помочь предварительно обработать данные, чтобы она будет работать в нашей модели.

Нам нужны данные в формате, который наш алгоритм может понять. Мы будем использовать сверточную нейронную сеть, поэтому данные должны быть преобразованы в изображения. Эта первая функция преобразует двоичный аудиофайл в тензор.

# Convert the binary audio file to a tensor
def decode_audio(audio_binary):
    audio, _ = tf.audio.decode_wav(audio_binary)

    return tf.squeeze(audio, axis=-1)

Поскольку у нас есть тензор, который мы можем работать с тем, что имеет необработанные данные, нам нужно получить этикетки, чтобы соответствовать их. Это то, что делает следующая функция, получая метку для аудиофайла из пути файла.

# Get the label (yes, no, up, down, etc) for an audio file.
def get_label(file_path):
    parts = tf.strings.split(file_path, os.path.sep)

    return parts[-2]

Далее нам нужно связать аудиофайлы с правильными метками. Мы делаем это и возвращая кортеж, с которым можно работать Tensorflow.

# Create a tuple that has the labeled audio files
def get_waveform_and_label(file_path):
    label = get_label(file_path)
    audio_binary = tf.io.read_file(file_path)
    waveform = decode_audio(audio_binary)

    return waveform, label

Мы кратко упомянули с использованием алгоритма сверточной нейронной сети (CNN) ранее. Это один из способов справиться с моделью распознавания голоса, как это. Как правило, CNNS очень хорошо работает на данных изображения и поможет снизить время предварительного обработки.

Мы собираемся воспользоваться этим путем преобразования наших аудиофайлов в спектрограммы. Спектрограмма представляет собой изображение спектра частот. Если вы посмотрите на аудиофайл, вы увидите, что это просто частотные данные. Таким образом, мы собираемся написать функцию, которая преобразует наши аудиоданные в изображения.

# Convert audio files to images
def get_spectrogram(waveform):
    # Padding for files with less than 16000 samples
    zero_padding = tf.zeros([16000] - tf.shape(waveform), dtype=tf.float32)
    # Concatenate audio with padding so that all audio clips will be of the same length
    waveform = tf.cast(waveform, tf.float32)
    equal_length = tf.concat([waveform, zero_padding], 0)
    spectrogram = tf.signal.stft(
        equal_length, frame_length=255, frame_step=128)
    spectrogram = tf.abs(spectrogram)

    return spectrogram

Теперь, когда мы отформатировали наши данные как изображения, нам нужно применить правильные этикетки на эти изображения. Это похоже на то, что мы сделали для исходных аудиофайлов.

# Label the images created from the audio files and return a tuple
def get_spectrogram_and_label_id(audio, label):
    spectrogram = get_spectrogram(audio)
    spectrogram = tf.expand_dims(spectrogram, -1)
    label_id = tf.argmax(label == commands)

    return spectrogram, label_id

Последняя функция помощника, которая нам нужна, это тот, который будет обрабатывать все вышеперечисленные операции для любого набора аудиофайлов, которые мы его передаем.

# Preprocess any audio files
def preprocess_dataset(files, autotune, commands):
    # Creates the dataset
    files_ds = tf.data.Dataset.from_tensor_slices(files)

    # Matches audio files with correct labels
    output_ds = files_ds.map(get_waveform_and_label,
                             num_parallel_calls=autotune)
    # Matches audio file images to the correct labels
    output_ds = output_ds.map(
        get_spectrogram_and_label_id,  
        num_parallel_calls=autotune)

    return output_ds

Теперь, когда у нас есть все эти функции помощника, мы получаем разделить данные.

Разделение данных в наборы данных

Преобразование аудиофайлов на изображения помогает сделать данные проще обработать с CNN, и именно поэтому мы написали все эти функции помощника. Мы сделаем пару вещей, чтобы сделать разделение данных проще.

Во-первых, мы получим список всех потенциальных команд для аудиофайлов, которые мы будем использовать в нескольких других местах в коде.

# Get all of the commands for the audio files
commands = np.array(tf.io.gfile.listdir(str(data_dir)))
commands = commands[commands != 'README.md']

Затем мы получим список всех файлов в каталоге данных и перемешайте их, чтобы мы могли назначить случайные значения каждому из насаждений, которые нам нужны.

# Get a list of all the files in the directory
filenames = tf.io.gfile.glob(str(data_dir) + '/*/*')

# Shuffle the file names so that random bunches can be used as the training, testing, and validation sets
filenames = tf.random.shuffle(filenames)

# Create the list of files for training data
train_files = filenames[:6400]

# Create the list of files for validation data
validation_files = filenames[6400: 6400 + 800]

# Create the list of files for test data
test_files = filenames[-800:]

Теперь у нас есть наша обучение, проверка и тестовые файлы, четко разделенные, поэтому мы можем предварительно обрабатывать эти файлы, чтобы получить их готовы к созданию и тестированию нашей модели. Мы используем Автонада Здесь, чтобы настроить значение наших параметров динамически во время выполнения.

autotune = tf.data.AUTOTUNE

Этот первый пример – просто показать, как работает предварительная обработка, и это дает нам spectrogram_ds Значение, которое нам нужно немного.

# Get the converted audio files for training the model
files_ds = tf.data.Dataset.from_tensor_slices(train_files)
    waveform_ds = files_ds.map(
    get_waveform_and_label, num_parallel_calls=autotune)
spectrogram_ds = waveform_ds.map(
    get_spectrogram_and_label_id, num_parallel_calls=autotune)

Поскольку вы видели то, что он хотелось пройти через шаги предварительного обработки, мы можем продолжать и использовать функцию помощника для обработки этого для всех наборов данных.

# Preprocess the training, test, and validation datasets
train_ds = preprocess_dataset(train_files, autotune, commands)
validation_ds = preprocess_dataset(
   validation_files, autotune, commands)
test_ds = preprocess_dataset(test_files, autotune, commands)

Мы хотим установить ряд учебных примеров, которые работают в каждой итерации эпохи, поэтому мы установим размер партии.

# Batch datasets for training and validation
batch_size = 64
train_ds = train_ds.batch(batch_size)
validation_ds = validation_ds.batch(batch_size)

Наконец, мы можем уменьшить сумму задержки в обучении нашей модели, используя кэширование.

# Reduce latency while training
train_ds = train_ds.cache().prefetch(autotune)
validation_ds = validation_ds.cache().prefetch(autotune)

Наши наборы данных, наконец, в форме, с которой мы можем тренировать модель.

Создание модели

Поскольку наши накидки четко определены, мы можем идти вперед и построить модель. Мы будем использовать CNN, чтобы создать нашу модель, поэтому нам нужно будет получить форму данных, чтобы получить правильную форму для наших слоев. Затем мы идем вперед построить модель последовательно.

# Build model
for spectrogram, _ in spectrogram_ds.take(1):
    input_shape = spectrogram.shape

num_labels = len(commands)

norm_layer = preprocessing.Normalization()
norm_layer.adapt(spectrogram_ds.map(lambda x, _: x))

model = models.Sequential([
    layers.Input(shape=input_shape),
    preprocessing.Resizing(32, 32),
    norm_layer,
    layers.Conv2D(32, 3, activation='relu'),
    layers.Conv2D(64, 3, activation='relu'),
    layers.MaxPooling2D(),
    layers.Dropout(0.25),
    layers.Flatten(),
    layers.Dense(128, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(num_labels),
])

model.summary()

Мы делаем некоторую конфигурацию на модели, чтобы она давала нам наилучшую точность.

# Configure built model with losses and metrics
model.compile(
    optimizer=tf.keras.optimizers.Adam(),
    loss=tf.keras.losses.SparseCategoricalCrossentropy(
        from_logits=True),
    metrics=['accuracy'],
)

Модель построена, так что теперь все, что осталось, это тренируется.

Обучение модели

После того, как вся работа предварительно обработала данные и построение модели, тренировка относительно проста. Мы определяем, сколько эпохи мы хотим работать с нашими наборами тренировки и валидации.

# Finally train the model and return info about each epoch
EPOCHS = 10
model.fit(
    train_ds,
    validation_data=validation_ds,
    epochs=EPOCHS,
    callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2),
)

Вот и все! Модель была обучена, и теперь нам просто нужно проверить ее.

Тестирование модели

Теперь, когда у нас есть модель с примерно 83% точности, пришло время мы тестируем, насколько хорошо он выполняет новые данные. Поэтому мы берем наш тестовый набор данных и разделите аудиофайлы с этикеток.

# Test the model
test_audio = []
test_labels = []

for audio, label in test_ds:
   test_audio.append(audio.numpy())
   test_labels.append(label.numpy())

test_audio = np.array(test_audio)
test_labels = np.array(test_labels)

Затем мы принимаем аудиоданные и используем его в нашей модели, чтобы увидеть, предсказывает ли он правильный ярлык.

# See how accurate the model is when making predictions on the test dataset
y_pred = np.argmax(model.predict(test_audio), axis=1)
y_true = test_labels

test_acc = sum(y_pred == y_true) / len(y_true)

print(f'Test set accuracy: {test_acc:.0%}')

Закончив трубопровод

Есть просто крошечный бит кода, который вам понадобится закончить свой трубопровод и сделать его делом с кем угодно. Это определяет изображение, которое будет использоваться в этом проводном конвейере.

###
# Pipeline Helper functions
###
def get_image():
    return co.Image(
        "python:3.8-slim",
        copy_dir=".",
        reqs_py=["conducto", "tensorflow", "keras"],
    )

if __name__ == "__main__":
    co.main(default=main)

Теперь вы можете запустить Python Pipelure.py --локал В вашем терминале, и он должен раскрутить ссылку на новый проводной трубопровод. Если у вас нет аккаунта, вы можете сделать один бесплатно здесь Отказ

Заключение

Это один из способов решить проблему обработки звука, но это может быть гораздо более сложным в зависимости от того, какие данные вы пытаетесь проанализировать. Создание его в трубопроводе позволяет легко поделиться с коллегами и получать помощь или обратная связь, если вы столкнетесь с ошибками.

Оригинал: “https://dev.to/flippedcoding/voice-recognition-with-tensorflow-2k0c”