700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > How to make a Speech Machine

How to make a Speech Machine

时间:2022-10-13 02:40:39

相关推荐

How to make a Speech Machine

⚠最近在复习RNN,整理了这篇注重实践的文章!十分适合刚学习RNN的同学进行练手!

关键词:speech recognition, machine

本文主要讲坑。

*

目录

一、结语二、第一部分三、第二部分三、第三部分

一、结语

致谢!

为了从今养成写笔记的习惯!强行写文章,没话找话说!写这篇文章我吃了三盒雪糕!拼了!

项目地址:Github

二、第一部分

前一阵子,有一天,我跟我老同事跟我讨论如何学学NLP方面的。。。我们都没钻研过NLP,我甚至自己说话(打字造句)都不利索,网上搜了很多资料,甚至还研究了一波 “极限端对端——音频到音频”的一些资料。但是发现不行,有很多地方不懂,知识点架空了,回去从RNN开始补习。复习过程中翻到了一个可玩性 及!其!高!的RNN小项目,我决定先拿它来忽悠我老同事。就是Andrew Ng的deeplearning课的作业Trigger word detection - v1.ipynb,我参阅的是这个的翻译版。对于他的课我的印象是:

(ps,图片中的这个人是Michael Rosen)

如果你对这个作业十分了解,现在可以立即跳过第一部分节省你宝贵的时间!

如果不了解建议结合着本部分给出的一些坑点指南(下面我们只讲一些坑点),好好的研究一下老吴的这个作业,肯定不会让你失望。

基于这个作业盘成很多有意思的东西。下面是我发现如今在原封不动使用的时候几大(两大)坑点:

必须使用2.0以下版本的tf框架,和对应kreas,具体原因参照我的这篇批量合成训练数据的代码问题,下面详细讲解

问题代码:

# GRADED FUNCTION: insert_audio_clipdef insert_audio_clip(background, audio_clip, previous_segments):"""Insert a new audio segment over the background noise at a random time step, ensuring that the audio segment does not overlap with existing segments.Arguments:background -- a 10 second background audio recording. audio_clip -- the audio clip to be inserted/overlaid. previous_segments -- times where audio segments have already been placedReturns:new_background -- the updated background audio"""# Get the duration of the audio clip in mssegment_ms = len(audio_clip)### START CODE HERE ### # Step 1: Use one of the helper functions to pick a random time segment onto which to insert # the new audio clip. (≈ 1 line)segment_time = get_random_time_segment(segment_ms)# Step 2: Check if the new segment_time overlaps with one of the previous_segments. If so, keep # picking new segment_time at random until it doesn't overlap. (≈ 2 lines)while is_overlapping(segment_time, previous_segments):segment_time = get_random_time_segment(segment_ms)# Step 3: Add the new segment_time to the list of previous_segments (≈ 1 line)previous_segments.append(segment_time)### END CODE HERE #### Step 4: Superpose audio segment and backgroundnew_background = background.overlay(audio_clip, position = segment_time[0])return new_background, segment_time

我在使用这段代码大批量生成训练样本的时候,发现其中的这个while会死循环,程序会卡死,并且不会报任何错。(您可以拿它的代码试一下,即使使用原来的小音频,也会出现死循环)

刚开始我觉得是某些不可抗拒因素导致,毕竟我的电脑的确不稳定。但因为当时死循环出现情况少,运气好,小批量多试几次程序能顺利执行完。

但当我自己录制,并且因为懒直接每次录2s的插入音频的时候,我的程序即使一次生成一个合成样本也会卡死,于是我顺藤摸瓜找到了这。然后瞬间明白了,原因很简单,怎么讲呢,比方说我们随机插入4个2s不重叠片段到10s里,假设前面的3个都已经顺利插入了,最后一个是不是会出现找不到足够大的不重叠空间的情况,很显然前面插入片段的位置直接影响后面插入片段的插入空间!

我误打误撞放大了这个问题,才发现这段在我眼中很权威的代码也有缺陷!原带的音频文件很小,且大小不一,所以只有运气不错的情况下会碰上插不进去陷入死循环的情况!

这是一个很好的坑,您可以去试一下 ,对于音频大小不一致的情况更丰富,我可以直接写出一个算式:如果要插入片段时长>(总时长-已插入片段总时长)/(已插入片的个数+1)那么就可能造成死循环,或者说必定在某种情况下死循环,具体那种情况,你可以去写程序去试。

当然我说的这个也不一定对,错了别打我。

(ps:注意制作训练集的时候,不要理所当然的用reshape,看看形状的改变会不会影响数据本身,该转置时就转置,别问我为什么念念不忘这种小问题,不想再提…)

三、第二部分

第二部分我们讲讲模型结构和训练时候的坑。

1.先分享一个不算是坑的坑,不坑坑

如果您有仔细做老吴的作业,会发现他给的那个模型,然后.summary()看一下,会发现居然跟作业中的不一样??他这个中的256替换了原模型上的196(可能是惊喜小彩蛋吧)。

但其实并没有什么影响。而对于刚发现的小白来说可能以为是关键所在,因为此时这个小白可能使用他那个196的模型在他给的26个样本上训练了一天一夜了!没有任何训练好的迹象!这个沙雕小白就是我,我把它改成256后又给了他一天一,哦不对,我又给了它半小时,我突然又来了灵感了,发现了第一部分叮当下面ps说的那个小问题。

2.再讲一个可能是坑的坑,谜之坑

这个坑,存疑,就是对作业自带的那26个训练数据存疑,我也不记得当时我是在自己的合成训练集上还是这26个,因为我在同时盘这个模型pytorch的版本,两个模型得到了类似的训练结果(错误的结果)。我现在也懒得去再试他这个训练集了,如果出现下面这种情况:

而且你也没有在折腾数据集的时候出问题,那么这个坑可能就是那26个样本数据是乱的。

3.模型翻译的坑,一

我是指翻译成pytorch,我觉得pytorch是个不错的框架(一直吹它有可玩性,而kreas我用.fit用的不是很有快感,仿佛是在用sklern的调包侠),我在复习RNN的过程中主要就是看pytorch官方文档然后结合一些小网文啥的,比如这篇,当然在这个翻译成pytoch过程中还着重看了下GRU,好家伙这,这就是坑之所在,当我把这个GRU放进模型之后,我晕了,它的输入,batch在中间,而其它层结构是正常的,到他这必须得转置放进去,为了符合老吴网络的结构,我还要使用单独的droupt层和bn层,所以进出都得转置。然而我这个(算是)初入RNN的小白,查了官方文档后发现有一个:

batch_first – If True, then the input and output tensors are provided as (batch, seq, feature). Default: False

赶紧的,这不就解决了必须转置的问题了嘛!True之后,我又晕了,不过还好,这次让我彻底明白了RNN模块的两个输入(层级输入,隐层输入)和对应的两个输出的关系,仔细一算,完全没问题,换回false,老老实实转置(毕竟是强行翻译的kreas,我们跟它不一样,强行就得绕个弯)。

4.模型翻译的坑,二

上面说的对!上面说的对!,我们不一样,不过还是有很多人热衷于,执着于强行变成“它”的样子,其实这样也好,更容易了解框架之间的深层次的差异,以及一些不可言其状的深层次的原理!

如果我的pytorch实现是真正的纯pytoch实现,肯定不是现在这个样,现在的无非是尽最大程度的模仿老吴作业里的kreas的代码样式

比如这个层级结构之巨坑——TimeDistributed;庆幸的是这个世界上还是有跟我一样问这个问题的人,而且有动手能力强的人已经仿照实现了一个写法(我把它copy了来塞我代码里了<_<),不过看官方论坛上pytoch高手们貌似是不会问这个问题。。参考我这篇对该问题的整理

三、第三部分

1.介绍一下我的这个整合的项目里面一些有价值的点和坑

先说说一些有价值的点吧,毕竟坑是重点最后说。

语音到样本,运行脚本一条龙指导你做出来模型训练高配优化和低配优化——提供更多直观的可视化信息为高配电脑准备,还有一些特殊的训练策略为低配电脑准备(近期更新)。实时语音推理的实现另外模型结构部分我会一直改下去!不仅仅包括模型结构,等,将来会有更多模型,甚至是可自定义的(pytoch再次高度封装)的结构。

重点来了!

坑位一:对于训练样本生成的脚本,除了固定2s的关键词录入这个逆天大坑之外,录音的时候最好录paint16(默认),至于为什么你可以试试,另外魔改这块的代码建议参阅pyaudio的一些官方文档,网上搜的可能比较旧了!我期望有人帮我改一个变长录音出来,没有的话我有空自己来,因为我后面还有盘一个想好了名就叫“labelaudio”的手动标记(老吴有提到手动标记做验证集很重要!)脚本出来,所以这部分不急!坑位二:生成完训练样本之后,你就可以直接运行train.py来训练,训练里面有大坑,当你运行的时候就会发现,但一般不会,具体问题就是读模型和保存模型的时候很不人性,你最好自己再修改修改加点安全措施,直接用原代码训练半天丢了进度,你可别打我坑位三:只要你保存了参数了,就可以直接运行run.py去让程序实时预测去,这部分代码是95%我自己盘出来的,借鉴了三个重要小网文,比如这个、这个、这个,分别是多声道、回调模式、线程队列和环境音均值(而且这个老哥也是在实现这个实时语音呢,不过他的代码有问题,而且是单通道,而且它的那种队列有严重bug,必须后进先出才能做到伪实时,不信你可以试试,研究一番你就懂了。嘿嘿我之所以知道就是因为我当时想直接copy来用,最后发现copy来的也就剩那个环境音均值了),以及仔稍加研究这个队列。所以这部分坑我自信的说只有一个,就是你如果安静太久,而之前队列里“缓存”了很多的话,他可能会突然chime一下吓你一跳,当然这里可以稍微修改一下就能解决,近期我会修改,不过除此之外是没有其它问题,如果有,你可以来打我。

另外项目里含有一个widows版的ffmpeg可以直接添加了环境变量来用,当然这是为以后更多音频处理而准备的,目前只是用来读入和播放一个wav,有点鸡肋。。。

附可视化训练和推理的实机演示效果:

Figure-1--12-09-17-12-37

Figure-1--12-09-17-14-40

其它环境问题我会在GitHub上更新出。

然后,最后你以为就这些坑了吗,你会发现大批量训练的时候验证集loss上升了,却预测结果变好,像这样。

还有更多的坑等你发掘!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。