【吴恩达课后编程作业】Course 5 - 序列模型 - 第三周作业 - 机器翻译与触发词检测

hello,吴恩达老师深度学习的

最后一课来啦,参考博客为何宽大佬的https://blog.csdn.net/u013733326/article/details/97619187

把自己复现代码遇到的问题记录一下

问题一:在代码

 出现错误TypeError: Calling ‘.seed()’ on instances is deprecated. Use the class method ‘Faker.seed()’ instead.

解决办法:将faker版本降低到2.0.0,并重启jupyter notebook。附上pip镜像代码:

pip3 install -i https://pypi.doubanio.com/simple/ faker==2.0.0

 2.触发词检测

 

 

import numpy as np
from pydub import AudioSegment
import random
import sys
import io
import os
import glob
import IPython
import sys
sys.path.append('E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection')
from td_utils import *
%matplotlib inline

 

IPython.display.Audio("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/raw_data/activates/1.wav")

 

 

IPython.display.Audio("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/audio_examples/example_train.wav")

 

x = graph_spectrogram("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/audio_examples/example_train.wav")

结果:

 

_, data = wavfile.read("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/audio_examples/example_train.wav")
print("Time steps in audio recording before spectrogram", data[:,0].shape)
print("Time steps in input after spectrogram", x.shape)

结果:

 现在,您可以定义:

Tx = 5511 # 从频谱图输入到模型的时间步数
n_freq = 101 # 在频谱图的每个时间步输入模型的频率数

 

请注意,即使我们的默认训练示例长度为10秒,也可以将10秒的时间离散化为不同的值。你已经知道 441000(原始音频)和 5511(频谱图)。在前一种情况下,每一步代表 10 / 441000 ≈ 0.000023 10/441000 \approx 0.00002310/441000≈0.000023 秒。在第二种情况下,每个步骤代表 10 / 5511 ≈ 0.0018 10/5511 \approx 0.001810/5511≈0.0018 秒。

对于10秒的音频,您将在此作业中看到的键值为:

  • 441000 441000441000 (原始音频)
  • 5511 = T x 5511 = T_x5511=Tx​ (频谱图输出和神经网络输入的维数).
  • 10000 1000010000 (由 pydub 模块用来合成音频)
  • 1375 = T y 1375 = T_y1375=Ty​ (您将构建的GRU输出中的步骤数).

  请注意,这些表示中的每一个都恰好对应于10秒的时间。只是他们在不同程度上将它们离散化。所有这些都是超参数,可以更改(除了 441000,这是麦克风的性能)。我们选择了语音系统标准范围内的值。

  考虑上面 T y = 1375 T_y = 1375Ty​=1375 的值,这意味着对于模型的输出,我们将10秒离散化为 1375 个时间间隔(每一个长度 10 / 1375 ≈ 0.0072 10/1375 \approx 0.007210/1375≈0.0072s) 并且尝试预测每个区间是否有人最近说完 “activate” 。

  还要考虑上面的 10000 的值。这相当于将10秒剪辑离散为 10/10000 = 0.001秒间隔。0.001秒也称为1毫秒,或者1ms。因此,当我们说我们按照1ms间隔进行离散化时,这意味着我们使用了10,000步。

Ty = 1375 # 我们模型输出中的时间步数

 

2.1.3 - 生成单个训练样例

  由于语音数据难以获取和标记,您将使用正例,负例和背景的音频剪辑合成您的训练数据。录制大量10秒音频片段并且里面随机的有 “activates” 是很慢的。相反,很容易录制很多正例和负例单词,背景噪音(或者从网上免费的下载背景噪音)

要合成单个训练示例,您将:

  • 选择一个随机的10秒背景音频剪辑。
  • 随机将 0-4 段正例(“activate”)的音频剪辑插入到这个10秒音频剪辑中。
  • 随机将 0-2 段负例(不是 “activate”)的音频剪辑插入到这个10秒音频剪辑中。

  因为您已将 “activate” 一词合成到背景剪辑中,所以您确切地知道在10秒剪辑中 “activate” 出现的时间。稍后您会看到,这样也可以更容易地生成标签y 〈 t 〉 y^{\langle t \rangle}y〈t〉。

  您将使用pydub包来操纵音频。Pydub将原始音频文件转换为Pydub数据结构列表(这里不需要了解详细信息过程)。Pydub使用1ms作为离散化间隔(1ms是1毫秒= 1/1000秒),这就是为什么10秒剪辑总是用10,000步表示的原因。

 

# 使用pydub加载音频片段 
activates, negatives, backgrounds = load_raw_audio()
print("background len: " + str(len(backgrounds[0])))    # 应该是10,000,因为它是一个10秒的剪辑
print("activate[0] len: " + str(len(activates[0])))     # 也许大约1000,因为 "activate" 音频剪辑通常大约1秒(但变化很大) 
print("activate[1] len: " + str(len(activates[1])))     # 不同的 "activate" 剪辑可以具有不同的长度 

这里注意一下,如果路径没放在默认地址的话,请到

修改下路径即可。 

 

执行结果:

background len: 10000
activate[0] len: 721
activate[1] len: 731</code></span>

 

 

def get_random_time_segment(segment_ms):
    """
    获取 10,000 ms音频剪辑中时间长为 segment_ms 的随机时间段。
    
    参数:
    segment_ms -- 音频片段的持续时间,以毫秒为单位("ms" 代表 "毫秒")
    
    返回:
    segment_time -- 以ms为单位的元组(segment_start,segment_end)
    """
    
    segment_start = np.random.randint(low=0, high=10000-segment_ms)   # 确保段不会超过10秒背景 
    segment_end = segment_start + segment_ms - 1
    
    return (segment_start, segment_end)

 我跳过了一部分代码

2.1.4 - 完整的训练集

  您现在已经实现了生成单个训练示例所需的代码。我们使用此过程生成一个大型训练集。为了节省时间,我们已经生成了一组训练样例。

# 加载预处理的训练样例
X = np.load("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/XY_train/X.npy")
Y = np.load("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/XY_train/Y.npy")
  • 2.1.5 - 开发集

  为了测试我们的模型,我们记录了一个包含25个示例的开发集。虽然我们的训练数据是合成的,但我们希望使用与实际输入相同的分布来创建开发集。因此,我们录制了25个10秒钟的人们说 “activate” 和其他随机单词的音频剪辑,并用手标记。这遵循课程3中描述的原则,即我们创建的开发集应该尽可能与测试集分布相似;这就是我们的开发集使用真实音频而非合成音频的原因。

# 加载预处理开发集示例
X_dev = np.load("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/XY_dev/X_dev.npy")
Y_dev = np.load("E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/XY_dev/Y_dev.npy")

 这里何宽大佬给的文件有一部分是压缩的,解压后即可

2.2 - 模型

  现在您已经构建了一个数据集,让我们编写并训练一个触发词检测模型!

  该模型将使用1-D卷积层,GRU层和全连接层。让我们加载允许您在Keras中使用这些图层的包。
这可能需要一分钟才能加载。

from keras.callbacks import ModelCheckpoint
from keras.models import Model, load_model, Sequential
from keras.layers import Dense, Activation, Dropout, Input, Masking, TimeDistributed, LSTM, Conv1D
from keras.layers import GRU, Bidirectional, BatchNormalization, Reshape
from keras.optimizers import Adam

 

2.2.1 - 建立模型

这是我们将使用的架构。
花一些时间来查看模型,看看它是否有意义。

 

 

# GRADED FUNCTION: model

def model(input_shape):
    """
    用 Keras 创建模型的图 Function creating the model's graph in Keras.
    
    参数:
    input_shape -- 模型输入数据的维度(使用Keras约定)
    
    返回:
    model -- Keras 模型实例
    """
    
    X_input = Input(shape = input_shape)
    
    # 第一步:卷积层 (≈4 lines)
    X = Conv1D(196, 15, strides=4)(X_input)             # CONV1D
    X = BatchNormalization()(X)                         # Batch normalization 批量标准化
    X = Activation('relu')(X)                           # ReLu activation ReLu 激活
    X = Dropout(0.8)(X)                                 # dropout (use 0.8)

    # 第二步:第一个 GRU 层 (≈4 lines)
    X = GRU(units = 128, return_sequences=True)(X)      # GRU (使用128个单元并返回序列)
    X = Dropout(0.8)(X)                                 # dropout (use 0.8)
    X = BatchNormalization()(X)                         # Batch normalization 批量标准化

    # 第三步: 第二个 GRU 层  (≈4 lines)
    X = GRU(units = 128, return_sequences=True)(X)      # GRU (使用128个单元并返回序列)
    X = Dropout(0.8)(X)                                 # dropout (use 0.8)
    X = BatchNormalization()(X)                         # Batch normalization 批量标准化
    X = Dropout(0.8)(X)                                 # dropout (use 0.8)

    # 第四步: 时间分布全连接层 (≈1 line)
    X = TimeDistributed(Dense(1, activation = "sigmoid"))(X) # time distributed  (sigmoid)

    model = Model(inputs = X_input, outputs = X)
    
    return model
model = model(input_shape = (Tx, n_freq))
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 5511, 101)         0         
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 1375, 196)         297136    
_________________________________________________________________
batch_normalization_1 (Batch (None, 1375, 196)         784       
_________________________________________________________________
activation_1 (Activation)    (None, 1375, 196)         0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 1375, 196)         0         
_________________________________________________________________
gru_1 (GRU)                  (None, 1375, 128)         124800    
_________________________________________________________________
dropout_2 (Dropout)          (None, 1375, 128)         0         
_________________________________________________________________
batch_normalization_2 (Batch (None, 1375, 128)         512       
_________________________________________________________________
gru_2 (GRU)                  (None, 1375, 128)         98688     
_________________________________________________________________
dropout_3 (Dropout)          (None, 1375, 128)         0         
_________________________________________________________________
batch_normalization_3 (Batch (None, 1375, 128)         512       
_________________________________________________________________
dropout_4 (Dropout)          (None, 1375, 128)         0         
_________________________________________________________________
time_distributed_1 (TimeDist (None, 1375, 1)           129       
=================================================================
Total params: 522,561
Trainable params: 521,657
Non-trainable params: 904
____________________________

网络的输出维度是 (None, 1375, 1) 而输入是 (None, 5511, 101)。Conv1D 将步数从 5511 减少到了 1375。

2.2.2 - 训练模型

  触发字检测训练需要花费很长时间。为了节省时间,我们已经使用您在上面构建的架构在GPU上训练了大约3个小时的模型,以及大约4000个示例的大型训练集。
让我们加载模型。

 

model = load_model('E:/360MoveData/Users/Administrator/Desktop/Course 5 - 3/Trigger word detection/models/tr_model.h5')

您可以使用Adam优化器和二进制交叉熵损失进一步训练模型,如下所示。这将很快运行,因为我们仅训练迭代一次,并且是一个包含26个示例的小训练集。

opt = Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, decay=0.01)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=["accuracy"])
model.fit(X, Y, batch_size = 5, epochs=1)
Epoch 1/1
26/26 [==============================] - ETA: 19s - loss: 0.0811 - accuracy: 0.973 - ETA: 10s - loss: 0.0503 - accuracy: 0.985 - ETA: 6s - loss: 0.0495 - accuracy: 0.985 - ETA: 3s - loss: 0.0508 - accuracy: 0.98 - ETA: 0s - loss: 0.0460 - accuracy: 0.98 - 14s 542ms/step - loss: 0.0481 - accuracy: 0.9844
<keras.callbacks.callbacks.History at 0x16b7b492b70>

2.2.3 - 测试模型

最后,让我们看看您的模型在开发集上的表现。

loss, acc = model.evaluate(X_dev, Y_dev)
print("Dev set accuracy = ", acc)

 

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值