baiduaip

一、百度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)
View Code

四、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下
语音识别和语音合成
原文地址:https://www.cnblogs.com/bubu99/p/11328449.html