想的很美
- ■玩笑■
时光逆流。竟得穿越。
月夜唐朝。禅房幽径。
还是那个贾岛,那是那头驴。
难得月朦胧鸟朦胧,不由得让人诗兴大发。
“鸟宿池边树,僧推月下门。妙”
“鸟宿池边树,僧敲月下门,甚妙”
“此一推一敲,孰优孰劣?孰劣孰优?愁煞”
酸腐的书生又在斟酌词句,却不想撞上了大和尚。
“贾施主又何必自寻烦恼,且看老衲”,说罢,
那和尚取出手机,左右上下点了三下两下,缓缓念道“鸟宿池边树”
不多时,手机娓娓传来一句“鸟宿池边树,僧敲月下门”
“妙哉!”瘦岛已然五体投地。
却见那和尚合十笑道“自古文章天成,老衲今日仗这‘安卓书童’妙手偶得,惭愧惭愧”,
说罢扬长而去。
- ■缘起■
用这样穿越的开头其实只是为了营造一个跟“安卓书童”较为贴合的意境。
安卓书童是清溪近期进行安卓语音识别实践的一个副产品。
这篇文章主要想谈谈期间的种种体会。
- ■历史遗留问题■
跟密码泄露一样,很多东西都存在着历史遗留问题。
我这个语音识别的历史遗留问题大概没有范先生的那样早,大约在一年以前形成。
当时我想做一款即时会议记录应用。
在我的想象中大概是这样几个应用场景:
团队里一群人坐在一起开会,说话人的声音传递到手机上,
程序实时地做语音识别,转成文本,进而存储。
虽然识别的结果必定存在大量误差,但是即使加入了最后的人工编辑环节,我觉得还是能够大幅提高生产力。
它能够解决快速记录会议内容要点的问题。
也许上述这种场合在现实来看必要性并不是那么强,
那么再考虑一下这种情况大概会有所改观:
大礼堂,大教室,前面的发言者拿着设备侃侃而谈,
字幕就在大屏幕上汩汩流出。
它能够解决后排人员听不清的问题。
可能你还是觉得这个想法太傻逼,
那么再看看这种场景:
一群外语白坐在高新园区的咖啡厅里听白佬讲ppt,
即使老外手舞足蹈热情高涨,下面的感觉依然是鸡同鸭讲。
如果这个应用能够实时地获取发言者的文本,再传送给翻译引擎,再变换为母语文字输出,
即使机器只能翻译出傻乎乎的句子,但是在不需要绝对精准的场合,我想对于泛泛理解应该是够了。
它能够解决异语种交流问题。
- ■尝试过程■
思路基本是明确的。
所谓的语音识别,基本就是做周波数曲线匹配。
一方面要具备相关的声学知识,另一方面更重要的是要有相对完备的语料数据库。
很遗憾,这两方面我都没有。我只能站在巨人的肩膀上。
针对语音识别可选项有以下几种方案:
下面逐个谈谈体会。
⇒科大讯飞
中文识别十分精准,效果好(讯飞最早是中科大学生的创业公司,我觉得技术是过硬的)。
国内本土做语音识别的似乎是它一家独大(原谅我的孤陋寡闻如果还有更好的请给我留言)
为了减轻服务器连接压力,一个连接超过30秒会强行断开(须重复启动),好在api暂时没有调用次数的限制。
当前android的api接口还不够丰富。用它来做会议记录,需要自己在断开后重新检测语音然后开启连接。
而且,识别一次,平均起码要3秒钟甚至更多。只能自己做buffer来缓存输入的语音(很不好实现),
另外每次一断一连就有遗漏字句的可能,丢包太严重了。
另外,有时候人正在说一句话你给断开了,切句不对,识别率大打折扣。
这个还可以忍,毕竟算法的问题可以自己慢慢调教(我目前的成果基本是失败的)
最致命的是讯飞的服务器似乎非常不稳定(可能是服务器压力过大?)。
我在2g网络和WiFi网络下进行的测试。2g偶尔成功,WiFi时常失败。
2g不快是可以理解的。WiFi缓慢是值得批评的。而WiFi接入经常连接失败则是不可原谅的。
网络服务器状况导致应用极不稳定,所以现阶段用讯飞的api来做应用,个人不认为是一个好的选择。
撇掉服务器的因素,用讯飞的api有一个额外的便利之处:
将应用部署到手机上大概不需要顾虑安卓系统的版本,也不需要安装额外的插件,只需要确保网络连通(所有必须的东西都打在sdk里了)。
而谷歌的api就比较麻烦(要求你手机系统高于2.2,要求你手机安装voiceSearch。这绝对影响用户的胃口)
⇒谷歌
当然,讯飞好并不意味着谷歌差。
这篇文章介绍的对比结果跟我的经历大致相当,可以看出来并不逊色。
google的服务器稳定这是一个强项。
用谷歌的api来做会议记录同样面临上面的问题(缓存音频,队列请求发送控制),
事实上,谷歌的博客公开表示当前的api还不适合连续多句子语音识别。(到这一步我知道会议记录应用的想法暂时是不可能了)。
另外重复一下, 谷歌的api需要你系统2.2以上并且安装了voicesearch(我的乐phone是绝对没有的)
⇒Julius
当初主要想对应日本市场,所以对日文的识别技术也进行了调查。
这是由京都大学早期开发的一个项目,opensource。
暂时没有android的版本,不过linux下的支持完备。所以我想大概可以加工成so文件然后用NDK来调用(未尝试)。
如果得以改造成功,这个不需要网络连接,而且可以自己控制断句处理。应该很有魅力。
因为是开源项目,我认为每个有志于日文语音识别方向的宅男都应该好好研究一下。地址这里
btw,如果是想学习英文的语音识别,可以关注这个开源项目。SPHINX卡耐基梅隆大学牵头。最新版本已经完全用Java改写,易读。
⇒ispeech
这一家api我并没有尝试。
不过看了它的demo,在语音合成方面效果很好。
说是可以支持语音识别。具体没有研究它的sdk(移动设备版本的sdk是免费的)。
- ■为什么做了唐诗机器人?■
从实践来看,目前我还很难用这些api来实现一个像样准确的实时会议记录应用。
当前的api主要特点适合于单句的(比如发个检索关键字,发个短信),允许等待的(3-5秒视网络状况而定)语音识别。
而且说话要跟手机靠的近,稍微远一点就不辨牛马了。
于是思路转回来,想想有什么互动形的idea可以依赖这个来实现呢?
以下是我当时想到的几个场景(当然大部分都是天马行空,不切实际的):
语音计算器
类似夏天我曾经给推土机机器人开发过的命令行计算功能,只不过这次改成用嘴说。
识别数字和操作符以后,转成传统的计算处理。
它能够让你在计算时解放你的手指。
当然弊端也是显而易见,识别一旦有误,则可能酿成大错。这种东西意义不大。玩玩而已。
语音交互式读心游戏
很多年以前接触过一个网站,连续问你20个问题你只需要回答是或者不是,然后它能猜出你心中所想。
虽然原理不复杂,但是游戏讲究的是趣味性。
后来ios上的这个应用其实是一样的原理。
微软研究院的这个也是。
只不过我想改成语音的。这个要点在于后面的数据库以及Question的设计,做不来,放弃。
歇后语机器人
这个相对简单,搜集大量的歇后语存入数据库,玩家说出上半句,程序识别以后,
检索相应结果,然后取出下半句,语音合成,反馈回来。
比如,你对着手机说一句“老太太看地图”,
两三秒后,手机对你说一声“这是哪到哪啊”(配合讯飞语音合成的东北口音,应该很有趣吧?)
这个想法存在的几个问题是:
⇒歇后语的语音识别不准确,很多语句都不是常用的,对于api识别准确率有太大影响
⇒资料库的构建不容易,全国各地歇后语那么多,如果不够完全,用户试了两次没结果就会丧失兴趣了。
⇒要做的好就需要进行模糊检索,比如同一条歇后语不同地区的人说出来用词不同,程序必须有能力分词,然后计算权值来选择最匹配的结果,而不是单纯的字符串正则(这属于搜索引擎的技术了。。。)
唐诗宋词机器人
这个跟歇后语其实差别不大。但是回避了几个问题,
首先,唐诗的数据来源(唐诗三百首,全唐诗都非常容易获得),其次,各语音识别api对唐诗的识别效果都比较准(看天极网那个测试可见一斑)
当然,模糊检索的问题依旧存在。
我爱记歌词
旋律响起,突然有段歌词等你来填,匹配成功了就加分,设置花样不断挑战达到游戏效果。
这个仅仅是胡思乱想的。因为语音识别对于变调的语音(唱)好像根本不给力。
虽然有哼唱检索技术,但那是旋律,不是歌词。
很遗憾,幻想模仿《我爱记歌词》节目中那样让用户自己在手机上玩,当下还是有距离的。
调查也不是没有收获,发现这样一个网站(爱吼网),挺有意思的。
幼儿单词教育
把这个功能做到幼教软件中,出题考小朋友。
比如屏幕上出来一只熊猫,就问小朋友这是什么,
小朋友说“panda”,机器就发出一句表扬之类的,否则再鼓励。
等等。这个还是比较靠谱的,个人认为。语音交互是最符合人性的交互。
- ■语音合成怎么弄?■
说了这么多,基本就是下面这样的流程:
人发出声音⇒机器识别为文本输入⇒处理后输出文本⇒文本结果语音合成输出反馈
所以在开发中语音合成也是必不可少的。下面也简单回顾一下。
当前安卓上比较方便的以下两种手段,
同样分别详细介绍一下。
利用TTS语音包本地合成
这是比较主流的方式,也比较符合设计规范。
但是前提是用户需要提前安装语音合成包。
常用的大概目前有如下几种
⇒SVOX(多语种)
⇒Pico(似乎不支持中文)
⇒KDDI的N2(日文)
⇒讯飞(中文,不过官方说没有免费开放这个离线包,虽然民间早已流传)
⇒手说(中文,火鸟曾经就用这个,效果很差)
安装TTS的优点是coding简单,但是部署麻烦(需要用户安装并设置了相应的语种),我个人不是很喜欢(因为乐phone默认是没有的)
利用网络api远程合成后传输
说白了这种方式就是向远程服务器提交一个请求,处理之后再返回一个音频流。
对用户来说比较简单,无需多余设置(只需要网络连通),
但是coding相对复杂一些(需要建立http连接处理,然后对音频数据接收,再调用播放)
有以下几家服务:
⇒爱立信实验室的TTS API(目前只支持英文)
⇒ispeech同我上面介绍的,这家的合成效果非常好DEMO
⇒JaTTS(日文)
⇒谷歌翻译(但是官方似乎从来没有公布过这个api,所以个人认为这个是没有保证的)
泛泛的写了这么多,该memo的也都梳理了一遍。
从这段时间的体验来看有这么几个体会:
⇒不要一直用嘴去说,所谓的交流和讨论其实都很空洞,
你要是觉得可行,就去实践证明一下。若是证明了不行,再想别的主意。
掌握一个东西,理解一个东西,讨论一百次,看书一百次,也赶不上实践一次(话可能有点夸张)。
⇒想象中的东西,往往和最后的结果大相径庭。
很多时候,你想的是A,结果出来的却是B,不试不知道。
多碰撞才会有多灵感,多尝试才会有多收获。
⇒编程技术尽可能跟具体产业领域结合才好。
技术存在的意义在于解决现实问题。或改善生活体验,或提高生产力。
还是那句话,
如果技术不能解决掉什么,那要么让它进垃圾堆,要么回象牙塔。
(完)























拍砖