音频只不过是数字格式的任何类型的声音。它可以是语音、音乐、环境声音等。音频数据常用于语音识别、音乐分析、音频分类等各个领域。近年来,对于可以执行音频相关任务的训练模型来说,音频数据已成为越来越重要的数据类型。但到了一定程度之后,人耳就无法再区分两者了。
声音到底是如何录制的?为了让计算机理解我们现实世界的音频,我们需要将音频转换为数字,就像处理图像一样。麦克风用于录制音频,随后通过定期采样将模拟声音转换为数字声音。它被称为采样率。音质随着采样率的增加而提高。平均声音采样率为 48kHz 或每秒 48000 个样本。
音频数据准备和增强是涉及音频数据的机器学习工作流程中的重要步骤。以下是一些原因:
- 为了使用音频数据,它应该是可用的格式,如 WAV、MP3 和 FLAC。
- 我们的音频数据可能包含噪声或背景声音,因此数据清理对于构建有效的模型是必要的。
- 增强音频数据还可以通过为输入数据带来更多变化来帮助提高机器学习模型的泛化能力。
音频数据准备
在本文中,我们使用“ tensorflow-io” 库,它为高效且可扩展的音频数据准备和增强提供了必要的 API。步骤如下:
第 1 步:
首先,我们将安装所需的软件包并重新启动内核/运行时。
!pip install tensorflow-io
第 2 步:加载数据集
下载示例音频文件:[ www2.cs.uic.edu/~i101/Sound… ] 。
我使用的是wav格式的音频,你可以使用其他格式。接下来通过指定路径加载音频文件并使用 'tfio.audio.AudioIOTensor' 读取它,它是一个 TensorFlow Python 模块,提供了一个用于将音频文件读取到 TensorFlow Tensor 对象中的类。
# 导入必要的库
import tensorflow as tf
import tensorflow_io as tfio
# 加载和读取音频文件
audio_data = tfio.audio.AudioIOTensor('/content/CantinaBand3.wav')
print(audio_data)
print(audio_data.shape)
print(audio_data.rate)
输出:
tf.Tensor([66150 1], shape=(2,), dtype=int64)
tf.Tensor(22050, shape=(), dtype=int32)
打印 AudioIOTensor 的形状、数据类型和采样率。形状表示为 [Samples, Channels](样本=以秒为单位的音频剪辑长度 * 音频采样率),因此从上面的示例中我们的音频剪辑在 int16 和 1 个通道中有 66150 (3*22050) 个样本,这表示我们的音频为单声道。
第 3 步:音频预处理
接下来是使用 TensorFlow 进行音频预处理。当我们想要聚焦或仅使用音频剪辑的特定部分时,就会进行切片。
# 执行切片
audio_sl = audio_data[6:]
print('Shape After Slicing :',audio_sl.shape)
# 忽略最后一个维度
audio_t = tf.squeeze(audio_sl, axis=[-1])
print('Shape After squeezing:',audio_t.shape)
# 为了播放音频
from IPython.display import Audio
Audio(audio_t.numpy(), rate=audio_data.rate.numpy())
输出:
Shape After Slicing : (66144, 1)
Shape After squeezing: (66144,)
我们使用 tf.squeeze() 函数删除音频张量的最后一个维度,因为它简化了数据表示,减少了内存使用,并使音频张量与 TensorFlow 操作兼容。由于我们的音频是单声道的,因此,我们取 axis=-1,如果是立体声,即,channel=2 则 axis=1。
注意:如果您的音频数据是浮点值张量,那么您可以使用以下代码执行归一化,
# 规格化-1和1之间的音频
normalized_audio = audio_t / tf.math.reduce_max(tf.math.abs(audio_t))
在我们的示例中,我们将音频数据表示为 16 位有符号整数的张量,因此常见的归一化技术是将整数值转换为 -1 到 1 之间的浮点值。这可以通过将整数值除以来完成整数数据类型可以表示的最大值,例如 16 位有符号整数为 32767。该技术有时称为“整数归一化”或“样本归一化”。
然后我们可以使用matplotlib.pyplot库以图表的形式绘制音频数据。
# 将张量转换为float数据类型
tensor = tf.cast(audio_t, tf.float32) / 32767.0
print(tensor)
# 绘制图表
import matplotlib.pyplot as plt
plt.figure()
plt.plot(tensor.numpy())
plt.show()
输出:
tf.Tensor(
[ 9.15555283e-05 2.13629566e-04 1.52592547e-04 ... -3.66222113e-04
-1.30314035e-02 -6.92770164e-03], shape=(66144,), dtype=float32)
第 4 步:修剪
修剪是另一种预处理技术,它用于去除音频中不必要的尾随静音,或者有助于减少不必要的处理并提高准确性。 “tfio.audio.trim()” 函数提供了一种在 TensorFlow 中执行此操作的便捷方法。
Syntax: tfio.audio.trim(audio, axis, epsilon)
参数
- 音频–> 表示音频波形。
- axis–> 修剪音频所沿的轴。
- epsilon--> 表示阈值,低于该阈值的样本被视为沉默,沉默部分或阈值为零的部分被删除。
# 从音频信号的开始和结束处修剪静音
trimed = tfio.audio.trim(tensor,
axis=0,
epsilon=0.2)
print('Trimmed :',trimed)
# 提及起始和结束限制
start = trimed[0]
stop = trimed[1]
print("START:{},nSTOP :{}".format(start.numpy(),
stop.numpy()))
trimmed_audio = tensor[start:stop]
print('Trimmed Audio shape:',trimmed_audio.shape)
plt.figure()
plt.plot(trimmed_audio.numpy())
# 为了播放音频
Audio(trimmed_audio.numpy(),
rate=audio_data.rate.numpy())
输出:
Trimmed : tf.Tensor([13840 59291], shape=(2,), dtype=int64)
START:13840,
STOP :59291
Trimmed Audio shape: (45451,)
第 5 步:淡入和淡出
淡入和淡出是常见的音频增强技术,用于避免音频信号的突然转变。
要应用淡入和淡出效果,您可以使用TensorFlow 中的tfio.audio.fade函数。
Syntax: tfio.audio.fade(samples, fade_in_len, fade_out_len, mode='logarithmic', axis=-1)
参数:
- 样本 -> 包含音频样本的张量。
- fade_in_len –> 整数标量,开始时淡入的样本数。
- fade_out_len –> 整数标量,最后淡出的样本数。
- mode–> (可选)指定淡入淡出类型的字符串,“对数”或“线性”。默认值为“对数”。
- axis–> (可选)一个整数,指定要应用淡入淡出的轴。默认值为-1,即最后一个轴。
以下是如何对音频剪辑应用淡入和淡出效果的示例:
# 应用具有持续时间的淡入淡出效果
audio_fade = tfio.audio.fade(trimmed_audio,
fade_in=1000,
fade_out=2000,
mode="logarithmic")
plt.figure()
# 绘制褪色的音频
plt.plot(audio_fade.numpy())
# 播放音频
Audio(audio_fade.numpy(),
rate=audio_data.rate.numpy())
输出:
tf.Tensor([0. 0.00027118 0.00048062 ... 0.000303 0.00016269 0. ],
shape=(45451,), dtype=float32)
第 6 步:频谱图
频谱图在预处理中很有用,因为它有助于表示音频数据中存在的频率。
它主要有助于声音检测、信息检索等。我们将使用 “tfio.audio.spectrogram” 函数来完成此操作。****
“tfio.audio.spectrogram” ,以audio_tensor对象作为输入,以及参数,
nfft --> representing the number of samples to use for the fast Fourier transform (FFT),
window --> representing the size of the window used for the FFT,
the stride --> representing the distance between consecutive windows.
该函数返回一个表示音频信号频谱图的新张量。
频谱图可用于音频增强技术,例如时间掩蔽和频率掩蔽。
# 转换为声谱图
spectrogram = tfio.audio.spectrogram(audio_fade,
nfft=512,
window=512,
stride=512)
plt.figure()
#plotting spectrogram
plt.imshow(tf.math.log(spectrogram).numpy())
plt.show()
输出:
梅尔谱图
梅尔声谱图是根据人类听觉系统缩放的声谱图的一个版本。梅尔音阶是频率的非线性变换,旨在更好地反映人耳感知声音的方式。
“tfio.audio.melscale” 是一个 TensorFlow I/O (TFIO) Python 模块函数,可用于将频谱图转换为 mel 频谱图。
“tfio.audio.melscale()” 采用的参数如下:
- 频谱图 –> 形状为 [batch_size, num_frames, num_fft_bins] 的浮点张量,表示输入频谱图。输入应采用线性幅度标度。
- rate–> 表示输入音频信号采样率的整数或浮点标量。默认值为 16000。
- mels–> 表示 mel bin 数量的整数标量。默认值为 500。
- fmin– >代表频谱图最小频率的浮点标量。默认值为 0。
- fmax–> 表示频谱图最大频率的浮点标量。默认值为 8000。
“ tfio.audio.dbscale ” 是一个 TensorFlow 模块函数,可用于将频谱图或梅尔频谱图转换为相同表示的分贝缩放版本。
我们称之为 “tfio.audio.dbscale” ,
- 频谱图对象作为输入
- top_db–> 表示应在输出中表示的最大值(以分贝为单位)。任何高于此阈值的值都将被剪裁为最大值。
该函数返回一个新的张量,表示音频信号的分贝标度频谱图。
# 将光谱图转换为具有250个mel波段的mel光谱图
spectrogram_mel = tfio.audio.melscale(spectrogram, rate=16000, mels=250, fmin=0, fmax=7000)
plt.figure()
plt.imshow(tf.math.log(spectrogram_mel).numpy())
# 将频谱图转换为分贝标度,top_db=70
spectrogram_dbscale = tfio.audio.dbscale(spectrogram_mel, top_db=70)
plt.figure()
plt.imshow(spectrogram_dbscale.numpy())
plt.show()
输出:
第 7 步:频率掩蔽和时间掩蔽
频率掩蔽和时间掩蔽是用于提高音频模型的鲁棒性和泛化性的音频增强技术。它们基于随机屏蔽音频信号中的某些频带或时间步长的想法,以模拟现实世界的变化并提高模型处理噪声或不完整输入的能力。
频率掩蔽
# 应用最大掩码宽度为100个频率仓的频率掩码
spec_freq_mask = tfio.audio.freq_mask(spectrogram_dbscale, param=100)
plt.figure()
plt.imshow(spec_freq_mask.numpy())
plt.show()
输出:
时间掩蔽
# 应用最大掩码宽度为50个时间步长的时间掩码
audio_time_masked = tfio.audio.time_mask(spectrogram_dbscale,
param=50)
plt.figure()
plt.imshow(audio_time_masked.numpy())
plt.show()
输出:
tfio.audio.freq_mask() 和 tfio.audio.time_mask() 通过设置分别以随机频率和时间索引为中心的零矩形窗口,分别在输入频谱图的频率轴和时间轴上应用掩蔽。
这有助于通过改变频率和时间来提高模型的泛化性能,从而使模型更加稳健。
通过执行以下步骤,您可以在 Python 中使用 TensorFlow 预处理和增强音频数据。您可以尝试不同的数据增强技术并评估它们对音频模型性能的影响。