baidu-aip
一、百度AI入手
预备资料:
1.FFmpeg:
链接:https://pan.baidu.com/s/1jonSAa_TG2XuaJEy3iTmHg
密码:w6hk
2.baidu-aip:
pip install baidu-aip
终于进入主题了,此篇是人工智能应用的重点,只用现成的技术不做底层算法,也是让初级程序员快速进入人工智能行业的捷径
目前市面上主流的AI技术提供公司有很多,比如百度,阿里,腾讯,主做语音的科大讯飞,做只能问答的图灵机器人等等
这些公司投入了很大一部分财力物力人力将底层封装,提供应用接口给我们,尤其是百度,完全免费的接口
开启人工智能技术的大门 : http://ai.baidu.com/ 封装好的接口如下:
首先进入控制台,注册一个百度的账号(百度账号通用)
开通一下我们百度AI开放平台的授权,然后找到已开通服务中的百度语音。
打开百度语音,进入语音应用管理界面,创建一个新的应用
创建语音应用App
就可以创建应用了,回到应用列表我们可以看到已创建的应用了
这里面有三个值 AppID , API Key , Secret Key 记住可以从这里面看到。
1.安装百度的人工智能SDK:
pip install baidu-aip
安装完成之后就来测试一下:
在工程目录下,就可以看到 s1.mp3 这个文件了,来听一听
上面咱们测试了一个语音合成的例子,那么就从语音合成开始入手
2.语音合成:
baidu-aip Python SDK 语音合成技术文档 : https://ai.baidu.com/docs#/TTS-Online-Python-SDK/top
这是与百度进行一次加密校验 , 认证你是合法用户 合法的应用
AipSpeech 是百度语音的客户端 认证成功之后,客户端将被开启,这里的client 就是已经开启的百度语音的客户端了
用百度语音客户端中的synthesis方法,并提供相关参数
成功可以得到音频文件,失败则返回一段错误信息
重点看一下 synthesis 这个方法 , 从 https://ai.baidu.com/docs#/TTS-Online-Python-SDK/top 来获得答案吧
从参数入手分析:
按照这些参数,从新发起一个语音合成
这次声音是不是与一点点萝莉了呢?
这都是语音语调的作用 0 - 9 其实就是 御姐音 - 萝莉音
这就是人工智能中的语音合成技术.
3.语音识别:
声音这个东西格式太多样化了,如果要想让百度的SDK识别咱们的音频文件,就要想办法转变成百度SDK可以识别的格式PCM
目前DragonFire已知可以实现自动化转换格式并且屡试不爽的工具 : FFmpeg 这个工具的下载地址是 : 链接:https://pan.baidu.com/s/1jonSAa_TG2XuaJEy3iTmHg 密码:w6hk
FFmpeg 环境变量配置:
首先你要解压缩,然后找到bin目录,我的目录是 C:\ffmpeg\bin
然后 以 windows 10 为例,配置环境变量
尝试一下,是否配置成功
看到这个界面就算配置成功了,配置成功有什么用呢, 这个工具可以将wav wma mp3 等音频文件转换为 pcm 无压缩音频文件
做一个测试,首先要打开windows的录音机,录制一段音频(说普通话)
现在假设录制的音频文件的名字为 audio.wav 放置在 D:\DragonFireAudio\
然后我们用命令行对这个 audio.wav 进行pcm格式的转换然后得到 audio.pcm
命令是 : ffmpeg -y -i audio.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 audio.pcm
然后打开目录就可以看到pcm文件了
pcm文件已经得到了,赶紧进入正题吧
百度语音识别SDK的应用:
前提是你的audio.pcm 要与你当前的文件在同一个目录,还是分段看一下代码
读取文件的内容,file_context 是 audio.pcm 文件打开的二进制流
asr函数需要四个参数,第四个参数可以忽略,自有默认值,参照一下这些参数是做什么的
第一个参数: speech 音频文件流 建立包含语音内容的Buffer对象, 语音文件的格式,pcm 或者 wav 或者 amr。(虽说支持这么多格式,但是只有pcm的支持是最好的)
第二个参数: format 文件的格式,包括pcm(不压缩)、wav、amr (虽说支持这么多格式,但是只有pcm的支持是最好的)
第三个参数: rate 音频文件采样率 如果使用刚刚的FFmpeg的命令转换的,你的pcm文件就是16000
第四个参数: dev_pid 音频文件语言id 默认1537(普通话 输入法模型)
再来看下一段代码,打印返回结果:
成功的dict中 result 就是我们要的识别文本
失败的dict中 err_no 就是我们要的错误编码,错误编码代表什么呢?
如果err_no不是0的话,就参照一下错误码表.
二、PyAudio 实现录音 自动化交互实现问答
Python 很强大其原因就是因为它庞大的三方库 , 资源是非常的丰富 , 当然也不会缺少关于音频的库
关于音频, PyAudio 这个库, 可以实现开启麦克风录音, 可以播放音频文件等等,此刻我们不去了解其他的功能,只了解一下它如何实现录音的
首先要先 pip 一个 PyAudio
pip install pyaudio
1.PyAudio 实现麦克风录音
然后建立一个py文件,复制如下代码
import pyaudio import wave CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 16000 RECORD_SECONDS = 2 WAVE_OUTPUT_FILENAME = "Oldboy.wav" p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("开始录音,请说话......") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("录音结束,请闭嘴!") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close()
尝试一下,在目录中出现了一个 Oldboy.wav 文件 , 听一听,还是很清晰的嘛
接下来,我们将这段录音代码,写在一个函数里面,如果要录音的话就调用
建立一个文件 pyrec.py 并将录音代码和函数写在内
# pyrec.py 文件内容 import pyaudio import wave CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 16000 RECORD_SECONDS = 2 def rec(file_name): p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("开始录音,请说话......") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("录音结束,请闭嘴!") stream.stop_stream() stream.close() p.terminate() wf = wave.open(file_name, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close()
rec 函数就是我们调用的录音函数,并且给他一个文件名,他就会自动将声音写入到文件中了
2.实现音频格式自动转换 并 调用语音识别
录音的问题解决了,赶快和百度语音识别接在一起使用一下:
不管你的录音有多么多么清晰,你发现百度给你返回的永远是:
{'err_msg': 'speech quality error.', 'err_no': 3301, 'sn': '6397933501529645284'} # 音质不清晰
其实不是没听清,而是百度支持的音频格式PCM搞的鬼
所以,我们要将录制的wav音频文件转换为pcm文件
写一个文件 wav2pcm.py 这个文件里面的函数是专门为我们转换wav文件的
使用 os 模块中的 os.system()方法 这个方法是执行系统命令用的, 在windows系统中的命令就是 cmd 里面写的东西,dir , cd 这类的命令
# wav2pcm.py 文件内容 import os def wav_to_pcm(wav_file): # 假设 wav_file = "音频文件.wav" # wav_file.split(".") 得到["音频文件","wav"] 拿出第一个结果"音频文件" 与 ".pcm" 拼接 等到结果 "音频文件.pcm" pcm_file = "%s.pcm" %(wav_file.split(".")[0]) # 就是此前我们在cmd窗口中输入命令,这里面就是在让Python帮我们在cmd中执行命令 os.system("ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s"%(wav_file,pcm_file)) return pcm_file
这样我们就有了把wav转为pcm的函数了 , 再重新构建一次咱们的代码
这次的返回结果还挺让人满意的嘛
{'corpus_no': '6569869134617218414', 'err_msg': 'success.', 'err_no': 0, 'result': ['老男孩教育'], 'sn': '8116162981529666859'}
拿到语音识别的字符串了,接下来用这段字符串 语音合成, 学习咱们说出来的话
3.语音合成 与 FFmpeg 播放mp3 文件
拿到字符串了,直接调用synthesis方法去合成吧
这段代码衔接上一段代码,成功获得了 synth.mp3 音频文件,并且确定了实在学习我们说的话
接下来就是让我们的程序自动将 synth.mp3 音频文件播放了 其实PyAudio 有播放的功能,但是操作有点复杂
所以我们还是选择用简单的方式解决复杂的问题,就是这么简单粗暴,是否还记得FFmpeg 呢?
FFmpeg 这个系统工具中,有一个 ffplay 的工具用来打开并播放音频文件的,使用方法大概是: ffplay 音频文件.mp3
建立一个playmp3.py文件, 写一个 play_mp3 的函数用来播放已经合成的语音
# playmp3.py 文件内容 import os def play_mp3(file_name): os.system("ffplay %s"%(file_name))
回到主文件,调用playmp3.py文件中的 play_mp3 函数
执行代码,当你看到 : 开始录音,请说话......
请大声的说出: 学IT 找老男孩教育
然后你就会听到,一个声音重复你说的话
4.简单问答
首先我们要把代码重新梳理一下:
把语音合成 语音识别部分的代码独立成函数放到baidu_ai.py文件中
# baidu_ai.py 文件内容 from aip import AipSpeech # 这里的三个参数,对应在百度语音创建的应用中的三个参数 APP_ID = "xxxxx" API_KEY = "xxxxxxx" SECRET_KEY = "xxxxxxxx" client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) def audio_to_text(pcm_file): # 读取文件 , 终于得到了PCM文件 with open(pcm_file, 'rb') as fp: file_context = fp.read() # 识别本地文件 res = client.asr(file_context, 'pcm', 16000, { 'dev_pid': 1536, }) # 从字典里面获取"result"的value 列表中第1个元素,就是识别出来的字符串"老男孩教育" res_str = res.get("result")[0] return res_str def text_to_audio(res_str): synth_file = "synth.mp3" synth_context = client.synthesis(res_str, "zh", 1, { "vol": 5, "spd": 4, "pit": 9, "per": 4 }) with open(synth_file, "wb") as f: f.write(synth_context) return synth_file
然后把我们的主文件进行一下修改
import pyrec # 录音函数文件 import wav2pcm # wav转换pcm 函数文件 import baidu_ai # 语音合成函数,语音识别函数 文件 import playmp3 # 播放mp3 函数 文件 pyrec.rec("1.wav") # 录音并生成wav文件,使用方式传入文件名 pcm_file = wav2pcm.wav_to_pcm("1.wav") # 将wav文件 转换成pcm文件 返回 pcm的文件名 res_str = baidu_ai.audio_to_text(pcm_file) # 将转换后的pcm音频文件识别成 文字 res_str synth_file = baidu_ai.text_to_audio(res_str) # 将res_str 字符串 合成语音 返回文件名 synth_file playmp3.play_mp3(synth_file) # 播放 synth_file
res_str 是字符串,如果字符串等于"你叫什么名字"的时候,我们就要给他一个回答:我的名字叫老男孩教育
新建一个FAQ.py的文件然后建立一个函数faq:
# FAQ.py 文件内容 def faq(Q): if Q == "你叫什么名字": # 问题 return "我的名字是老男孩教育" # 答案
return "我不知道你在说什么" #问题没有答案时返
在主文件中导入这个函数,并将语音识别后的字符串传入函数中
现在来尝试一下:"你叫什么名字","你今年几岁了"
成功了,现在你可以对 FAQ.py 这个文件进行更多的问题匹配了
三、jieba gensim 最好别分家之最简单的相似度实现
简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能中的另一项技术:
自然语言处理(NLP) : 大概意思就是 让计算机明白一句话要表达的意思,NLP就相当于计算机在思考你说的话,让计算机知道"你是谁","你叫啥","你叫什么名字"是一个意思
这就要做 : 语义相似度
接下来我们用Python来实现一个简单的自然语言处理
现在又要用到Python强大的三方库了
1、第一个是将中文字符串进行分词的库叫 jieba
pip install jieba
我们通常把这个库叫做 结巴分词 确实是结巴分词,而且这个词库是 made in china , 基本用一下这个结巴分词:
import jieba key_word = "你叫什么名字" # 定义一句话,基于这句话进行分词 cut_word = jieba.cut(key_word) # 使用结巴分词中的cut方法对"你叫什么名字" 进行分词 print(cut_word) # <generator object Tokenizer.cut at 0x03676390> 不懂生成器的话,就忽略这里 cut_word_list = list(cut_word) # 如果不明白生成器的话,这里要记得把生成器对象做成列表 print(cut_word_list) # ['你', '叫', '什么', '名字'] text1 = "今天天气很不错" text2 = "太上皇打天下,到一半儿,挂了" text3 = "先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也" # res = list(jieba.cut(text)) res = list(jieba.cut_for_search(text1)) # 用这个 res2 = list(jieba.cut_for_search(text2)) res3 = list(jieba.cut_for_search(text3)) # res = list(jieba.lcut_for_search(text)) print(res,res2,res3)
测试代码就很明显了,它很清晰的把咱们的中文字符串转为列表存储起来了
pip3 install pypinyin from pypinyin import lazy_pinyin,TONE2,TONE,TONE3 a = "蓓蓓,贝贝" res = lazy_pinyin(a,style=TONE2) print("".join(res))
2、第二个是一个语言训练库叫 gensim
pip install gensim
这个训练库很厉害, 里面封装很多机器学习的算法, 是目前人工智能的主流应用库,这个不是很好理解, 需要一定的Python数据处理的功底
import jieba from gensim import corpora from gensim import models from gensim import similarities # from gensim.models import tfidfmodel,lsimodel l1 = ["你的名字是什么", "你今年几岁了", "你有多高你胸多大", "你胸多大"] a = "你今年多大了" all_doc_list = [] for doc in l1: doc_list = [word for word in jieba.cut_for_search(doc)] all_doc_list.append(doc_list) print(all_doc_list) #[['你', '的', '名字', '是', '什么'], ['你', '今年', '几岁', '了'], ['你', '有', '多', '高', '你', '胸多大'], ['你', '胸多大']] doc_test_list = [word for word in jieba.cut_for_search(a)] #[你 今年 多 大 了] # 制作语料库 dictionary = corpora.Dictionary(all_doc_list) # 制作词袋 # 14230 1675 1,9,8,11,1,10 [(1,2),(9,1),(8,1),(11,1)(10,1)] # 1685 # 词袋的理解 # 词袋就是将很多很多的词,进行排列形成一个 词(key) 与一个 标志位(value) 的字典 # 例如: {'什么': 0, '你': 1, '名字': 2, '是': 3, '的': 4, '了': 5, '今年': 6, '几岁': 7, '多': 8, '有': 9, '胸多大': 10, '高': 11} # 至于它是做什么用的,带着问题往下看 print("token2id", dictionary.token2id) print("dictionary", dictionary, type(dictionary)) corpus = [dictionary.doc2bow(doc) for doc in all_doc_list] # [[(1,1),(4,1),(2,1),(3,1),(0,1)],[(),(),()]] = dictionary.doc2bow(doc) # 14230 1675 # 1685 # 语料库: # 这里是将all_doc_list 中的每一个列表中的词语 与 dictionary 中的Key进行匹配 # 得到一个匹配后的结果,例如['你', '今年', '几岁', '了'] # 就可以得到 [(1, 1), (5, 1), (6, 1), (7, 1)] # 1代表的的是 你 1代表出现一次, 5代表的是 了 1代表出现了一次, 以此类推 6 = 今年 , 7 = 几岁 print("corpus", corpus, type(corpus)) # 将需要寻找相似度的分词列表 做成 语料库 doc_test_vec doc_test_vec = dictionary.doc2bow(doc_test_list) #[(1,1),(6,1)] print("doc_test_vec", doc_test_vec, type(doc_test_vec)) # 3 x 1 5 # 3 x 10 + 3 x 5 # 3X5 + 3X5 + 3X5 # 将corpus语料库(初识语料库) 使用Lsi模型进行训练 lsi = models.LsiModel(corpus) # 向量 # [(5*5),(6*8),(9*3),(5*6)] (4*4) # 这里的只是需要学习Lsi模型来了解的,这里不做阐述 print("lsi", lsi, type(lsi)) # 语料库corpus的训练结果 print("lsi[corpus]", lsi[corpus]) # 获得语料库doc_test_vec 在 语料库corpus的训练结果 中的 向量表示 print("lsi[doc_test_vec]", lsi[doc_test_vec]) # 文本相似度 # 稀疏矩阵相似度 将 主 语料库corpus的训练结果 作为初始值 index = similarities.SparseMatrixSimilarity(lsi[corpus], num_features=len(dictionary.keys())) # 我是一个标准 正矩形 边长+-1 # [(5*5),(6*8),(9*3),(5*6)] (4*4) = (5*5) = 1 print("index", index, type(index)) # 将 语料库doc_test_vec 在 语料库corpus的训练结果 中的 向量表示 与 语料库corpus的 向量表示 做矩阵相似度计算 sim = index[lsi[doc_test_vec]] print("sim", sim, type(sim)) # 对下标和相似度结果进行一个排序,拿出相似度最高的结果 # cc = sorted(enumerate(sim), key=lambda item: item[1],reverse=True) cc = sorted(enumerate(sim), key=lambda item: -item[1]) print(cc) text = l1[cc[0][0]] print(a,text)
四、others
# pip install baidu-aip from aip import AipSpeech #创建百度AI语音客户端 """ 你的 APPID AK SK """ APP_ID = '16979868' API_KEY = '1OyheYgoQY2LNnqnMfq9gDvv' SECRET_KEY = 'DLuM0hMQqGozLbI4ose7fpCRTk14eXlH' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) # ##############################语音合成 result = client.synthesis('你好','zh',1,{ 'vol':5, }) print(result) #识别正确返回语音二进制,错误则返回dict 参照下面错误码 if not isinstance(result,dict): with open('audio.mp3','wb') as f: f.write(result) ##############################语音识别 # 读取文件 import os def get_file_content(filePath): os.system(f"ffmpeg -y -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm") with open(f"{filePath}.pcm", 'rb') as fp: return fp.read() # 识别本地文件 res = client.asr(get_file_content('audio.mp3'), 'pcm', 16000, { 'dev_pid': 1537, }) print(res) """ // 成功返回 { "err_no": 0, "err_msg": "success.", "corpus_no": "15984125203285346378", "sn": "481D633F-73BA-726F-49EF-8659ACCC2F3D", "result": ["北京天气"] } // 失败返回 { "err_no": 2000, "err_msg": "data empty.", "sn": null } """ #### ffmpeg.org 转换音频视频格式(添加环境变量) (格式工厂) #### ffmpeg -y -i 16k.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm
#!/usr/bin/env python # -*- coding: utf-8 -*- from aip import AipSpeech #创建百度AI语音客户端 """ 你的 APPID AK SK """ APP_ID = '16979868' API_KEY = '1OyheYgoQY2LNnqnMfq9gDvv' SECRET_KEY = 'DLuM0hMQqGozLbI4ose7fpCRTk14eXlH' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) #自然语言处理() from aip import AipNlp nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY) """ 调用短文本相似度 """ res_nlp = nlp_client.simnet('你的名字是什么', '你丫谁呀') print(res_nlp)
# !/usr/bin/env python # -*- coding: utf-8 -*- # 图灵机器人 www.tuling123.com/ import requests dic = { "reqType": 0, "perception": { "inputText": { "text": "你叫什么名字" }, }, "userInfo": { "apiKey": "5ceb5670c0b743caa6510da14b7a0707", "userId": "123456789" } } def go_tuling(q): dic['perception']['inputText']['text'] = q res = requests.post("http://openapi.tuling123.com/openapi/api/v2", json=dic) res_dic = res.json() return res_dic.get("results")[0]["values"]["text"]
from aip import AipSpeech #创建百度AI语音客户端 """ 你的 APPID AK SK """ APP_ID = '16979868' API_KEY = '1OyheYgoQY2LNnqnMfq9gDvv' SECRET_KEY = 'DLuM0hMQqGozLbI4ose7fpCRTk14eXlH' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) ##############################语音识别 #开取语音识别 # 读取文件 import os def get_file_content(filePath): os.system(f"ffmpeg -y -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm") with open(f"{filePath}.pcm", 'rb') as fp: return fp.read() # 识别本地文件 res = client.asr(get_file_content('audio.mp3'), 'pcm', 16000, { 'dev_pid': 1537, }) #自然语言处理() from aip import AipNlp nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY) """ 调用短文本相似度 """ # res_nlp = nlp_client.simnet('你的名字是什么', '你丫谁呀') # print(res_nlp) #58% 以上的相似度就算高的 #{'log_id': 957434345924889161, 'texts': {'text_2': '你丫谁呀', 'text_1': '你的名字是什么'}, 'score': 0.71901} def my_nlp_func(text): # if "你叫什么名字" in text: #你的名字是什么? 你丫谁呀? 您贵姓? what's your name? # # NLP 自然语言处理的问题 # return "我叫孙悟空" if nlp_client.simnet("你叫什么名字",text).get("score") >=0.58: return "我叫孙悟空" # return "我没听清楚,你能在说一遍么?" ########### import reqs return reqs.go_tuling(text) ########### answer = my_nlp_func(res.get("result")[0]) # ##############################语音合成 result = client.synthesis(answer,'zh',1,{ 'vol':5, }) print(result) #识别正确返回语音二进制,错误则返回dict 参照下面错误码 if not isinstance(result,dict): with open('answer.mp3','wb') as f: f.write(result) #自动播放音频 # os.system("ffplay answer.mp3") #linux和mac下 os.system("answer.mp3") #window下