教程| 如何使用TensorFlow構建、訓練和改進循環神經網絡

2021-01-11 機器之心Pro

選自SVDS作者:Matthew Rubashkin、Matt Mollison機器之心編譯參與:李澤南、吳攀

來自 Silicon Valley Data Science 公司的研究人員為我們展示了循環神經網絡(RNN)探索時間序列和開發語音識別模型的能力。目前有很多人工智慧應用都依賴於循環深度神經網絡,在谷歌(語音搜索)、百度(DeepSpeech)和亞馬遜的產品中都能看到RNN的身影。

然而,當我們開始著手構建自己的 RNN 模型時,我們發現在使用神經網絡處理語音識別這樣的任務上,幾乎沒有簡單直接的先例可以遵循。一些可以找到的例子功能非常強大,但非常複雜,如 Mozilla 的 DeepSpeech(基於百度的研究,使用 TensorFlow);抑或極其簡單抽象,無法應用於實際數據。

本文將提供一個有關如何使用 RNN 訓練語音識別系統的簡短教程,其中包括代碼片段。本教程的靈感來自於各類開源項目。

本項目 GitHub 地址:https://github.com/silicon-valley-data-science/RNN-Tutorial

首先,開始閱讀本文以前,如果你對 RNN 還不了解,可以閱讀 Christopher Olah 的 RNN 長短期記憶網絡綜述:

http://colah.github.io/posts/2015-08-Understanding-LSTMs/

語音識別:聲音和轉錄

直到 2010 年時,最優秀的語音識別模型仍是基於語音學(Phonetics)的方法,它們通常包含拼寫、聲學和語言模型等單獨組件。不論是過去還是現在,語音識別技術都依賴於使用傅立葉變換將聲波分解為頻率和幅度,產生如下所示的頻譜圖:

訓練語音模型時,使用隱馬爾科夫模型(Hidden Markov Models,HMM)需要語音+文本數據,同時還需要單詞與音素的詞典。HMM 用於順序數據的生成概率模型,通常使用萊文斯坦距離來評估(Levenshtein 距離,是編輯距離的一種。指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。可以進行的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符)。

這些模型可以被簡化或通過音素關聯數據的訓練變得更準確,但那是一些乏味的手工任務。因為這個原因,音素級別的語音轉錄在大數據集的條件下相比單詞級別的轉錄更難以實現。有關語音識別工具和模型的更多內容可以參考這篇博客:

https://svds.com/open-source-toolkits-speech-recognition/

連接時間分類(CTC)損失函數

幸運的是,當使用神經網絡進行語音識別時,通過能進行字級轉錄的連接時間分類(Connectionist Temporal Classification,CTC)目標函數,我們可以丟棄音素的概念。簡單地說,CTC 能夠計算多個序列的概率,而序列是語音樣本中所有可能的字符級轉錄的集合。神經網絡使用目標函數來最大化字符序列的概率(即選擇最可能的轉錄),隨後把預測結果與實際進行比較,計算預測結果的誤差,以在訓練中不斷更新網絡權重。

值得注意的是,CTC 損失函數中的字符級錯誤與通常被用於常規語音識別模型的萊文斯坦錯詞距離。對於字符生成 RNN 來說,字符和單詞錯誤距離在表音文字(phonetic language)中是相同的(如世界語、克羅埃西亞語),這些語言的不同發音對應不同字符。與之相反的是,字符與單詞錯誤距離在其他拼音文字中(如英語)有著顯著不同。

如果你希望了解 CTC 的更多內容和百度對它最新的研究,以下是一些連結:

http://suo.im/tkh2ehttp://suo.im/3WuVwVhttps://arxiv.org/abs/1703.00096

為了優化算法,構建傳統/深度語音識別模型,SVDS 的團隊開發了語音識別平臺:

數據的重要性

毫無疑問,訓練一個將語音轉錄為文字的系統需要數字語音文件和這些錄音的轉錄文本。因為模型終將被用於解釋新的語音,所以越多的訓練意味著越好的表現。SVDS 的研究人員使用了大量帶有轉錄的英文語音對模型進行訓練;其中的一些數據包含 LibriSpeech(1000 小時)、TED-LIUM(118 小時)和 VoxForge(130 小時)。下圖展示了這些數據集的信息,包括時長,採樣率和注釋。

LibriSpeech:http://www.openslr.org/12/TED-LIUM:http://www.openslr.org/7/VoxForge:http://www.voxforge.org/

為了讓模型更易獲取數據,我們將所有數據存儲為同一格式。每條數據由一個.wav 文件和一個.txt 文件組成。例如:Librispeech 的『211-122425-0059』 在 Github 中對應著 211-122425-0059.wav 與 211-122425-0059.txt。這些數據的文件使用數據集對象類被加載到 TensorFlow 圖中,這樣可以讓 TensorFlow 在加載、預處理和載入單批數據時效率更高,節省 CPU 和 GPU 內存負載。數據集對象中數據欄位的示例如下所示:

classDataSet:

def__init__(self, txt_files, thread_count, batch_size, numcep, numcontext):

# ...

deffrom_directory(self, dirpath, start_idx=0, limit=0, sort=None):

returntxt_filenames(dirpath, start_idx=start_idx, limit=limit, sort=sort)

defnext_batch(self, batch_size=None):

idx_list=range(_start_idx, end_idx)

txt_files=[_txt_files[i]foriinidx_list]

wav_files=[x.replace('.txt','.wav')forxintxt_files]

# Load audio and text into memory

(audio, text)=get_audio_and_transcript(

txt_files,

wav_files,

_numcep,

_numcontext)

特徵表示

為了讓機器識別音頻數據,數據必須先從時域轉換為頻域。有幾種用於創建音頻數據機器學習特徵的方法,包括任意頻率的 binning(如 100Hz),或人耳能夠感知的頻率的 binning。這種典型的語音數據轉換需要計算 13 位或 26 位不同倒譜特徵的梅爾倒頻譜係數(MFCC)。在轉換之後,數據被存儲為時間(列)和頻率係數(行)的矩陣。

因為自然語言的語音不是獨立的,它們與字母也不是一一對應的關係,我們可以通過訓練神經網絡在聲音數據上的重疊窗口(前後 10 毫秒)來捕捉協同發音的效果(一個音節的發音影響了另一個)。以下代碼展示了如何獲取 MFCC 特徵,以及如何創建一個音頻數據的窗口。

# Load wav files

fs, audio=wav.read(audio_filename)

# Get mfcc coefficients

orig_inputs=mfcc(audio, samplerate=fs, numcep=numcep)

# For each time slice of the training set, we need to copy the context this makes

train_inputs=np.array([], np.float32)

train_inputs.resize((orig_inputs.shape[0], numcep+2*numcep*numcontext))

fortime_sliceinrange(train_inputs.shape[0]):

# Pick up to numcontext time slices in the past,

# And complete with empty mfcc features

need_empty_past=max(0, ((time_slices[0]+numcontext)-time_slice))

empty_source_past=list(empty_mfccforempty_slotsinrange(need_empty_past))

data_source_past=orig_inputs[max(0, time_slice-numcontext):time_slice]

assert(len(empty_source_past)+len(data_source_past)==numcontext)

...

對於這個 RNN 例子來說,我們在每個窗口使用前後各 9 個時間點——共 19 個時間點。有 26 個倒譜係數,在 25 毫秒的時間裡共 494 個數據點。根據數據採樣率,我們建議在 16,000 Hz 上有 26 個倒譜特徵,在 8,000 Hz 上有 13 個倒譜特徵。以下是一個 8,000 Hz 數據的加載窗口:

如果你希望了解更多有關轉換數字音頻用於 RNN 語音識別的方法,可以看看 Adam Geitgey 的介紹:http://suo.im/Wkp8B

對語音的序列本質建模

長短期記憶(LSTM)是循環神經網絡(RNN)的一種,它適用於對依賴長期順序的數據進行建模。它對於時間序列數據的建模非常重要,因為這種方法可以在當前時間點保持過去信息的記憶,從而改善輸出結果,所以,這種特性對於語音識別非常有用。如果你想了解在 TensorFlow 中如何實例化 LSTM 單元,以下是受 DeepSpeech 啟發的雙向循環神經網絡(BiRNN)的 LSTM 層示例代碼:

with tf.name_scope('lstm'):

# Forward direction cell:

lstm_fw_cell=tf.contrib.rnn.BasicLSTMCell(n_cell_dim, forget_bias=1.0, state_is_tuple=True)

# Backward direction cell:

lstm_bw_cell=tf.contrib.rnn.BasicLSTMCell(n_cell_dim, forget_bias=1.0, state_is_tuple=True)

# Now we feed `layer_3` into the LSTM BRNN cell and obtain the LSTM BRNN output.

outputs, output_states=tf.nn.bidirectional_dynamic_rnn(

cell_fw=lstm_fw_cell,

cell_bw=lstm_bw_cell,

# Input is the previous Fully Connected Layer before the LSTM

inputs=layer_3,

dtype=tf.float32,

time_major=True,

sequence_length=seq_length)

tf.summary.histogram("activations", outputs)

關於 LSTM 網絡的更多細節,可以參閱 RNN 與 LSTM 單元運行細節的概述:

http://karpathy.github.io/2015/05/21/rnn-effectiveness/http://colah.github.io/posts/2015-08-Understanding-LSTMs/

此外,還有一些工作探究了 RNN 以外的其他語音識別方式,如比 RNN 計算效率更高的卷積層:https://arxiv.org/abs/1701.02720

訓練和監測網絡

因為示例中的網絡是使用 TensorFlow 訓練的,我們可以使用 TensorBoard 的可視化計算圖監視訓練、驗證和進行性能測試。在 2017 TensorFlow Dev Summit 上 Dandelion Mane 給出了一些有用的幫助:https://www.youtube.com/watch?v=eBbEDRsCmv4

我們利用 tf.name_scope 添加節點和層名稱,並將摘要寫入文件,其結果是自動生成的、可理解的計算圖,正如下面的雙向神經網絡(BiRNN)所示。數據從左下角到右上角在不同的操作之間傳遞。為了清楚起見,不同的節點可以用命名空間進行標記和著色。在這個例子中,藍綠色 fc 框對應於完全連接的層,綠色 b 和 h 框分別對應於偏差和權重。

我們利用 TensorFlow 提供的 tf.train.AdamOptimizer 來控制學習速度。AdamOptimizer 通過使用動量(參數的移動平均數)來改善傳統梯度下降,促進超參數動態調整。我們可以通過創建標籤錯誤率的摘要標量來跟蹤丟失和錯誤率:

# Create a placeholder for the summary statistics

with tf.name_scope("accuracy"):

# Compute the edit (Levenshtein) distance of the top path

distance=tf.edit_distance(tf.cast(self.decoded[0], tf.int32),self.targets)

# Compute the label error rate (accuracy)

self.ler=tf.reduce_mean(distance, name='label_error_rate')

self.ler_placeholder=tf.placeholder(dtype=tf.float32, shape=[])

self.train_ler_op=tf.summary.scalar("train_label_error_rate",self.ler_placeholder)

self.dev_ler_op=tf.summary.scalar("validation_label_error_rate",self.ler_placeholder)

self.test_ler_op=tf.summary.scalar("test_label_error_rate",self.ler_placeholder)

如何改進 RNN

現在我們構建了一個簡單的 LSTM RNN 網絡,下一個問題是:如何繼續改進它?幸運的是,在開源社區裡,很多大公司都開源了自己的最新語音識別模型。在 2016 年 9 月,微軟的論文《The Microsoft 2016 Conversational Speech Recognition System》展示了在 NIST 200 Switchboard 數據中單系統殘差網絡錯誤率 6.9% 的新方式。他們在卷積+循環神經網絡上使用了幾種不同的聲學和語言模型。微軟的團隊和其他研究人員在過去 4 年中做出的主要改進包括:

在基於字符的 RNN 上使用語言模型使用卷積神經網絡(CNN)從音頻中獲取特徵使用多個 RNN 模型組合

值得注意的是,在過去幾十年裡傳統語音識別模型獲得的研究成果,在目前的深度學習語音識別模型中仍然扮演著自己的角色。

修改自: A Historical Perspective of Speech Recognition, Xuedong Huang, James Baker, Raj Reddy Communications of the ACM, Vol. 57 No. 1, Pages 94-103, 2014

訓練你的第一個 RNN 模型

在本教程的 Github 裡,作者提供了一些介紹以幫助讀者在 TensorFlow 中使用 RNN 和 CTC 損失函數訓練端到端語音識別系統。大部分事例數據來自 LibriVox。數據被分別存放於以下文件夾中:

Train: train-clean-100-wav (5 examples)Test: test-clean-wav (2 examples)Dev: dev-clean-wav (2 examples)

當訓練這些示例數據時,你會很快注意到訓練數據的詞錯率(WER)會產生過擬合,而在測試和開發集中詞錯率則有 85% 左右。詞錯率不是 100% 的原因在於每個字母有 29 種可能性(a-z、逗號、空格和空白),神經網絡很快就能學會:

某些字符(e,a,空格,r,s,t)比其他的更常見輔音-元音-輔音是英文的構詞特徵MFCC 輸入聲音信號振幅特徵的增加只與字母 a-z 有關

使用 Github 中默認設置的訓練結果如下:

如果你想訓練一個更強大的模型,你可以添加額外的.wav 和.txt 文件到這些文件夾裡,或創建一個新的文件夾,並更新 configs / neural_network.ini 的文件夾位置。注意:幾百小時的音頻也需要大量時間來進行訓練,即使你有一塊強大的 GPU。

原文連結:https://svds.com/tensorflow-rnn-tutorial/

相關焦點

  • TensorFlow2.0-Keras入門
    最近在知乎上寫一些學習tensorflow2.0的筆記心得,整理成中文教程,希望幫助想學習tensorflow2的朋友更好的了解tensorflow2的同時,也是倒逼自己更好的學習。我始終相信:最好的學習是輸出知識,最好的成長是共同成長。希望可以通過這個公眾號和廣大的深度學習愛好者,一起學習成長。
  • 如何在PyTorch和TensorFlow中訓練圖像分類模型
    在本文中,我們將了解如何在PyTorch和TensorFlow中建立基本的圖像分類模型。我們將從PyTorch和TensorFlow的簡要概述開始。然後,我們將使用MNIST手寫數字分類數據集,並在PyTorch和TensorFlow中使用CNN(卷積神經網絡)建立圖像分類模型。這將是你的起點,然後你可以選擇自己喜歡的任何框架,也可以開始構建其他計算機視覺模型。
  • 用Tensorflow讓神經網絡自動創造音樂
    前幾天看到一個有意思的分享,大意是講如何用Tensorflow教神經網絡自動創造音樂。下面來說一下是怎麼做的:    1.首先下載Project Magenta   1 git clone https://github.com/tensorflow/magenta.git    2.安裝需要的工具:  在這裡(https://www.tensorflow.org/versions/r0.9/get_started
  • 【TF秘籍】令人困惑的 TensorFlow!(II)
    這是因為作用域可以將名稱轉換為 first_scope/coef:0 和 first_scope/second_scope/coef:0,它們是不同的。訓練好的神經網絡包括兩個基本組成部分:已經學習過某些任務優化的網絡權重說明如何利用權重獲得結果的網絡圖Tensorflow 將這兩個組件分開,但很明顯它們需要緊密匹配。
  • 令人困惑的TensorFlow!
    這個神經網絡框架通過構建「計算圖」來運行,對於很多新手來說,在理解其邏輯時會遇到很多困難。本文中,來自谷歌大腦的工程師 Jacob Buckman 將試圖幫你解決初遇 TensorFlow 時你會遇到的麻煩。導論這是什麼?我是誰?我叫 Jacob,是 Google AI Resident 項目的研究學者。
  • TensorFlow 2.X,會是它走下神壇的開始嗎?
    你會驚奇地發現,它們的 TensorFlow 導入都是這種風格:import tensorflow.compat.v1 as tfimport tensorflow.compat.v2 as tf其中,「compat」是 TF2.X 專門為兼容 TF 1.X 配置的模塊。
  • 令人困惑的 TensorFlow!(II)
    保存和加載訓練好的神經網絡包括兩個基本組成部分:已經學習過某些任務優化的網絡權重說明如何利用權重獲得結果的網絡圖Tensorflow 將這兩個組件分開,但很明顯它們需要緊密匹配。這通常會讓 Tensorflow 初學者感覺很挫敗。使用預先訓練好的模型作為神經網絡的一個組成部分不失為加速訓練的好方法,但是也有可能搞砸一切。保存模型當只有單個模型時,Tensorflow 用於保存和加載的內置工具使用很方便:只需創建一個 tf.train.Saver()。
  • TensorFlow 2.4來了:上線對分布式訓練和混合精度的新功能支持
    編輯:小舟、蛋醬今天,谷歌正式發布了 TensorFlow 2.4,帶來了多項新特性和功能改進。ParameterServerStrategy 和自定義訓練循環進行模型異步訓練的試驗性支持。大多數 TensorFlow 模型使用 float32 dtype,但現在有些低精度數據類型佔用的內存更少,比如 float16。混合精度指的是在同一模型中使用 16 位和 32 位浮點數以進行更快的訓練。這一 API 可將模型性能在 GPU 上提高到 3 倍,在 TPU 上提高 60%。要使用混合精度 API,必須使用 Keras 層和優化器,但不一定需要使用其他 Keras 類。
  • 谷歌重磅推出TensorFlow Graphics:為3D圖像任務打造的深度學習利器
    近年來,可插入到神經網絡架構中的一種新型可微圖形層(differentiable graphics layers)開始興起。從空間變換器(spatial transformers)到可微圖形渲染器,這些新型的神經網絡層利用計算機視覺、圖形學研究獲得的知識來構建新的、更高效的網絡架構。
  • 深度 谷歌官方指南:如何通過玩TensorFlow Playground來理解神經網絡
    而眾多神經元組成的深度神經網絡能提取更多特徵,解決更複雜更抽象的問題。(之前相關報導:業界 | 想揭開深度學習隱藏層的神秘面紗?試試Tensor Flow的神經網絡遊樂場)源碼:https://github.com/tensorflow/playground神經網絡和深度學習近來已經變成了網際網路上的熱詞,你可能也想一探究竟。
  • 入門 | 關於TensorFlow,你應該了解的9件事
    #3:逐行構建神經網絡Keras + TensorFlow = 更容易的神經網絡構建!Keras 致力於用戶友好性和簡單的原型設計,這是之前的 TensorFlow 所渴望的。如果你喜歡面向對象的思維,喜歡一次構建一層神經網絡,你會喜歡 tf.keras。在下面幾行代碼中,我們創建了一個序列神經網絡(sequential neural network),其具備標準的附屬組件,如 dropout。
  • TensorFlow Recommenders 現已開源,讓推薦系統更上一層樓!
    import tensorflow as tfimport tensorflow_datasets as tfdsimport tensorflow_recommenders as tfrs# Ratings data.
  • TensorFlow 2.1.0-rc2發布
    pip install tensorflow安裝的TF默認也有gpu支持了(windows、linux),pip install tensorflow-gpu仍舊可以用,如果考慮到包的大小,也可以用只支持CPU的:tensorflow-cpuWindows用戶:為了使用新的/d2ReducedOptimizeHugeFunctions
  • 詳解深度強化學習展現TensorFlow 2.0新特性(代碼)
    深度actor- critical方法雖然很多基礎的RL理論是在表格案例中開發的,但現代RL幾乎完全是用函數逼近器完成的,例如人工神經網絡。 具體來說,如果策略和值函數用深度神經網絡近似,則RL算法被認為是「深度的」。
  • 使用Amazon SageMaker 運行基於 TensorFlow 的中文命名實體識別
    因此客戶迫切想使用業內最先進的算法在行業內數據集上進行訓練,以改進現有NER工具的不足。本文將介紹如何使用Amazon SageMaker運行基於TensorFlow的中文命名實體識別。命名實體識別,是指識別文本中具有特定意義的實體,主要包括人名、地名、機構名、專有名詞等。命名實體識別是信息提取、問答系統、句法分析、機器翻譯、知識圖譜等應用領域的重要基礎工具。
  • 機器如何閱讀圖片?能看破並說破一切的TensorFlow
    本文將展示如何使用TensorFlow API構建目標檢測模型。目標檢測的總體框架構建目標檢測框架的過程一般分為以下三步:1、 首先,使用深度學習模型或算法生成一組遍布整張圖片的邊界框(即目標定位組件)。
  • 社交距離檢測器——Tensorflow檢測模型設計
    在隔離期間,我花時間在github上探索Tensorflow的大量預訓練模型。這樣做時,我偶然發現了一個包含25 個帶有性能和速度指標的預訓練對象檢測模型的存儲庫。擁有一些計算機視覺知識並給出了實際的背景知識,我認為使用其中之一來構建社交隔離應用程式可能會很有趣。
  • 使用Tensorflow實現RNN-LSTM的菜鳥指南
    簡單的多層神經網絡是分類器,當給定某個輸入時,將輸入標記為屬於許多類之一。它們使用現有的反向傳播算法進行訓練。這些網絡在他們所做的事情上表現出色,但他們無法處理按順序排列的輸入。例如,對於神經網絡來識別句子中的名詞,僅將單詞作為輸入是沒有用的。在單詞的上下文中存在許多信息,這些信息只能通過查看給定單詞附近的單詞來確定。要研究整個序列以確定輸出。
  • Tensorflow還是PyTorch?哪一個才更適合編程實現深度神經網絡?
    這兩種框架都提供了編程神經網絡常用的機器學習步驟:導入所需的庫加載並預處理數據定義模型定義優化器和損失函數訓練模型評估模型這些步驟可以在任何一個框架中找到非常類似的實現(即使是像MindSpore這樣的框架)。為此,在本文中,我們將構建一個神經網絡模型,分別在PyTorch API與TensorFlow Keras API下進行手寫數字分類任務的實現。
  • 用RNN和TensorFlow創作自己的《哈利波特》小說
    最近我開始學習神經網絡,著迷於深度學習的強大創造力。靈光乍現,我為什麼不把它們融合在一起呢?因此,我使用TensorFlow執行了一個簡單的文本生成模型來創作我自己的《哈利·波特》短篇小說。本文將介紹了我為實現它而編寫的完整代碼。