Phần 15: Nhận diện giọng nói phần 1 – Lập trình AI bằng Python

(*1*)
Trong bài này, ta sẽ tìm hiểu thêm về nhận dạng giọng nói bằng AI với Python.
Lời nói là phương tiện giao tiếp căn bản nhất của con người khi trưởng thành. Mục tiêu căn bản của xử lý giọng nói là cung cấp sự tương tác giữa con người và máy móc.
Hệ thống xử lý giọng nói chủ yếu có ba tác vụ:
- Đầu tiên, nhận dạng giọng nói cho phép máy bắt các từ, cụm từ và câu ta nói
- Thứ 2, xử lý ngôn ngữ tự nhiên để cho phép máy hiểu những gì ta nói và
- Thứ ba, tổng hợp giọng nói để cho phép máy nói.
Bài này tập trung nhiều vào nhận dạng giọng nói, quá trình hiểu các từ mà con người nói. Hãy nhớ rằng các tín hiệu giọng nói được ghi lại cùng với sự giúp đỡ của micrô và rồi nó phải được hệ thống hiểu.
Table of Contents
1. Xây dựng hệ thống nhận dạng giọng nói :
Nhận dạng giọng nói hay Nhận dạng giọng nói tự động (ASR) là trung tâm của sự lưu ý đối với những dự án AI như robotic. Nếu như không có ASR, không thể tưởng tượng 1 robotic nhận thức tương tác với con người. Tuy nhiên, việc xây dựng 1 công cụ nhận dạng giọng nói không phải là điều hoàn toàn đơn giản.
Khó khăn ở trong việc phát triển hệ thống nhận dạng giọng nói
Phát triển 1 hệ thống nhận dạng giọng nói chất lượng cao chính là 1 bài toán khó. Khó khăn của công nghệ nhận dạng giọng nói có thể được giới thiệu chung theo những góc cạnh như được thảo luận sau đây:
- Kích thước của từ vựng: ảnh hưởng tới sự dễ dàng của việc phát triển 1 ASR.(kích thước từ vựng càng lớn thì việc nhận dạng càng khó.)
- Đặc điểm của channel – Chất lượng chanel cũng chính là 1 yếu tố quan trọng. Ví dụ, lời nói của con người có băng thông cao với dải tần đầy đủ, trong khi lời nói qua điện thoại gồm băng thông hẹp với dải tần hạn chế. Chú ý rằng nó khó hơn trong phần sau.
- Chế độ nói – Việc phát triển ASR dễ dàng cũng dựa vào chế độ nói, đó là liệu bài phát biểu có ở chế độ từ riêng biệt, hay chế độ từ được kết nối hay ở chế độ nói liên tiếp. Chú ý rằng 1 bài phát biểu liên tiếp khó nhận thấy hơn.
- Phong cách nói – Bài phát biểu được đọc có thể theo phong cách trang trọng, hay tự phát và đối thoại với phong cách bình thường. Cái sau khó nhận thấy hơn.
- Sự phụ thuộc người nói – Lời nói có thể dựa vào người nói, sự thích ứng của người nói hay độc lập với người nói. Rất khó nhất để xây dựng 1 diễn giả độc lập
- Loại tiếng ồn – Tiếng ồn là 1 yếu tố khác cần xem xét khi phát triển ASR. Tỷ lệ tín hiệu trên tiếng ồn có thể nằm trong khá nhiều phạm vi khác nhau, tùy vào môi trường âm thanh quan sát ít hơn so với rất nhiều tiếng ồn xung quanh
– Nếu như tỷ lệ tín hiệu trên nhiễu lớn hơn 30dB, nó được xem là dải cao
– Nếu như tỷ lệ tín hiệu trên nhiễu nằm trong khoảng từ 30dB tới 10db, nó được xem là SNR trung bình
– Nếu như tỷ lệ tín hiệu trên nhiễu nhỏ hơn 10 dB, nó được xem là dải tần thấp - Đặc điểm của micrô – Chất lượng của micrô có thể tốt, trung bình hay dưới trung bình. Ngoài ra, khoảng cách giữa miệng và micro cellphone có thể khác nhau. Các yếu tố này cũng cần được coi xét đối với hệ thống công nhận.
Bất chấp những khó khăn này, những nhà nghiên cứu đã làm việc nhiều trên những góc cạnh khác nhau của lời nói như hiểu tín hiệu giọng nói, người nói và xác định các trọng âm.
Bạn phải thực hiện theo những bước sau đây để tạo trình nhận dạng giọng nói
2. Hình dung tín hiệu âm thanh – Đọc từ file và làm việc:
Đây chính là bước trước tiên ở trong việc xây dựng hệ thống nhận dạng giọng nói vì nó cung cấp hiểu biết về cách 1 tín hiệu âm thanh được cấu trúc. Những bước thông dụng có thể thực hiện theo để làm việc với tín hiệu âm thanh như dưới đây:
Recording :
Đầu tiên, khi bạn cần đọc tín hiệu âm thanh từ 1 file, rồi ghi lại bằng micrô.
Sampling :
Khi ghi âm bằng micrô, các tín hiệu được lưu trữ dưới dạng số hóa. Nhưng để hoạt động, máy cần chúng ở dạng số rời rạc. Do đó, ta nên thực hiện lấy mẫu ở 1 tần số nhất định và chuyển đổi tín hiệu thành dạng số rời rạc. Việc chọn tần số cao để lấy mẫu ngụ ý rằng khi con người nghe tín hiệu, họ cảm nhận thấy nó như 1 tín hiệu âm thanh liên tiếp.
Ví dụ :
Ví dụ dưới đây cho ta thấy 1 cách tiếp cận từng bước để phân tích tín hiệu âm thanh, sử dụng Python, được lưu trong 1 file. Tần số của tín hiệu âm thanh này là 44.100 HZ.
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
Hiện tại, hãy đọc file âm thanh được lưu trữ. Nó sẽ trả về 2 giá trị: tần số lấy mẫu và tín hiệu âm thanh. Cung cấp link của file âm thanh nơi nó được lưu trữ, như được hiển thị tại đây
frequency_sampling, audio_signal = wavfile.learn("/Users/admin/audio_file.wav")
Hiển thị những thông số như tần số lấy mẫu của tín hiệu âm thanh, loại dữ liệu của tín hiệu và thời lượng của nó, sử dụng những lệnh được hiển thị:
print('nSignal form:', audio_signal.form)
print('Signal Datatype:', audio_signal.dtype)
print('Signal period:', spherical(audio_signal.form[0] /
float(frequency_sampling), 2), 'seconds')
Bước này liên quan tới việc chuẩn hóa tín hiệu như hình bên dưới đây :
audio_signal = audio_signal / np.energy(2, 15)
Trong bước này, tôi sẽ trích xuất 100 giá trị đầu tiên từ tín hiệu này để hình dung. Sử dụng những lệnh sau cho mục đích này:
audio_signal = audio_signal [:100]
time_axis = 1000 * np.arange(0, len(sign), 1) / float(frequency_sampling)
Hình dung tín hiệu bằng cách sử dụng những lệnh sau đây:
plt.plot(time_axis, sign, colour='blue')
plt.xlabel('Time (milliseconds)')
plt.ylabel('Amplitude')
plt.title('Input audio sign')
plt.present()
Bạn sẽ có thể nhận thấy đồ thị đầu ra và dữ liệu được trích xuất cho tín hiệu âm thanh bên trên như thể hiện trong hình ảnh ở đây :
Signal form: (132300,)
Signal Datatype: int16
Signal period: 3.0 seconds
3. Điểm đặc biệt cho tín hiệu âm thanh: Chuyển đổi sang dãy tần số
Điểm đặc biệt cho 1 tín hiệu âm thanh liên quan tới việc chuyển đổi tín hiệu miền thời gian thành miền tần số và hiểu các thành phần tần số của nó. Đây chính là bước quan trọng vì nó cho biết nhiều thông tin về tín hiệu. Bạn sẽ có thể sử dụng 1 công cụ toán học như Fourier Transform để thực hiện phép biến đổi này.
Ví dụ dưới đây cho ta thấy, từng bước, cách giới thiệu đặc tính của tín hiệu, sử dụng Python, được lưu trong 1 file. Chú ý rằng tại đây mình đang dùng công cụ toán học Fourier Transform để chuyển nó thành miền tần số.
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
Hiện tại, hãy đọc file âm thanh được lưu trữ. Nó sẽ trả về 2 giá trị: tần số lấy mẫu và tín hiệu âm thanh. Cung cấp link của file âm thanh nơi nó được lưu trữ như được hiển thị trong lệnh tại đây –
frequency_sampling, audio_signal = wavfile.learn("/Users/admin/pattern.wav")
Trong bước này, mình sẽ hiện ra những thông số như tần số lấy mẫu của tín hiệu âm thanh, loại dữ liệu của tín hiệu và thời lượng của nó, bằng cách sử dụng những lệnh được đưa ra phía dưới:
print('nSignal form:', audio_signal.form)
print('Signal Datatype:', audio_signal.dtype)
print('Signal period:', spherical(audio_signal.form[0] /
float(frequency_sampling), 2), 'seconds')
ta cần chuẩn hóa tín hiệu như dưới đây :
audio_signal = audio_signal / np.energy(2, 15)
Bước này liên quan tới việc trích xuất độ dài và nửa độ dài của tín hiệu :
length_signal = len(audio_signal)
half_length = np.ceil((length_signal + 1) / 2.0).astype(np.int)
Hiện tại, ta cần áp dụng những công cụ toán học để biến đổi thành miền tần số. Tại đây mình đang dùng Biến đổi Fourier.
signal_frequency = np.fft.fft(audio_signal)
thực hiện chuẩn hóa tín hiệu miền tần số và bình phương nó
signal_frequency = abs(signal_frequency[0:half_length]) / length_signal
signal_frequency **= 2
Tiếp theo, trích xuất độ dài và nửa độ dài của tín hiệu được biến đổi tần số :
len_fts = len(signal_frequency)
Chú ý rằng tín hiệu biến đổi Fourier phải được điều chỉnh cho trường hợp chẵn cũng như là lẻ.
if length_signal % 2:
signal_frequency[1:len_fts] *= 2
else:
signal_frequency[1:len_fts-1] *= 2
Hiện tại, trích xuất công suất bằng decibel (dB) –
signal_power = 10 * np.log10(signal_frequency)
Điều chỉnh tần số tính bằng kHz cho trục X –
x_axis = np.arange(0, len_half, 1) * (frequency_sampling / length_signal) / 1000.0
plt.determine()
plt.plot(x_axis, signal_power, colour='black')
plt.xlabel('Frequency (kHz)')
plt.ylabel('Signal energy (dB)')
plt.present()