人工智能--語音入門篇

前戲

1、 知識儲備

1.函數 : def args kwargs

def func(參數1,參數2):  # def 用來定義函數及函數名,參數1和參數2就是定義時的形參,也就是未來調用函數時必需要傳入的參數
    變量1 = 參數1+參數2
    return 變量1
# *args 就是 將未定義且多餘的 位置參數記錄在內,偷偷的告訴你,args是個元祖,裏面記錄着你個函數傳遞的多餘位置參數
 
 # **kwargs 就是 將多餘的關鍵字參數記錄在內,kwargs 實際上是個dict哦,裏面大概就是{"name":"python","age":1+1+1+1+1+1+18}
 def args_func(a,b,*args):  # args 裏面保存着除了ab以外的全部多餘參數
     print(args) # 這回知道是元組了吧
     for i in args:
         print(i)
 
 args_func(1,2,3,4,5,6)  # 這裏調用的時候1,2分別傳遞給a,b,那麼3456就會保存在args裏面哦
 def kwargs_func(a, b, **kwargs):  # kwargs 裏面保存着除了ab以外其餘關鍵字傳入參的參數
     print(kwargs)  # 這回知道是字典了吧
     for k, v in kwargs:
         print(k, v)
 
 kwargs_func(1, 2, c=3, d=4, e=5)  # 這裏調用的時候,12分別傳遞給a,b 那麼c=3,d=4,e=5 就會保存在**kwargs裏面哦
 def args_kwargs_func(*args, **kwargs):  # 這裏必定要注意*args 要在 **kwargs以前
     print(args)
     print(kwargs)
 

 args_kwargs_func(1, 2, a=1, b=2)  # 12存入args a=1,b=2 存入kwargs,這裏要注意的是關鍵字傳參以後,不能夠在位置傳參了

2.推導式

兩個栗子:python

2.1 列表推導式: mysql

li = [i for i in range(10)]  # 簡單的列表推導式,就是在列表內寫一個for循環對吧
 print(li)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 
 lis = [i for i in range(10) if i % 2 == 0]  # 這是帶if 條件的列表推導式
 print(lis)  # [0, 2, 4, 6, 8

2.2 生成器推導式:程序員

gener = (i for i in range(10))  # 簡單的生成器推導式,就是在元組內寫一個for循環對吧
 print(gener)  # <generator object <genexpr> at 0x04F9B3C0>
 
 geners = (i for i in range(10) if i % 2 == 0)  # 這是帶if 條件的生成器推導式
 print(geners)  # <generator object <genexpr> at 0x04F9B3F0>

從上述來看,列表推導式和生成器推導式只是[] 與 () 的區別算法

可是實際上,生成器推導式的效率很是高,但可控性不好,好比不直觀,用一次就沒了sql

相對而言列表推導式的效率比較低,可是可控性強,能夠反覆利用,並且數據顯示很直觀shell

3.模塊

字符串之json模塊json

 import json
 
 # 咱們作一個字典
 dic = {
     "name": "Dragon",
     "age": 20,
     "hobby": ["摩托車", "騎車"],
     "other": {
         "say": "hello",
         "see": "beautiful girl",
     }
 }
 json_dic = json.dumps(dic)  # json序列化
 
 print(type(json_dic), json_dic)
 
 # <class 'str'> {"name": "Dragon", "age": 20, "hobby": ["\u6469\u6258\u8f66", "\u9a91\u8f66"], "other": {"say": "hello", "see": "beautiful girl"}}
 
 loads_dic = json.loads(json_dic) # json 反序列化
 
 print(type(loads_dic), loads_dic)
 
 # <class 'dict'> {'name': 'Dragon', 'age': 20, 'hobby': ['摩托車', '騎車'], 'other': {'say': 'hello', 'see': 'beautiful girl'}}

os模塊,集成了不少操做系統的方法,好比建立文件夾,拼接路徑,刪除文件,建立文件等等flask

import os
os.path.join("a","b") # 組合路徑 a/b
os.system("ls") # 執行系統命令
os.sep() # 獲取當前操做系統的路徑分隔符 
os.path.dirname(__file__) # 獲取當前文件的所在目錄

 os補充:vim

import os

os.getcwd()  # 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname")  # 改變當前腳本工做目錄;至關於shell下cd
os.curdir()  # 返回當前目錄: ('.')
os.pardir()  # 獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dir1/dir2')  # 可生成多層遞歸目錄
os.removedirs('dirname1')  # 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')  # 生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')  # 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')  # 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove("file_name")  # 刪除一個文件
os.rename("oldname", "new")  # 重命名文件/目錄
os.stat('path/filename')  # 獲取文件/目錄信息
os.sep()  # 操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep()  # 當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep()  # 用於分割文件路徑的字符串
os.name()  # 字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  # 運行shell命令,直接顯示
os.environ()  # 獲取系統環境變量
os.path.abspath(path)  # 返回path規範化的絕對路徑
os.path.split(path)  # 將path分割成目錄和文件名二元組返回
os.path.dirname(path)  # 返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  # 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  # 若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path)  # 若是path是絕對路徑,返回True
os.path.isfile(path)  # 若是path是一個存在的文件,返回True。不然返回False
os.path.isdir(path)  # 若是path是一個存在的目錄,則返回True。不然返回False
os.path.join(path1[, path2[, ...]])  # 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  # 返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  # 返回path所指向的文件或者目錄的最後修改時間

4.文件操做

f = open("123.txt","rb") #打開文件句柄
print(f.read()) # 讀取文件內容
f.close() # 關閉文件句柄

打開文件時,須要指定文件路徑和以何等方式打開文件,打開後,便可獲取該文件句柄,往後經過此文件句柄對該文件操做。windows

打開文件的模式有:

  • r ,只讀模式【默認】
  • w,只寫模式【不可讀;不存在則建立;存在則清空內容;】
  • x, 只寫模式【不可讀;不存在則建立,存在則報錯】
  • a, 追加模式【可讀;   不存在則建立;存在則只追加內容;】

"+" 表示能夠同時讀寫某個文件

  • r+, 讀寫【可讀,可寫】
  • w+,寫讀【可讀,可寫】
  • x+ ,寫讀【可讀,可寫】
  • a+, 寫讀【可讀,可寫】

 "b"表示以字節的方式操做

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

 注:以b方式打開時,讀取到的內容是字節類型,寫入時也須要提供字節類型

 

# 文件上下文操做
with open("123.txt","rb") as f: # 文件句柄f 自動打開關閉文件句柄
    f.read() # 讀取文件內容(所有)
    

with open("123.txt","rb") as f:
    f.read() #讀取文件內容(所有)
    f.readline() # 讀取文件中一行文件
    f.readlines() # 讀取文件中全部行 ["1","2"]
    
    f.write("666") # 寫入文件內容
    f.writelines("666") # 寫入一行文件
    
    f.flush()# 刷新文件
    f.seek(10) # 移動光標到10位置
    f.truncate(6) # 從光標當前位置截取6位
    f.tell() # 獲取當前光標位置

 

人工智能底層的擇取

預備環境:



1.FFmpeg:

連接:https://pan.baidu.com/s/1jonSAa_TG2XuaJEy3iTmHg

密碼:w6hk



2.baidu-aip:

pip install baidu-aip

 

此篇是人工智能應用的重點,只用現成的技術不作底層算法,也是讓初級程序員快速進入人工智能行業的捷徑

目前失眠上主流的AI技術提供公司有不少,BAT和只能問答的圖靈機器人等,另外提一點:主作語音的科大訊飛是佼佼者但它是有償使用

這裏咱們採用百度的徹底免費接口

開啓人工智能技術的大門 : http://ai.baidu.com/

 

 

首先進入控制檯,註冊一個百度的帳號(百度帳號通用)

開通一下咱們百度AI開放平臺的受權

而後找到已開通服務中的百度語音

這裏省去自行建立應用過程

 進入管理應用,牢記下述3個值,後面實例接口時會用上

 

 

2、 百度的人工智能SDK:

1.安裝SDK與測試

 首先我們要 pip install baidu-aip 安裝一個百度人工智能開放平臺的Python SDK實在是太方便了,這也是爲何咱們選擇百度人工智能的最大緣由

在工程目錄下,就能夠看到s1.mp3這個文件了,可用播放器試聽效果

上面我們測試了一個語音合成的例子,那麼就從語音合成開始入手

2.語音合成

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/08/25 18:28
# @Author  : MJay_Lee
# @File    : ai.py
# @Contact : limengjiejj@hotmail.com

from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '11721488'
API_KEY = 'RSs9MrcwhhdndG6vLHN9Q9dC'
SECRET_KEY = 'RpQwPMiPUYXYNOFb0bmFIHORNj4t6Nb0'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

res = client.synthesis(
    "智能語音的第一個示例", # text,合成的文本,使用UTF-8編碼,請注意文本長度必須小於1024字節
    "zh", # lang,語言,中文:zh 英文:en
    1, # ctp,客戶端信息這裏就寫1
    { # 這是一個dict類型的參數,裏面的kv是關鍵,以下:
        "vol":5, # 合成音頻文件的準音量
        "spd":4, # 語速,0~9,默認爲5,中語速
        "pit":8, # 語調音調,0~9,默認爲5,中語調
        "per":4, # 發音人選擇,0爲女聲,1爲1男聲,3爲度逍遙,4爲度丫丫,默認爲普通女聲
    }
)

if not isinstance(res,dict):
    with open("audio.mp3","wb")as f:
        f.write(res)
else:
    print(res)
'''
# 錯誤返回示例:
{
    'err_detail': 'Params error.',
    'err_msg': 'parameter error.',
    'err_no': 501,
    'err_subcode': 29,
    'tts_logid': 3204603220
}
'''
完整示例

技術上,代碼上的任何疑慮均可以從官方文檔中獲得答案

baidu-aip Python SDK 語音合成技術文檔 : https://ai.baidu.com/docs#/TTS-Online-Python-SDK/top

剛纔咱們作了一個語音合成的例子,藉此可繼續展開說明

這裏與百度進行一次加密校驗,認證你是合法用戶,合法的應用

AipSpeech 是百度語音的客戶端,認證成功以後,客戶端都將被開啓,這裏的client就是已經開啓的百度語音的客戶端

res就是我們音頻文件的byte流

若是失敗,res就會是個字典,如上圖的 #錯誤返回示例。

 

用百度語音客戶端中的synthesis方法,並提供相關參數

成功能夠獲得音頻文件,失敗則返回一段錯誤信息

重點看一下 synthesis 這個方法 , 從 https://ai.baidu.com/docs#/TTS-Online-Python-SDK/top 來得到答案吧

從參數入手分析:

至此,人工只能中的語音合成技術點到爲止了。

3.語音識別

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/08/25 18:28
# @Author  : MJay_Lee
# @File    : ai.py
# @Contact : limengjiejj@hotmail.com

from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '11721488'
API_KEY = 'RSs9MrcwhhdndG6vLHN9Q9dC'
SECRET_KEY = 'RpQwPMiPUYXYNOFb0bmFIHORNj4t6Nb0'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 讀取文件
def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()


# 識別本地文件
res = client.asr(get_file_content('audio.pcm'), 'pcm', 16000, {
    'dev_pid': 1536,
})


print(res)
'''
# res內容
{
    'corpus_no': '6594294686519761176',
    'err_msg': 'success.',
    'err_no': 0,
    'result': ['陳杰陳杰你好'],
    'sn': '995932809701535353876'
}
'''
完整示例

聲音這個東西格式太多樣化了,若是要想讓百度的SDK識別我們的音頻文件,就要想辦法轉變成百度SDK能夠識別的格式PCM

已知能夠實現自動化轉換格式而且屢試不爽的工具 : FFmpeg

FFmpeg 環境變量配置:

首先你要解壓縮,而後找到bin目錄,

 

個人目錄是 C:\my_AI\ai_voice\ffmpeg-20180619-a990184-win64-shared\bin

 以window10爲例,配置環境變量

嘗試一下是否配置成功

看到這個界面就算配置成功了

ffmpeg 這個工具能夠將wav wma MP3 等音頻文件轉換爲pcm無壓縮音頻文件,測試過程以下:

# 作一個測試,首先要打開windows的錄音機,錄製一段音頻(說普通話)

# 如今假設錄製的音頻文件的名字爲 audio.wav 放置在 c:\myaudio\

# 而後咱們用命令行對這個 audio.wav 進行pcm格式的轉換而後獲得 audio.pcm

# 命令是 :

ffmpeg -y  -i audio.wav  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 audio.pcm

 在錄音文件所在目錄下,執行上述命令,而後打開目錄,就能夠看到pcm文件了

好了,換個環境

 以mac爲例,配置環境變量

自行安裝brew,而後導入ffmpeg

brew install ffmpeg

切換root用戶

su root

成功切換至root用戶後,添加ffmpeg至環境變量

vim /etc/profile

# 進入profile文件,將ffmpeg絕對路徑添加至export中,以下:
export "PATH=/usr/local/mysql/bin:/anaconda3/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/tools/unrar:/usr/local/Cellar/ffmpeg/4.0.2/bin/ffmpeg"

最後重啓服務便可

source /etc/profile

接下來步驟同windows同樣,找到目標文件,執行事先制定好的pcm文件命令便可獲得咱們須要的pcm文件

那麼, pcm文件已經獲得了,進入正題

百度語音識別SDK的應用:

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的話,就參照一下錯誤碼錶

到此百度AI語音部分的調用就結束了。

補充:mac環境中,自動執行mp3文件,要改用指令:os.system("open xueshuohua.mp3")

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/08/27 15:31
# @Author  : MJay_Lee
# @File    : ai_xueshuohua.py
# @Contact : limengjiejj@hotmail.com


import os
from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '11721488'
API_KEY = 'RSs9MrcwhhdndG6vLHN9Q9dC'
SECRET_KEY = 'RpQwPMiPUYXYNOFb0bmFIHORNj4t6Nb0'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 自動化交互將本身說的音頻內容轉換爲pcm文件
file_name = "audio"
cmd_str = f"ffmpeg -y  -i {file_name}.m4a  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {file_name}.pcm"
os.system(cmd_str)


# 讀取文件
def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()


# 識別本地文件
res = client.asr(get_file_content('audio.pcm'), 'pcm', 16000, {
    'dev_pid': 1536,
})

# 提取本身說的內容
text = res['result'][0]


# 合成ai的音頻文件對象
speech = client.synthesis(text,'zh',1,{
    'spd': 4,
    'vol': 8,
    'pit': 8,
    'per': 4
})

# 建立ai的音頻文件
with open("xueshuohua.mp3","wb") as f:
    f.write(speech)


os.system("xueshuohua.mp3")
簡易版識別+合成語音

3、 Pyaudio實現錄音 自動化交互問答

Python 很強大其緣由就是由於它龐大的三方庫 , 資源是很是的豐富 , 固然也不會缺乏關於音頻的庫

關於音頻, PyAudio 這個庫, 能夠實現開啓麥克風錄音, 能夠播放音頻文件等等,此刻咱們不去了解其餘的功能,只瞭解一下它如何實現錄音的

首先

pip install pyaudio

1.Pyaudio實現麥克風錄音

(補充flask理論先)

相關文章
相關標籤/搜索