中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
老張讓我用TensorFlow識(shí)別語音命令:前進(jìn)、停止、左轉(zhuǎn)、右轉(zhuǎn)

一、老張的需求

我有朋友叫老張,他是做傳統(tǒng)單片機(jī)的。他經(jīng)常搞一些簡(jiǎn)單的硬件發(fā)明,比如他家窗簾的打開和關(guān)閉,就是他親自設(shè)計(jì)的電路板控制的。他布線很亂,從電視柜的插座直接扯電線到陽臺(tái)的窗戶,電線就像蜘蛛網(wǎng)一樣縱橫交錯(cuò)。

老張的媳婦是個(gè)強(qiáng)迫癥、完美主義者,沒法忍受亂扯的電線。但是,她又害怕影響自己的丈夫成為大發(fā)明家。于是,她就順著電線綁上綠蘿,這樣就把電線隱藏起來了,絲毫不影響房間的美觀。

上周,老張邀請(qǐng)我去他家里,參觀這個(gè)電動(dòng)窗簾。老張很激動(dòng),趕緊拿來凳子,站在凳子上,用拖把桿去戳一個(gè)紅色的按鈕。他激動(dòng)地差點(diǎn)滑下來。我問他,你為什么要把開關(guān)放那么偏僻。老張說,是為了避免3歲的兒子頻繁地按開關(guān)。老張站在凳子上,像跳天鵝湖一樣,墊著腳尖努力去戳按鈕,給我演示窗簾的開和關(guān)。

我趕緊夸他的窗簾非常棒。我不知道,就這種情況,如果他摔下來,從法律上講我有沒有連帶責(zé)任。

我連忙轉(zhuǎn)移注意力:哎,你家的綠蘿長(zhǎng)得挺好。我不自覺地摸了一下葉子,感覺手指頭麻了一下。我去!老張你家綠蘿帶刺!

老張說,不是帶刺,可能是帶電。

我并沒有太驚奇,因?yàn)槲艺J(rèn)識(shí)老張10多年了。我們先是高中3年同學(xué),后來4年大學(xué)同學(xué),后來又2年同事。在老張這里,什么奇怪的事情都可能發(fā)生。我還記得,高中時(shí),他晚上抱著半個(gè)西瓜插著勺子,去廁所蹲坑,上下同步進(jìn)行。他絲毫沒有尷尬的意思,并稱之為豁達(dá)。

我回憶起往事,痛苦不堪。今天被綠蘿電了,也會(huì)成為往事。我起身準(zhǔn)備要走。老張說,我搞了好多年嵌入式板子,你知道為什么一直沒有起色?

我說,什么?你對(duì)電路板還能起色?!

老張說,不。我意思是說,我搞嵌入式工作這么多年,一直是平平無奇。主要原因,我感覺就是沒有結(jié)合高新技術(shù),比如人工智能。而你,現(xiàn)在就在搞人工智能。

我說,我能讓你起色嗎?

老張說,是的。我研究的巡邏小車,都是靠無線電控制的,我一按,就發(fā)送個(gè)電波。你幫我搞一個(gè)語音控制的。我一喊:跑哇!它就往前走。我一喊:站??!它就停止。我一喊:往左,往右!它就轉(zhuǎn)彎。

我說,這個(gè)不難。但是,這有用嗎?

老張說,是的,這很起色。據(jù)我所知,我們車間里,還沒有人能想出來我這個(gè)想法。而我,馬上就能做出來了。

我說,可以。你這個(gè)不復(fù)雜。但是,我也有個(gè)要求。那就是,我把你這個(gè)事情,寫到博客里,也讓網(wǎng)友了解一下,可以嗎?

老張說:沒問題!

二、我的研究

人工智能有三大常用領(lǐng)域,視覺、文字和語音。前兩者,我寫過很多。這次,開始對(duì)語音領(lǐng)域下手。

以下代碼,環(huán)境要求 TensorFlow 2.6(2021年10之后版) + python 3.9。

2.1 語音的解析

我們所看到的,聽到的,都是數(shù)據(jù)。體現(xiàn)到計(jì)算機(jī),就是數(shù)字。

比如,我們看到下面這張像素圖,是4*4的像素點(diǎn)。圖上有兩個(gè)紫色的點(diǎn)。你看上去,是這樣。

其實(shí),如果是黑白單通道,數(shù)據(jù)是這樣:

[[255, 255, 255, 255],
[255, 131, 255, 255],
[255, 131, 255, 255],
[255, 255, 255, 255]]

如果是多通道,也就是彩色的,數(shù)據(jù)是下面這樣:

[[[255, 255,255],[255, 255, 255],[255, 255, 255],[255, 255, 255]],
[[255, 255, 255],[198, 102, 145],[255, 255, 255],[255, 255, 255]],
[[255, 255, 255],[198, 102, 145],[255, 255, 255],[255, 255, 255]],
[[255, 255, 255],[255, 255, 255],[255, 255, 255],[255, 255, 255]]]

我們看到,空白都是255。只是那2個(gè)紫色的格子有變化。彩色值是[198, 102, 145],單色值是131??梢哉f,一切皆數(shù)據(jù)。

語音是被我們耳朵聽到的。但是,實(shí)際上,它也是數(shù)據(jù)。

你要不信,我們來解析一個(gè)音頻文件。

 tensorflow  tf
audio_binary  tf.io.read_file()
audio, rate  tf.audio.decode_wav(contentsaudio_binary)

使用tf.audio.decode_wav可以讀取和解碼音頻文件,返回音頻文件的數(shù)據(jù)audio和采樣率rate。

其中,解析的數(shù)據(jù)audio打印如下:

<tf.Tensor: shape=(11146, 1), dtype=float32, numpy=
array([[-0.00238037],
[-0.0038147 ],
[-0.00335693],
...,
[-0.00875854],
[-0.00198364],
[-0.00613403]], dtype=float32)>

上面的數(shù)據(jù),形式是[[x]]。這表示,這段音頻是單聲道(類比黑白照片)。x是聲道里面某一時(shí)刻具體的數(shù)值。其實(shí)它是一個(gè)波形,我們可以把它畫出來。

 matplotlib.pyplot  plt
plt.plot(audio)
plt.show()

這個(gè)波的大小,就是推動(dòng)你耳朵鼓膜的力度。

上面的圖是11146個(gè)采樣點(diǎn)的形狀。下面,我們打印10個(gè)點(diǎn)的形狀。這10個(gè)點(diǎn)就好比是推了你耳朵10下。

 matplotlib.pyplot  plt
plt.plot(audio[:])
plt.show()

至此,我們可以看出,音頻實(shí)際上就是幾組帶有序列的數(shù)字。

要識(shí)別音頻,就得首先分析音頻數(shù)據(jù)的特征。

2.2 音頻的頻譜

每個(gè)個(gè)體都有自己的組成成分,他們是獨(dú)一無二的。就像你一樣。

但是,多個(gè)個(gè)體之間,也有相似之處。就像我們都是程序員。于是,我們可以用一種叫“譜”的東西來描述一個(gè)事物。比如,辣子雞的菜譜。正是菜譜描述了放多少辣椒,用哪個(gè)部位的雞肉,切成什么形狀。這才讓我們看到成品時(shí),大喊一聲:辣子雞,而非糖醋魚。

聲音也有“譜”,一般用頻譜描述。

聲音是振動(dòng)發(fā)生的,這個(gè)振動(dòng)的頻率是有譜的。

把一段聲音分析出來包含哪些固定頻率,就像是把一道菜分析出來由辣椒、雞肉、豆瓣醬組成。再通過分析食材,最終我們判斷出來是什么菜品。

聲音也是一樣,一段聲波可以分析出來它的頻率組成。如果想要詳細(xì)了解“頻譜”的知識(shí),我有一篇萬字長(zhǎng)文詳解了《傅里葉變換》??赐晷枰雮€(gè)小時(shí)。

我上面說的,谷歌公司早就知道了。因此,他們?cè)?code style="color: rgb(0, 0, 0);font-family: Menlo, Monaco, Consolas, "Courier New", monospace;background-color: rgb(240, 240, 240);border-radius: 3px;padding-top: 0.2em;padding-bottom: 0.2em;font-size: 0.85em !important;">TensorFlow框架中,早就內(nèi)置了獲取音頻頻譜的函數(shù)。它采用的是短時(shí)傅里葉變換stft。

waveform  tf.squeeze(audio, axis)
spectrogram  tf.signal.stft(waveform, frame_length, frame_step)

我們上面通過tf.audio.decode_wav解析了音頻文件,它返回的數(shù)據(jù)格式是[[-0.00238037][-0.0038147 ]]這種形式。

你可能好奇,它為什么不是[-0.00238037, -0.0038147 ]這種形式,非要外面再套一層。回憶一下,我們的紫色像素的例子,一個(gè)像素點(diǎn)表示為[[198, 102, 145]],這表示RGB三個(gè)色值通道描述一個(gè)彩色像素。其實(shí),這里也一樣,是兼容了多聲道的情況。

但是,我們只要一個(gè)通道就好。所以需要通過tf.squeeze(audio, axis=-1)對(duì)數(shù)據(jù)進(jìn)行降一個(gè)維度,把[[-0.00238037][-0.0038147 ]]變?yōu)?code style="color: rgb(0, 0, 0);font-family: Menlo, Monaco, Consolas, "Courier New", monospace;background-color: rgb(240, 240, 240);border-radius: 3px;padding-top: 0.2em;padding-bottom: 0.2em;font-size: 0.85em !important;">[-0.00238037, -0.0038147 ]。這,才是一個(gè)純粹的波形。嗯,這樣才能交給傅里葉先生進(jìn)行分析。

tf.signal.stft里面的參數(shù),是指取小樣的規(guī)則。就是從總波形里面,每隔多久取多少小樣本進(jìn)行分析。分析之后,我們也是可以像繪制波形一樣,把分析的頻譜結(jié)果繪制出來的。

看不懂上面的圖沒有關(guān)系,這很正常,非常正常,極其正常。因?yàn)?,我即便用了一萬多字,50多張圖,專門做了詳細(xì)的解釋。但是依然,有20%左右的讀者還是不明白。

不過,此時(shí),你需要明白,一段聲音的特性是可以通過科學(xué)的方法抽取出來的。這,就夠了。

把特性抽取出來之后,我們就交給人工智能框架去訓(xùn)練了。

2.3 音頻數(shù)據(jù)的預(yù)處理

上面,我們已經(jīng)成功地獲取到一段音頻的重要靈魂:頻譜。

下面,就該交給神經(jīng)網(wǎng)絡(luò)模型去訓(xùn)練了。

在正式交給模型之前,其實(shí)還有一些預(yù)處理工作要做。比如,給它切一切毛邊,疊一疊,整理成同一個(gè)形狀。

正如計(jì)算機(jī)只能識(shí)別0和1,很多框架也是只能接收固定的結(jié)構(gòu)化數(shù)據(jù)。

舉個(gè)簡(jiǎn)單的例子,你在訓(xùn)練古詩(shī)的時(shí)候,有五言的和七言的。比如:“床前明月光”和“一頓不吃餓得慌”兩句。那么,最終都需要處理成一樣的長(zhǎng)短。要么前面加0,要么后邊加0,要么把長(zhǎng)的裁短。總之,必須一樣長(zhǎng)度才行。

床前明月光〇〇
一頓不吃餓得慌
蜀道難〇〇〇〇

那么,我們的音頻數(shù)據(jù)如何處理呢?我們的音波數(shù)據(jù)經(jīng)過短時(shí)傅里葉變換之后,格式是這樣的:

<tf.Tensor: shape=(86, 129, 1), dtype=float32, numpy=
array([[[4.62073803e-01],
...,
[2.92062759e-05]],

[[3.96062881e-01],
[2.01166332e-01],
[2.09505502e-02],
...,
[1.43915415e-04]]], dtype=float32)>

這是因?yàn)槲覀?1146長(zhǎng)度的音頻,經(jīng)過tf.signal.stftframe_step=128分割之后,可以分成86份。所以我們看到shape=(86, 129, 1)。那么,如果音頻的長(zhǎng)度變化,那么這個(gè)結(jié)構(gòu)也會(huì)變。這樣不好。

因此,我們首先要把音頻的長(zhǎng)度規(guī)范一下。因?yàn)椴蓸勇适?code style="color: rgb(0, 0, 0);font-family: Menlo, Monaco, Consolas, "Courier New", monospace;background-color: rgb(240, 240, 240);border-radius: 3px;padding-top: 0.2em;padding-bottom: 0.2em;font-size: 0.85em !important;">16000,也就是1秒鐘記錄16000次音頻數(shù)據(jù)。那么,我們不妨就拿1秒音頻,也就是16000個(gè)長(zhǎng)度,為一個(gè)標(biāo)準(zhǔn)單位。過長(zhǎng)的,我們就裁剪掉后面的。過短的,我們就在后面補(bǔ)上0。

我說的這一系列操作,反映到代碼上,就是下面這樣:

waveform  tf.squeeze(audio, axis)
input_len  
waveform  waveform[:input_len]
zero_padding  tf.zeros([]  tf.shape(waveform),dtypetf.float32)
waveform  tf.cast(waveform, dtypetf.float32)
equal_length  tf.concat([waveform, zero_padding], )
spectrogram  tf.signal.stft(equal_length, frame_length, frame_step)
spectrogram  tf.(spectrogram)
spectrogram  spectrogram[..., tf.newaxis]

這時(shí)候,再來看看我們的頻譜數(shù)據(jù)結(jié)構(gòu):

<tf.Tensor: shape=(124, 129, 1), dtype=float32, numpy=
array([[[4.62073803e-01],
...,
[2.92062759e-05]],
...
[0.00000000e+00],
...,
[0.00000000e+00]]], dtype=float32)>

現(xiàn)在,不管你輸入任何長(zhǎng)短的音頻,最終它的頻譜都是shape=(124, 129, 1)。從圖上我們也可以看出,不足的就算后面補(bǔ)0,也得湊成個(gè)16000長(zhǎng)度。

下面,真的要開始構(gòu)建神經(jīng)網(wǎng)絡(luò)了。

2.4 構(gòu)建模型和訓(xùn)練

依照老張的要求……我現(xiàn)在不想提他,因?yàn)槲业氖种副痪G蘿電的還有點(diǎn)發(fā)麻。

依照要求……他要四種命令,分別是:前進(jìn)、停止、左轉(zhuǎn)、右轉(zhuǎn)。那么,我就搞了四種音頻,分別放在對(duì)應(yīng)的文件夾下面。

從文件夾讀取數(shù)據(jù)、輸入輸出結(jié)對(duì)、按照比例分出數(shù)據(jù)集和驗(yàn)證集,以及把datasets劃分為batch……這些操作,在TensorFlow中已經(jīng)很成熟了。而且,隨著版本的更新,越來越成熟。體現(xiàn)在代碼上,就是字?jǐn)?shù)越來越少。此處我就不說了,我會(huì)把完整代碼上傳到github,供諸君參考。

下面,我重點(diǎn)說一下,本例子中,實(shí)現(xiàn)語音分類,它的神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),以及模型訓(xùn)練的配置。

 tensorflow  tf
 tensorflow.keras  layers
 tensorflow.keras  models

model  models.Sequential([
       layers.Input(shape (, , )),
       layers.Resizing(, ),
       layers.Normalization(),
       layers.Conv2D(, , activation),
       layers.Conv2D(, , activation),
       layers.MaxPooling2D(),
       layers.Dropout(),
       layers.Flatten(),
       layers.Dense(, activation),
       layers.Dropout(),
       layers.Dense(),
])
model.(
       optimizertf.keras.optimizers.Adam(),
       losstf.keras.losses.SparseCategoricalCrossentropy(from_logits),
       metrics[]
)

其實(shí),我感覺人工智能應(yīng)用層面的開發(fā),預(yù)處理和后處理比較難。中間的模型基本上都是有固定招式的。

第1層layers.Input(shape= (124, 129, 1))叫輸入層,是訓(xùn)練樣本的數(shù)據(jù)結(jié)構(gòu)。就是我們上一節(jié)湊成16000之后,求頻譜得出的(124, 129)這個(gè)結(jié)構(gòu)。

最后一層layers.Dense(4),是輸出層。我們搞了“走”,“?!?,“左”,“右”4個(gè)文件夾分類,最終結(jié)果是4類,所以是4。

頭尾基本固定后,這個(gè)序列Sequential就意味著:吃音頻文件,然后排出它是4個(gè)分類中的哪一種。

那么中間我們就可以自己操作了。Normalization是歸一化。Conv2D是做卷積。MaxPooling2D是做池化。Dropout(0.25)是隨機(jī)砍掉一定比例(此處是25%)的神經(jīng)網(wǎng)絡(luò),以保證其健壯性。快結(jié)束時(shí),通過Flatten()將多維數(shù)據(jù)拉平為一維數(shù)據(jù)。后面給個(gè)激活函數(shù),收縮神經(jīng)元個(gè)數(shù),準(zhǔn)備降落。最后,對(duì)接到Dense(4)。

這就實(shí)現(xiàn)了,將前面16000個(gè)音頻采樣點(diǎn),經(jīng)過一系列轉(zhuǎn)化后,最終輸出為某個(gè)分類。

最后,進(jìn)行訓(xùn)練和保存模型。

model  create_model()
cp_callback  tf.keras.callbacks.ModelCheckpoint(filepath,
       save_weights_only,
       save_best_only)
history  model.fit(
       train_ds,
       validation_dataval_ds,
       epochs,
       callbacks[cp_callback]
)

filepath='model/model.ckpt'表示訓(xùn)練完成后,存儲(chǔ)的路徑。save_weights_only=True只存儲(chǔ)權(quán)重?cái)?shù)據(jù)。save_best_only=True意思是只存儲(chǔ)最好的訓(xùn)練的結(jié)果。調(diào)用訓(xùn)練很簡(jiǎn)單,調(diào)用model.fit,傳入訓(xùn)練集、驗(yàn)證集、訓(xùn)練輪數(shù)、以及訓(xùn)練回調(diào)就可以啦。

2.5 加載模型并預(yù)測(cè)

上一節(jié)中,我們指定了模型的保存路徑,調(diào)用model.fit后會(huì)將結(jié)果保存在對(duì)應(yīng)的路徑下。這就是我們最終要的產(chǎn)物:

我們可以加載這些文件,這樣就讓我們的程序具備了多年功力??梢詫?duì)外來音頻文件做預(yù)測(cè)。

model  create_model()
 os.path.exists():
       model.load_weights()  
labels  [, , , ]

audio  get_audio_data()
audios  np.array([audio])
predictions  model(audios)
index  np.argmax(predictions[])
(labels[index])

上面代碼中,先加載了歷史模型。然后,將我錄制的一個(gè)mysound.wav文件進(jìn)行預(yù)處理,方式就是前面說的湊成16000,然后通過短時(shí)傅里葉解析成(124, 129)結(jié)構(gòu)的頻譜數(shù)據(jù)。這也是我們訓(xùn)練時(shí)的模樣。

最后,把它輸入到模型。出于慣性,它會(huì)順勢(shì)輸出這是'go'分類的語音指令。盡管這個(gè)模型,從來沒有見過我這段動(dòng)聽的嗓音。但是它也能識(shí)別出來,我發(fā)出了一個(gè)包含'go'聲音特性的聲音。

以上,就是利用TensorFlow框架,實(shí)現(xiàn)聲音分類的全過程。

再次提醒大家:要求TensorFlow 2.6(2021年10之后版) + python 3.9。因?yàn)?,里面用了很多新特性。舊版本是跑不通的,具體體現(xiàn)在TensorFlow各種找不到層。

音頻分類項(xiàng)目開源地址:https://github.com/hlwgy/sound

三、我們的合作

我?guī)е晒フ依蠌?。老張沉默了一?huì)兒,不說話。

我說,老張啊,你就說吧。你不說話,我心里沒底,不知道會(huì)發(fā)生啥。

老張說,兄弟啊,其實(shí)語音小車這個(gè)項(xiàng)目,沒啥創(chuàng)意。我昨天才知道,我們車間老王,三年前,自己一個(gè)人,就做出來過了。說完,老張又沉默了。

我安慰他說,沒關(guān)系的。這個(gè)不行,你就再換一個(gè)唄。

老張猛然抬起頭,眼睛中閃著光,他說:兄弟,宇宙飛船相關(guān)的軟件,你搞得定嗎?!火星車也行。

我不緊不忙地關(guān)閉服務(wù),并把電腦收進(jìn)包里。

我穿上鞋,然后拿上包。打開門,回頭跟老張說了一句:兄弟,三個(gè)月內(nèi),我們先不聯(lián)系了吧。

我是IT男,帶你從IT角度看世界。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【完結(jié)】TensorFlow2.0 快速上手手冊(cè)
編織人工智能:機(jī)器學(xué)習(xí)發(fā)展總覽與關(guān)鍵技術(shù)全解析
聊聊圖像識(shí)別的小原理,動(dòng)手實(shí)現(xiàn)自己的圖像分類
車輛車型識(shí)別系統(tǒng)python TensorFlow Django網(wǎng)頁界面 算法模型
使用TensorFlow和OpenCV實(shí)現(xiàn)口罩檢測(cè)
TensorFlow 1.9 正式推出!
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服